วิธีรับชื่อฟังก์ชั่นจากภายในฟังก์ชั่นนั้น?


263

ฉันจะเข้าถึงชื่อฟังก์ชันจากภายในฟังก์ชันนั้นได้อย่างไร

// parasitic inheritance
var ns.parent.child = function() {
  var parent = new ns.parent();
  parent.newFunc = function() {

  }
  return parent;
}

var ns.parent = function() {
  // at this point, i want to know who the child is that called the parent
  // ie
}

var obj = new ns.parent.child();

ดีในผู้ปกครองฉันสามารถเข้าถึงฟังก์ชั่นอื่น ๆ โดยการประชุมเช่น ns [child] [schema] หรือ ns [child] [dbService] หากไม่มีมันฉันจะต้องเขียนโค้ดอ้างอิงเหล่านี้อย่างหนักในทุกชั้นของเด็ก
Scott Klarenbach

ทำไมไม่เพียงแค่ส่งผ่านฟังก์ชันลูกเป็นอาร์กิวเมนต์ไปยังผู้ปกครอง var parent = new ns.parent (this);
เพียร

เพราะมีการค้นหาหลายสิบครั้งและเด็กอีกหลายสิบคน ขณะนี้เป็นสิ่งที่ฉันกำลังทำอยู่ แต่มันก็เหมือนเดิมทุกครั้งและจะสมบูรณ์แบบถ้าตรรกะที่ซ้ำกันนั้นสามารถถูกวางไว้ในผู้ปกครองเพียงครั้งเดียวตามฟังก์ชั่นที่ได้รับ
Scott Klarenbach

ดูไม่ใช่ฟังก์ชั่นลูกที่ฉันต้องการมันเป็นวิธีการตั้งชื่อที่ใช้เพราะระเบียบการตั้งชื่อนั้นสามารถใช้เพื่อโหลดฟังก์ชั่นอื่น ๆ ที่ไม่ได้กำหนดไว้ในวัตถุลูกในปัจจุบัน แต่เกี่ยวข้องกับลูกนั้นตลอดทั้งระบบ
Scott Klarenbach

1
@Scott ฉันเห็นด้วยกับคนอื่น ๆ การจัดการความซับซ้อนและโครงสร้างโค้ดของคุณผิดที่ต้องทำ การมีเพศสัมพันธ์แบบนี้เป็นการตัดสินใจที่ไม่ดีและจะทำให้เกิดความยุ่งเหยิง @SimeVidas ของคุณหมอผีดี :)
Raynos

คำตอบ:


163

ใน ES5 สิ่งที่ดีที่สุดที่ควรทำคือ:

function functionName(fun) {
  var ret = fun.toString();
  ret = ret.substr('function '.length);
  ret = ret.substr(0, ret.indexOf('('));
  return ret;
}

การใช้Function.callerไม่ได้มาตรฐาน Function.callerและarguments.calleeทั้งคู่ถูกห้ามในโหมดเข้มงวด

แก้ไข: คำตอบจาก regex ของ nus ด้านล่างบรรลุสิ่งเดียวกัน แต่มีประสิทธิภาพที่ดีกว่า!

ใน ES6 คุณสามารถใช้งานmyFunction.nameได้

หมายเหตุ: ระวังว่า JS minifiers บางตัวอาจทิ้งชื่อฟังก์ชันเพื่อบีบอัดให้ดีขึ้น คุณอาจต้องปรับการตั้งค่าเพื่อหลีกเลี่ยงปัญหานั้น


ในขณะที่สิ่งนี้ไม่ได้ตอบคำถามที่เพียงพอสำหรับฉัน (เนื่องจากฟังก์ชั่นที่ไม่ระบุชื่อ) มันทำให้ฉันมีความคิดที่จะทำสิ่งนี้: fun.toString().substr(0, 100)สำหรับความต้องการของฉันจะเพียงพอที่จะค้นหาฟังก์ชั่นที่เป็นปัญหา ดังนั้นขอบคุณสำหรับแรงบันดาลใจ!
Campbeln

