เป็นไปได้ที่จะทำสิ่งนี้:
myfile.js:
function foo() {
alert(<my-function-name>);
// pops-up "foo"
// or even better: "myfile.js : foo"
}
ฉันมีกรอบ Dojo และ jQuery ในสแต็กของฉันดังนั้นหากหนึ่งในนั้นทำให้ง่ายขึ้น
เป็นไปได้ที่จะทำสิ่งนี้:
myfile.js:
function foo() {
alert(<my-function-name>);
// pops-up "foo"
// or even better: "myfile.js : foo"
}
ฉันมีกรอบ Dojo และ jQuery ในสแต็กของฉันดังนั้นหากหนึ่งในนั้นทำให้ง่ายขึ้น
คำตอบ:
ใน ES5 ขึ้นไปจะไม่มีการเข้าถึงข้อมูลนั้น
ในรุ่นเก่าของ JS arguments.callee
คุณจะได้รับโดยใช้
คุณอาจต้องแยกชื่อแม้ว่ามันอาจจะรวมถึงขยะบางพิเศษ arguments.callee.name
แม้ว่าในการใช้งานบางอย่างที่คุณสามารถได้รับชื่อโดยใช้
แยก:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
ที่มา: Javascript - ได้รับชื่อของฟังก์ชั่นในปัจจุบัน
arguments.callee
คือไม่ได้รับอนุญาตภายใต้โหมดเข้มงวด
สำหรับฟังก์ชั่นที่ไม่ระบุชื่อ
function foo()
{
alert(arguments.callee.name)
}
แต่ในกรณีที่ตัวจัดการข้อผิดพลาดผลลัพธ์จะเป็นชื่อของฟังก์ชันตัวจัดการข้อผิดพลาดใช่ไหม
ทุกสิ่งที่คุณต้องการนั้นง่าย สร้างฟังก์ชั่น:
function getFuncName() {
return getFuncName.caller.name
}
หลังจากนั้นเมื่อใดก็ตามที่คุณต้องการคุณเพียงแค่ใช้:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
แทนที่จะเป็นชื่อของผู้โทร
ตามMDN
คำเตือน: ECMAScript (ES5) รุ่นที่ 5 ห้ามมิให้มีการใช้ arguments.callee () ในโหมดเข้มงวด หลีกเลี่ยงการใช้ arguments.callee () โดยให้ชื่อฟังก์ชันแก่นิพจน์หรือใช้ฟังก์ชันประกาศที่ฟังก์ชันต้องเรียกใช้ฟังก์ชันเอง
ตามที่ระบุไว้สิ่งนี้จะใช้เฉพาะในกรณีที่สคริปต์ของคุณใช้ "โหมดเข้มงวด" นี่คือเหตุผลด้านความปลอดภัยเป็นหลักและในปัจจุบันน่าเศร้าที่ไม่มีทางเลือกสำหรับสิ่งนี้
สิ่งนี้ควรทำ:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
caller.toString()
สำหรับผูที่ใช้เพียง
[
สิ่งนี้จะต้องอยู่ในหมวดหมู่ของ "แฮ็กที่น่าเกลียดที่สุดในโลก" แต่ที่นี่คุณไป
ก่อนอื่นการพิมพ์ชื่อของฟังก์ชั่นปัจจุบัน (เหมือนในคำตอบอื่น ๆ ) ดูเหมือนว่าจะมีการใช้งานที่ จำกัด กับฉันเนื่องจากคุณรู้อยู่แล้วว่าฟังก์ชั่นนี้คืออะไร!
อย่างไรก็ตามการค้นหาชื่อของฟังก์ชันการเรียกอาจเป็นประโยชน์สำหรับฟังก์ชันติดตาม นี่เป็น regexp แต่การใช้ indexOf จะเร็วขึ้นประมาณ 3 เท่า:
function getFunctionName() {
var re = /function (.*?)\(/
var s = getFunctionName.caller.toString();
var m = re.exec( s )
return m[1];
}
function me() {
console.log( getFunctionName() );
}
me();
นี่คือวิธีที่ใช้งานได้:
export function getFunctionCallerName (){
// gets the text between whitespace for second part of stacktrace
return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}
จากนั้นในการทดสอบของคุณ:
import { expect } from 'chai';
import { getFunctionCallerName } from '../../../lib/util/functions';
describe('Testing caller name', () => {
it('should return the name of the function', () => {
function getThisName(){
return getFunctionCallerName();
}
const functionName = getThisName();
expect(functionName).to.equal('getThisName');
});
it('should work with an anonymous function', () => {
const anonymousFn = function (){
return getFunctionCallerName();
};
const functionName = anonymousFn();
expect(functionName).to.equal('anonymousFn');
});
it('should work with an anonymous function', () => {
const fnName = (function (){
return getFunctionCallerName();
})();
expect(/\/util\/functions\.js/.test(fnName)).to.eql(true);
});
});
โปรดทราบว่าการทดสอบครั้งที่สามจะใช้งานได้เมื่อการทดสอบอยู่ใน / util / ฟังก์ชั่น
getMyName
ฟังก์ชั่นในตัวอย่างด้านล่างผลตอบแทนที่ชื่อของฟังก์ชั่นการโทร มันสับและอาศัยอยู่กับที่ไม่ได้มาตรฐานError.prototype.stack
คุณลักษณะ: โปรดทราบว่ารูปแบบของสตริงที่ส่งกลับโดยError.prototype.stack
มีการใช้งานแตกต่างกันในเอนจินต่าง ๆ ดังนั้นสิ่งนี้อาจไม่สามารถใช้ได้ทุกที่
function getMyName() {
var e = new Error('dummy');
var stack = e.stack
.split('\n')[2]
// " at functionName ( ..." => "functionName"
.replace(/^\s+at\s+(.+?)\s.+/g, '$1' );
return stack
}
function foo(){
return getMyName()
}
function bar() {
return foo()
}
console.log(bar())
เกี่ยวกับการแก้ปัญหาอื่น ๆarguments.callee
ไม่ได้รับอนุญาตในโหมดที่เข้มงวดและFunction.prototype.caller
เป็นที่ไม่ได้มาตรฐานและไม่ได้รับอนุญาตในโหมดที่เข้มงวด
กรณีการใช้งานอื่นอาจเป็นตัวส่งเหตุการณ์ที่ถูกผูกไว้ที่รันไทม์:
MyClass = function () {
this.events = {};
// Fire up an event (most probably from inside an instance method)
this.OnFirstRun();
// Fire up other event (most probably from inside an instance method)
this.OnLastRun();
}
MyClass.prototype.dispatchEvents = function () {
var EventStack=this.events[GetFunctionName()], i=EventStack.length-1;
do EventStack[i]();
while (i--);
}
MyClass.prototype.setEvent = function (event, callback) {
this.events[event] = [];
this.events[event].push(callback);
this["On"+event] = this.dispatchEvents;
}
MyObject = new MyClass();
MyObject.setEvent ("FirstRun", somecallback);
MyObject.setEvent ("FirstRun", someothercallback);
MyObject.setEvent ("LastRun", yetanothercallback);
ข้อได้เปรียบที่นี่คือโปรแกรมเลือกจ่ายงานสามารถนำกลับมาใช้ใหม่ได้อย่างง่ายดายและไม่จำเป็นต้องรับคิวการจัดส่งเป็นอาร์กิวเมนต์แทนโดยจะมาพร้อมกับชื่อการเรียกใช้ ...
ในท้ายที่สุดกรณีทั่วไปที่แสดงไว้ที่นี่จะเป็น "การใช้ชื่อฟังก์ชันเป็นอาร์กิวเมนต์เพื่อให้คุณไม่ต้องผ่านมันอย่างชัดเจน" และอาจเป็นประโยชน์ในหลาย ๆ กรณีเช่น jquery animate () ตัวเลือกการโทรกลับ หรือในการโทรกลับหมดเวลา / ช่วงเวลา (เช่นคุณผ่าน funcion NAME เท่านั้น)
ชื่อของฟังก์ชั่นปัจจุบันและวิธีการรับสามารถดูเหมือนจะมีการเปลี่ยนแปลงในช่วง 10 ปีที่ผ่านมาเนื่องจากคำถามนี้ถูกถาม
ตอนนี้ไม่ได้เป็นนักพัฒนาเว็บมืออาชีพที่รู้ประวัติของเบราว์เซอร์ทั้งหมดที่เคยมีอยู่นี่คือวิธีที่มันใช้ได้กับฉันในเบราว์เซอร์ chrome 2019:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
คำตอบอื่น ๆ บางข้อพบข้อผิดพลาดของ Chrome เกี่ยวกับรหัสจาวาสคริปต์ที่เข้มงวดและอะไรก็ตาม
เมื่อคุณเขียนฟังก์ชั่นชื่อfoo
และคุณรู้ว่ามันเป็นmyfile.js
เพราะเหตุใดคุณจึงจำเป็นต้องได้รับข้อมูลนี้แบบไดนามิก?
ที่กล่าวว่าคุณสามารถใช้arguments.callee.toString()
ภายในฟังก์ชั่น (นี่คือการเป็นตัวแทนสตริงของฟังก์ชั่นทั้งหมด) และ regex ออกค่าของชื่อฟังก์ชั่น
นี่คือฟังก์ชั่นที่จะแยกชื่อของตัวเองออกมา:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
การรวมกันของคำตอบบางอย่างที่ฉันเคยเห็นที่นี่ (ทดสอบใน FF, Chrome, IE11)
function functionName()
{
var myName = functionName.caller.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
return myName;
}
function randomFunction(){
var proof = "This proves that I found the name '" + functionName() + "'";
alert(proof);
}
การเรียก randomFunction () จะแจ้งเตือนสตริงที่มีชื่อฟังก์ชั่น
การสาธิต JS Fiddle: http://jsfiddle.net/mjgqfhbe/
คำตอบที่อัปเดตสำหรับสิ่งนี้สามารถพบได้ในคำตอบนี้: https://stackoverflow.com/a/2161470/632495
และหากคุณไม่รู้สึกอยากคลิก:
function test() {
var z = arguments.callee.name;
console.log(z);
}
ข้อมูลเป็นจริงในปี 2559
ส่งผลให้ Opera
>>> (function func11 (){
... console.log(
... 'Function name:',
... arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
...
... (function func12 (){
... console.log('Function name:', arguments.callee.name)
... })();
Function name:, func11
Function name:, func12
ส่งผลให้ Chrome
(function func11 (){
console.log(
'Function name:',
arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
})();
(function func12 (){
console.log('Function name:', arguments.callee.name)
})();
Function name: func11
Function name: func12
ส่งผลให้ NodeJS
> (function func11 (){
... console.log(
..... 'Function name:',
..... arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
Function name: func11
undefined
> (function func12 (){
... console.log('Function name:', arguments.callee.name)
... })();
Function name: func12
ไม่ทำงานใน Firefox ไม่ได้ทดสอบบน IE และ Edge
ส่งผลให้ NodeJS
> var func11 = function(){
... console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11
ส่งผลให้ Chrome
var func11 = function(){
console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11
ไม่ทำงานใน Firefox, Opera ไม่ได้ทดสอบบน IE และ Edge
หมายเหตุ:
~ $ google-chrome --version
Google Chrome 53.0.2785.116
~ $ opera --version
Opera 12.16 Build 1860 for Linux x86_64.
~ $ firefox --version
Mozilla Firefox 49.0
~ $ node
node nodejs
~ $ nodejs --version
v6.8.1
~ $ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
(function f() {
console.log(f.name); //logs f
})();
รูปแบบตัวพิมพ์:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
หมายเหตุมีเฉพาะในเอ็นจิ้นที่สอดคล้องกับ ES6 / ES2015 ดูเพิ่มเติม
นี่คือหนึ่งซับ:
arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')
แบบนี้:
function logChanges() {
let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
console.log(whoami + ': just getting started.');
}
นี่คือตัวแปรของIgor Ostroumov'sคำตอบที่คำตอบ :
หากคุณต้องการใช้เป็นค่าเริ่มต้นสำหรับพารามิเตอร์คุณต้องพิจารณาการเรียกระดับที่สองเป็น 'ผู้โทร':
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
สิ่งนี้จะอนุญาตให้มีการนำมาใช้ซ้ำในหลายฟังก์ชั่น
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(myFunctionName);
}
// pops-up "foo"
function foo()
{
bar();
}
function crow()
{
bar();
}
foo();
crow();
หากคุณต้องการชื่อไฟล์ด้วยนี่คือคำตอบที่ใช้คำตอบจากF-3000กับคำถามอื่น:
function getCurrentFileName()
{
let currentFilePath = document.scripts[document.scripts.length-1].src
let fileName = currentFilePath.split('/').pop() // formatted to the OP's preference
return fileName
}
function bar(fileName = getCurrentFileName(), myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(fileName + ' : ' + myFunctionName);
}
// or even better: "myfile.js : foo"
function foo()
{
bar();
}
คำตอบสั้น ๆ : alert(arguments.callee.name);