Câu trả lời:
Trong ES5 trở lên, không có quyền truy cập vào thông tin đó.
Trong các phiên bản cũ hơn của JS, bạn có thể lấy nó bằng cách sử dụng arguments.callee
.
Bạn có thể phải phân tích tên, mặc dù nó có thể sẽ bao gồm một số rác bổ sung. Mặc dù, trong một số triển khai, bạn chỉ cần lấy tên bằng cách sử dụng arguments.callee.name
.
Phân tích cú pháp:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
Nguồn: Javascript - lấy tên hàm hiện tại .
arguments.callee
là không được phép trong chế độ nghiêm ngặt.
Đối với các chức năng không ẩn danh
function foo()
{
alert(arguments.callee.name)
}
Nhưng trong trường hợp trình xử lý lỗi, kết quả sẽ là tên của hàm xử lý lỗi, phải không?
Tất cả những gì bạn cần là đơn giản. Tạo chức năng:
function getFuncName() {
return getFuncName.caller.name
}
Sau đó, bất cứ khi nào bạn cần, bạn chỉ cần sử dụng:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
chứ không phải tên của người gọi nó.
Theo MDN
Cảnh báo: Phiên bản thứ 5 của ECMAScript (ES5) cấm sử dụng argument.callee () trong chế độ nghiêm ngặt. Tránh sử dụng argument.callee () bằng cách đặt tên biểu thức hàm hoặc sử dụng khai báo hàm trong đó hàm phải gọi chính nó.
Như đã lưu ý, điều này chỉ áp dụng nếu tập lệnh của bạn sử dụng "chế độ nghiêm ngặt". Điều này chủ yếu là vì lý do bảo mật và đáng buồn là hiện tại không có sự thay thế nào cho việc này.
Điều này nên làm điều đó:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
Đối với người gọi, chỉ cần sử dụng caller.toString()
.
[
Điều này phải thuộc danh mục "những vụ hack xấu nhất thế giới", nhưng ở đây bạn đi.
Trước tiên, việc in tên của hàm hiện tại (như trong các câu trả lời khác) dường như đã hạn chế sử dụng đối với tôi, vì bạn đã biết chức năng này là gì!
Tuy nhiên, việc tìm ra tên của chức năng gọi có thể khá hữu ích cho chức năng theo dõi. Đây là một biểu thức chính quy, nhưng sử dụng indexOf sẽ nhanh hơn khoảng 3 lần:
function getFunctionName() {
var re = /function (.*?)\(/
var s = getFunctionName.caller.toString();
var m = re.exec( s )
return m[1];
}
function me() {
console.log( getFunctionName() );
}
me();
Đây là một cách sẽ làm việc:
export function getFunctionCallerName (){
// gets the text between whitespace for second part of stacktrace
return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}
Sau đó, trong các bài kiểm tra của bạn:
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);
});
});
Lưu ý rằng thử nghiệm thứ ba sẽ chỉ hoạt động nếu thử nghiệm được đặt trong / hồn / chức năng
Các getMyName
chức năng trong đoạn mã dưới đây trả về tên của hàm gọi. Đó là một hack và dựa vào tính năng không chuẩn : Error.prototype.stack
. Lưu ý rằng định dạng của chuỗi được trả về Error.prototype.stack
được triển khai khác nhau trong các công cụ khác nhau, vì vậy điều này có thể sẽ không hoạt động ở mọi nơi:
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())
Về các giải pháp khác: arguments.callee
không được phép trong chế độ nghiêm ngặt và Function.prototype.caller
là phi tiêu chuẩn và không được phép vào chế độ nghiêm ngặt .
Một trường hợp sử dụng khác có thể là một bộ điều phối sự kiện bị ràng buộc trong thời gian chạy:
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);
Ưu điểm ở đây là bộ điều phối có thể dễ dàng được sử dụng lại và không phải nhận hàng đợi công văn làm đối số, thay vào đó, nó đi kèm với tên gọi ...
Cuối cùng, trường hợp chung được trình bày ở đây sẽ là "sử dụng tên hàm làm đối số để bạn không phải chuyển nó một cách rõ ràng" và điều đó có thể hữu ích trong nhiều trường hợp, như gọi lại tùy chọn jquery animate (), hoặc trong các cuộc gọi lại thời gian chờ / khoảng thời gian, (tức là bạn chỉ vượt qua một TÊN TÊN).
Tên của hàm hiện tại và cách có thể lấy được dường như đã thay đổi trong 10 năm qua, vì câu hỏi này đã được hỏi.
Bây giờ, không phải là một nhà phát triển web chuyên nghiệp, người biết về tất cả lịch sử của tất cả các trình duyệt đã từng tồn tại, đây là cách nó hoạt động với tôi trong trình duyệt chrome 2019:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
Một số câu trả lời khác gặp phải một số lỗi chrome về mã javascript nghiêm ngặt và không có gì.
Vì bạn đã viết một hàm có tên foo
và bạn biết đó là myfile.js
lý do tại sao bạn cần lấy thông tin này một cách linh hoạt?
Điều đó đang được nói rằng bạn có thể sử dụng arguments.callee.toString()
bên trong hàm (đây là biểu diễn chuỗi của toàn bộ hàm) và lấy ra giá trị của tên hàm.
Đây là một chức năng sẽ nhổ tên của chính nó:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
Một sự kết hợp của một vài câu trả lời tôi đã thấy ở đây. (Đã thử nghiệm trong 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);
}
Gọi RandomFunction () sẽ cảnh báo một chuỗi có chứa tên hàm.
Bản trình diễn JS Fiddle: http://jsfiddle.net/mjgqfhbe/
Câu trả lời cập nhật cho điều này có thể được tìm thấy tại câu trả lời này: https://stackoverflow.com/a/2161470/632495
và, nếu bạn không cảm thấy muốn nhấp vào:
function test() {
var z = arguments.callee.name;
console.log(z);
}
Thông tin là thực tế vào năm 2016.
Kết quả trong 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
Kết quả trong 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
Kết quả trong 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
Không hoạt động trong Firefox. Chưa được kiểm tra trên IE và Edge.
Kết quả trong NodeJS
> var func11 = function(){
... console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11
Kết quả trong Chrome
var func11 = function(){
console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11
Không hoạt động trong Firefox, Opera. Chưa được kiểm tra trên IE và Edge.
Ghi chú:
~ $ 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
})();
Biến thể bản in:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
Lưu ý chỉ có sẵn trong các công cụ tuân thủ ES6 / ES2015. Để xem thêm
Đây là một lót:
arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')
Như thế này:
function logChanges() {
let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
console.log(whoami + ': just getting started.');
}
Đây là một biến thể của câu trả lời của Igor Ostroumov :
Nếu bạn muốn sử dụng nó làm giá trị mặc định cho tham số, bạn cần xem xét cuộc gọi cấp hai đến 'người gọi':
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
Điều này sẽ tự động cho phép thực hiện có thể sử dụng lại trong nhiều chức năng.
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(myFunctionName);
}
// pops-up "foo"
function foo()
{
bar();
}
function crow()
{
bar();
}
foo();
crow();
Nếu bạn cũng muốn tên tệp, đây là giải pháp sử dụng câu trả lời từ F-3000 cho một câu hỏi khác:
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();
}
Thử:
alert(arguments.callee.toString());