3
Yup myFunction.nameเป็นสิ่งที่ดีที่สุดใน ES6
Vlad A Ionescu

15
สิ่งที่จุดในmyFunction.nameถ้าคุณพิมพ์ชื่อฟังก์ชัน? เอาชนะวัตถุประสงค์ของตัวแปรเวทย์มนตร์
adi518

2
@ adi518: ไม่จำเป็น .. สมมติว่าคุณมีฟังก์ชั่นมากมายและคุณทำซ้ำไปเรื่อย ๆ โดยใช้สำหรับ / foreach .. จากarr[index].nameนั้นจะใช้งานได้ :)
Debasish Chowdhury

2
@ adi518 มันไม่ได้ไร้ประโยชน์ หากฉันเปลี่ยนชื่อฟังก์ชั่นภายใน IDE ของฉันmyFunction.nameก็จะได้รับการปรับปรุงด้วย แน่นอนว่า intelliJ รองรับการเปลี่ยนชื่อตัวระบุภายในสตริง แต่ก็ใช้งานได้น้อยกว่าอย่างต่อเนื่องและจะล้าสมัยหากใครบางคนลืมที่จะติ๊กตัวเลือก "ค้นหาในสตริง" myFunction.nameเป็นตัวเลือกที่ดีกว่าการเข้ารหัสสตริงเล็กน้อย
byxor

141

ES6 (แรงบันดาลใจจากคำตอบของ sendy halim ด้านล่าง):

myFunction.name

ชี้แจง MDN ตั้งแต่ปี 2015 ใช้งานได้ใน nodejs และเบราว์เซอร์หลักทั้งหมดยกเว้น IE

หมายเหตุ: ในฟังก์ชั่นที่ถูกผูกไว้สิ่งนี้จะให้ " bound <originalName>" คุณจะต้องตัด "ผูกพัน" ถ้าคุณต้องการได้รับชื่อเดิม


ES5 (แรงบันดาลใจจากคำตอบของ Vlad):

หากคุณมีการอ้างอิงถึงฟังก์ชั่นคุณสามารถทำ:

function functionName( func )
{
    // Match:
    // - ^          the beginning of the string
    // - function   the word 'function'
    // - \s+        at least some white space
    // - ([\w\$]+)  capture one or more valid JavaScript identifier characters
    // - \s*        optionally followed by white space (in theory there won't be any here,
    //              so if performance is an issue this can be omitted[1]
    // - \(         followed by an opening brace
    //
    var result = /^function\s+([\w\$]+)\s*\(/.exec( func.toString() )

    return  result  ?  result[ 1 ]  :  '' // for an anonymous function there won't be a match
}
  • ฉันไม่ได้ใช้การทดสอบหน่วยในเรื่องนี้หรือตรวจสอบความแตกต่างของการใช้งาน แต่โดยหลักการแล้วมันควรจะใช้ได้ถ้าไม่แสดงความคิดเห็น
  • หมายเหตุ: จะไม่ทำงานกับฟังก์ชั่นที่ถูกผูกไว้
  • หมายเหตุ: ที่callerและcalleeจะถือว่าเลิก

[1] ฉันรวมมันไว้ที่นี่เพราะมันถูกกฎหมายและบ่อยครั้งที่เครื่องมือการเน้นไวยากรณ์ไม่เพียงพอที่จะคำนึงถึงช่องว่างสีขาวระหว่างชื่อฟังก์ชันและวงเล็บ ในทางกลับกันฉันไม่ได้ตระหนักถึงการใช้. toString () ใด ๆ ที่จะรวมพื้นที่สีขาวที่นี่ด้วยเหตุนี้คุณจึงสามารถละเว้นได้


ตามคำตอบของคำถามดั้งเดิมฉันจะทิ้งมรดกของกาฝากและไปหารูปแบบการออกแบบ OOP แบบดั้งเดิม ฉันเขียนTidBits.OoJsเพื่อเขียนรหัส OOP ใน JavaScript อย่างสะดวกสบายด้วยชุดคุณสมบัติที่เลียนแบบ C ++ (ยังไม่เสร็จสมบูรณ์ แต่ส่วนใหญ่)

ฉันเห็นจากความคิดเห็นที่คุณต้องการหลีกเลี่ยงการส่งผ่านข้อมูลที่parentจำเป็นในการสร้างมัน ฉันต้องยอมรับว่ารูปแบบการออกแบบดั้งเดิมจะไม่ช่วยให้คุณประหยัดจากรูปแบบนั้นได้เนื่องจากโดยทั่วไปถือว่าเป็นสิ่งที่ดีที่จะทำให้การอ้างอิงของคุณชัดเจนและถูกบังคับใช้

ฉันอยากจะแนะนำให้หลีกเลี่ยงฟังก์ชั่นนิรนาม พวกเขาทำการดีบักและสร้างโปรไฟล์ PITA เพียงเพราะทุกอย่างแสดงเป็น "ฟังก์ชันที่ไม่ระบุชื่อ" และไม่มีประโยชน์สำหรับพวกเขาที่ฉันรู้


3
Nice RegEx! นี่คือการทดสอบประสิทธิภาพที่แสดงว่ารหัสของคุณเร็วที่สุดในหลายกรณี โดยทั่วไปดูเหมือนว่า RegEx จะชนะ JS พื้นเมืองโดยความเร็วประมาณ 2x ที่นี่โดยเฉลี่ย jsperf.com/get-function-name/2
Beejor

@ Tomasz สวัสดีขอบคุณที่ชี้ให้เห็น ฉันไม่รู้ ฟังก์ชั่นที่ถูกผูกไว้เป็นจริงฟังก์ชั่นใหม่ที่ห่อฟังก์ชั่นเดิมของคุณ มาตรฐาน ecmascript § 19.2.3.2 กำหนดว่าชื่อของฟังก์ชั่นใหม่จะต้อง "ผูก" + originalName วิธีการ toString จะไม่ทำงานในฟังก์ชั่นที่ถูกผูกไว้อย่างใดอย่างหนึ่ง ... คุณจะต้องตัดคำที่ถูกผูกไว้

จุดใน myFunction.name คืออะไรถ้าคุณพิมพ์ชื่อฟังก์ชั่น เอาชนะวัตถุประสงค์ของตัวแปรเวทย์มนตร์
Borjovsky

โปรดทราบว่าหากคุณใช้ React Native อาจทำงานไม่ถูกต้อง ฉันมีโครงการ RN ที่ฉันกำลังทำงานกับงานแสดงสินค้ารุ่นที่ 36 และ.nameคุณสมบัติของวิธีการองค์ประกอบแสดงเป็นสตริง "ค่า" ไม่ว่าจะเรียกว่าอะไร แปลกมากในขณะที่การทดสอบในแอปเอ็กซ์โปมันก็โอเค แต่เมื่อรวบรวมเป็นแอปพลิเคชันจริงมันจะล้มเหลวอย่างเงียบ ๆ
Andy Corman

64

สิ่งที่คุณกำลังทำคือการกำหนดฟังก์ชั่นที่ไม่มีชื่อให้กับตัวแปร คุณอาจต้องใช้ชื่อฟังก์ชันนิพจน์แทน ( http://kangax.github.com/nfe/ )

var x = function x() {
    console.log( arguments.callee.name );
}
x();

อย่างไรก็ตามฉันไม่แน่ใจว่าจะใช้เบราว์เซอร์ข้ามเท่าใด มีปัญหากับ IE6 ที่ทำให้ชื่อฟังก์ชันของคุณรั่วไหลไปยังขอบเขตด้านนอก ยัง arguments.callee strict modeเป็นชนิดของการเลิกและจะส่งผลให้เกิดข้อผิดพลาดหากคุณกำลังใช้


1
สิ่งนี้ใช้ไม่ได้กับเบราว์เซอร์ Safari เวอร์ชันเก่า
Anubhav Gupta

17

ใด ๆ ที่constructorแสดงคุณสมบัติnameซึ่งเป็นชื่อฟังก์ชั่น คุณเข้าถึงconstructorอินสแตนซ์ (โดยใช้new) หรือprototype:

function Person() {
  console.log(this.constructor.name); //Person
}

var p = new Person();
console.log(p.constructor.name); //Person

console.log(Person.prototype.constructor.name);  //Person

6
ครั้งแรกที่console.logบันทึกการโทรwindowหรือสำหรับฉันขึ้นอยู่ที่ผมใช้มันไม่ได้Object Person
Bart S

คุณแน่ใจหรือไม่ว่าคุณใช้อินสแตนซ์ของ "ใหม่" ไม่เช่นนั้นจะใช้งานไม่ได้
roland

14

ดูเหมือนสิ่งที่โง่ที่สุดที่ฉันเขียนในชีวิตของฉัน แต่มันตลก: D

function getName(d){
  const error = new Error();
  const firefoxMatch = (error.stack.split('\n')[0 + d].match(/^.*(?=@)/) || [])[0];
  const chromeMatch = ((((error.stack.split('at ') || [])[1 + d] || '').match(/(^|\.| <| )(.*[^(<])( \()/) || [])[2] || '').split('.').pop();
  const safariMatch = error.stack.split('\n')[0 + d];

  // firefoxMatch ? console.log('firefoxMatch', firefoxMatch) : void 0;
  // chromeMatch ? console.log('chromeMatch', chromeMatch) : void 0;
  // safariMatch ? console.log('safariMatch', safariMatch) : void 0;

  return firefoxMatch || chromeMatch || safariMatch;
}

d- ความลึกของกองซ้อน 0- คืนชื่อฟังก์ชั่นนี้1- ผู้ปกครอง ฯลฯ
[0 + d]- เพียงเพื่อความเข้าใจ - เกิดอะไรขึ้น
firefoxMatch- ใช้งานได้กับซาฟารี แต่ฉันมีเวลาน้อยมากในการทดสอบเพราะเจ้าของแม็คกลับมาหลังจากสูบบุหรี่และขับไล่ฉันออกไป: '(

การทดสอบ:

function limbo(){
  for(let i = 0; i < 4; i++){
    console.log(getName(i));
  }
}
function lust(){
  limbo();
}
function gluttony(){
  lust();
}

gluttony();

ผลลัพธ์:
Chrome:
ป้อนคำอธิบายรูปภาพที่นี่

Fitefox:
ป้อนคำอธิบายรูปภาพที่นี่

โซลูชันนี้สร้างเพื่อความสนุกเท่านั้น! อย่าใช้มันสำหรับโครงการจริง มันไม่ได้ขึ้นอยู่กับข้อกำหนดของ ES มันขึ้นอยู่กับการใช้งานเบราว์เซอร์เท่านั้น หลังจากการอัปเดต chrome / firefox / safari ครั้งถัดไปอาจทำให้เสีย
ยิ่งไปกว่านั้นไม่มีการประมวลผลข้อผิดพลาด (ฮ่า) - ถ้าdจะมากกว่าความยาวสแต็ค - คุณจะได้รับข้อผิดพลาด;
สำหรับรูปแบบ messaage ข้อผิดพลาดของ wrowsers อื่น ๆ - คุณจะได้รับข้อผิดพลาด
มันจะต้องใช้ได้กับคลาส ES6 ( .split('.').pop()) แต่คุณก็จะได้รับความผิดปกติ


13

สิ่งนี้อาจใช้ได้กับคุณ:

function foo() { bar(); }

function bar() { console.log(bar.caller.name); }

วิ่ง foo () จะส่งออก "foo" หรือไม่ได้กำหนดถ้าคุณโทรจากฟังก์ชั่นที่ไม่ระบุชื่อ

มันทำงานร่วมกับตัวสร้างเช่นกันในกรณีนี้มันจะเอาท์พุทชื่อของตัวสร้างการเรียก (เช่น "Foo")

ข้อมูลเพิ่มเติมที่นี่: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller

พวกเขาอ้างว่ามันไม่ได้มาตรฐาน แต่ก็สนับสนุนโดยเบราว์เซอร์ที่สำคัญทั้งหมด: Firefox, Safari, Chrome, Opera และ IE


ไม่สามารถใช้งานได้ในโหมดเข้มงวด ... mmm
Ka Mok

8

คุณทำไม่ได้ ฟังก์ชั่นไม่มีชื่อตามมาตรฐาน (แม้ว่าโมซิลล่ามีคุณลักษณะดังกล่าว) - พวกเขาสามารถกำหนดให้กับตัวแปรที่มีชื่อเท่านั้น

ความคิดเห็นของคุณ:

// access fully qualified name (ie "my.namespace.myFunc")

อยู่ภายในฟังก์ชัน my.namespace.myFunc.getFn

สิ่งที่คุณสามารถทำได้คือส่งคืนตัวสร้างของวัตถุที่สร้างขึ้นใหม่

ดังนั้นคุณสามารถพูดได้

var obj = new my.namespace.myFunc();
console.info(obj.constructor); //my.namespace.myFunc

1
ฉันต้องการภายใน func เพราะฉันผ่านมันขึ้นมาในห่วงโซ่การสืบทอดและฉันละเว้นสิ่งนั้นสั้น ๆ
Scott Klarenbach

1
'this' จะเป็นอินสแตนซ์ที่เรียกใช้ฟังก์ชัน ดังนั้นหากคุณ 'นี่' ในฟังก์ชันผู้ปกครองที่จะให้อินสแตนซ์ของฟังก์ชันที่เรียกว่า นั่นคือทั้งหมดที่คุณควรต้องมี - ไม่แน่ใจว่าทำไมคุณถึงต้องการชื่อด้วย
จงเพียร

1
ดีในผู้ปกครองฉันสามารถเข้าถึงฟังก์ชั่นอื่น ๆ โดยการประชุมเช่น ns [child] [schema] หรือ ns [child] [dbService] หากไม่มีมันฉันจะต้องเขียนโค้ดอ้างอิงเหล่านี้อย่างหนักในทุกชั้นของเด็ก
Scott Klarenbach

1
กรณีการใช้งานของฉันสำหรับการค้นหาชื่อเพื่อให้ง่ายขึ้นสำหรับการสร้างข้อความ console.error ที่บอกว่าข้อความมาจากไหนโดยไม่ต้องเปลี่ยนกลับเป็นสแต็กการถ่ายโอนข้อมูล เช่น console.error ({'ข้อผิดพลาด': {การอ้างอิง self.name} + "ข้อผิดพลาดพร้อมพารามิเตอร์อินพุต") มันง่ายกว่าที่จะตัด / วางข้อความแสดงข้อผิดพลาดที่ทำซ้ำในหลายฟังก์ชั่นถ้าคุณไม่ต้องหยุดและเปลี่ยนข้อความภายในแต่ละครั้ง ในกรณีของฉันฉันกำลังส่งคืนข้อผิดพลาดของสัญญาจากการโทรตามสัญญาหลายครั้ง - ดีที่ได้ทราบว่าสัญญา / ฟังก์ชันสร้างข้อผิดพลาด
สกอตต์

7

คุณสามารถใช้สิ่งนี้สำหรับเบราว์เซอร์ที่รองรับ Error.stack (อาจไม่เกือบทั้งหมด)

function WriteSomeShitOut(){ 
  var a = new Error().stack.match(/at (.*?) /);
  console.log(a[1]);
} 
WriteSomeShitOut();

แน่นอนว่านี่เป็นฟังก์ชั่นปัจจุบัน แต่คุณเข้าใจแล้ว

มีความสุขน้ำลายไหลในขณะที่คุณรหัส


4

คุณสามารถใช้nameคุณสมบัติเพื่อรับชื่อฟังก์ชันยกเว้นว่าคุณกำลังใช้ฟังก์ชันที่ไม่ระบุชื่อ

ตัวอย่างเช่น:

var Person = function Person () {
  this.someMethod = function () {};
};

Person.prototype.getSomeMethodName = function () {
  return this.someMethod.name;
};

var p = new Person();
// will return "", because someMethod is assigned with anonymous function
console.log(p.getSomeMethodName());

ตอนนี้ลองทำฟังก์ชั่นที่มีชื่อ

var Person = function Person () {
  this.someMethod = function someMethod() {};
};

ตอนนี้คุณสามารถใช้

// will return "someMethod"
p.getSomeMethodName()

4

คุณสามารถใช้ชื่อตัวสร้างเช่น:

{your_function}.prototype.constructor.name

รหัสนี้เพียงแค่ส่งกลับชื่อของวิธีการ


3

ในฐานะที่เป็นส่วนหนึ่งECMAScript 6คุณสามารถใช้วิธีFunction.name

function doSomething() {}

alert(doSomething.name); // alerts "doSomething"

ใน ReactJS คุณต้องเพิ่มสิ่งนี้: console.log (this.doSomething.name);
Bitclaw

2
ที่อยู่นอกฟังก์ชั่น
สกอตต์

3

คุณสามารถใช้Function.name :

ในการใช้งานจาวาสคริปต์ส่วนใหญ่เมื่อคุณมีการอ้างอิงคอนสตรัคเตอร์ในขอบเขตคุณสามารถรับชื่อสตริงจากคุณสมบัติชื่อ (เช่น Function.name หรือ Object.constructor.name

คุณสามารถใช้Function.callee :

พื้นเมืองarguments.callerวิธีการได้รับการคัดค้าน แต่เบราว์เซอร์ส่วนใหญ่สนับสนุนFunction.callerซึ่งจะกลับวัตถุกล่าวอ้างจริง (ร่างกายของรหัส): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ ฟังก์ชั่น / โทร? redirectlocale = th & redirectslug = JavaScript% 2FReference% 2FGlobal_Objects% 2FFunction% 2Fcaller

คุณสามารถสร้างแผนที่แหล่งที่มา :

หากสิ่งที่คุณต้องการคือลายเซ็นของฟังก์ชั่นตัวอักษร ("ชื่อ" ของมัน) และไม่ใช่วัตถุเองคุณอาจต้องหันไปใช้สิ่งที่กำหนดเองมากกว่านี้เล็กน้อยเช่นการสร้างการอ้างอิงอาร์เรย์ของค่าสตริง API ที่คุณต้องการ เข้าถึงบ่อยครั้ง คุณสามารถแมปพวกเขาเข้าด้วยกันโดยใช้Object.keys()และชุดสตริงของคุณหรือดูที่ไลบรารีแผนที่ของ Mozilla บน GitHub สำหรับโครงการขนาดใหญ่: https://github.com/mozilla/source-map


2

ฉันรู้ว่านี่เป็นคำถามเก่า แต่เมื่อเร็ว ๆ นี้ฉันได้พบกับปัญหาที่คล้ายกันในขณะที่พยายามตกแต่งวิธีการของ React Component เพื่อใช้ในการดีบั๊ก อย่างที่ผู้คนพูดกันแล้วarguments.callerและarguments.calleeถูกห้ามในโหมดเข้มงวดซึ่งอาจเปิดใช้งานโดยค่าเริ่มต้นในการทำ React transpiling ของคุณ คุณสามารถปิดการใช้งานหรือฉันสามารถแฮ็คอื่นได้เพราะใน React ฟังก์ชันคลาสทั้งหมดถูกตั้งชื่อคุณสามารถทำสิ่งนี้ได้จริง:

Component.prototype.componentWillMount = function componentWillMount() {
    console.log('Callee name: ', this.__proto__.constructor.toString().substr(0,30));
...
}

1

สิ่งนี้ใช้ได้สำหรับฉัน

function AbstractDomainClass() {
    this.className = function() {
        if (!this.$className) {
            var className = this.constructor.toString();
            className = className.substr('function '.length);
            className = className.substr(0, className.indexOf('('));
            this.$className = className;
        }
        return this.$className;
    }
}

รหัสทดสอบ:

var obj = new AbstractDomainClass();
expect(obj.className()).toBe('AbstractDomainClass');

1

ฉันมีปัญหาที่คล้ายกันและฉันแก้ไขได้ดังนี้

Function.prototype.myname = function() {
   return this.toString()
       .substr( 0, this.toString().indexOf( "(" ) )
       .replace( "function ", "" ); 
}

รหัสนี้ใช้อย่างสะดวกสบายยิ่งขึ้นหนึ่งคำตอบที่ฉันได้อ่านมาแล้วที่ด้านบนของการสนทนานี้ ตอนนี้ฉันมีฟังก์ชั่นสมาชิกที่ดึงชื่อของวัตถุใด ๆ นี่คือสคริปต์แบบเต็ม ...

<script language="javascript" TYPE="text/javascript">

    Function.prototype.myname = function() { 
        return this.toString()
            .substr( 0, this.toString().indexOf( "(" ) )
            .replace("function ", "" ); 
    }
    function call_this( _fn ) { document.write( _fn.myname() ); }
    function _yeaaahhh() { /* do something */ }
    call_this( _yeaaahhh ); 

</script>


0

สิ่งนี้จะทำงานใน ES5, ES6, เบราว์เซอร์ทั้งหมดและฟังก์ชั่นโหมดเข้มงวด

นี่คือลักษณะของฟังก์ชันที่มีชื่อ

(function myName() {
  console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at myName (<anonymous>:2:15)

นี่คือลักษณะที่ปรากฏด้วยฟังก์ชันที่ไม่ระบุชื่อ

(() => {
  console.log(new Error().stack.split(/\r\n|\r|\n/g)[1].trim());
})();
at <anonymous>:2:15

สิ่งนี้ให้ผลลัพธ์ที่แตกต่างกันต่อเบราว์เซอร์ Chrome: at myName (<anonymous>:2:15)Firefox:@debugger eval code:3:3
jkdev

(function myName () {console.log (ข้อผิดพลาดใหม่ (). stack.split (/ \ r \ n | \ r | \ n / g) [1] .trim (). split ("") [1]) ;}) ();
Zibri

-2

ดูที่นี่: http://www.tek-tips.com/viewthread.cfm?qid=1209619

arguments.callee.toString();

น่าจะเหมาะกับความต้องการของคุณ


3
arguments.callee.toString () เพียงแค่ส่งคืนแหล่งที่มาของฟังก์ชั่น
Scott Klarenbach

2
ไม่อนุญาต: คุณสมบัติ 'ผู้โทร', 'callee' และ 'การขัดแย้ง' อาจไม่สามารถเข้าถึงได้ในฟังก์ชั่นโหมดที่เข้มงวดหรือวัตถุที่เป็นอาร์กิวเมนต์สำหรับการโทรถึงพวกเขา
Eric Hodonsky

-2

คุณสามารถใช้ Error.stack เพื่อติดตามชื่อฟังก์ชั่นและตำแหน่งที่แน่นอนของตำแหน่งที่คุณอยู่

ดูstacktrace.js


-3

วิธีง่ายๆในการรับชื่อฟังก์ชั่นจากภายใน fuction ที่คุณกำลังเรียกใช้

function x(){alert(this.name)};x()


1
มอบ GUID ให้ฉัน
Tamir Daniely

1
ระวังเนื้อหาของthisมันโดยทั่วไปสามารถเป็นอะไรก็ได้ ลอง(function(){console.log(this.name);}).bind({name: "put basically anything here even an object maybe a 1TB string maybe a class definition"})()
Valen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.