Tên hàm động trong javascript?


87

Tôi có cái này:

this.f = function instance(){};

Tôi muốn có cái này:

this.f = function ["instance:" + a](){};

10
Bạn không thể. Nhưng bạn có thể cóthis["instance"] = function() { }
Raynos


Để làm rõ những gì Raynos đang nói, bạn có thể làm this["instance" + a] = function() { }. Điều đó không rõ ràng với tôi.
Andrew

Câu trả lời:


7

cập nhật

Như những người khác đã đề cập, đây không phải là giải pháp nhanh nhất và cũng không được khuyến khích nhất. Giải pháp của Marcosc dưới đây là cách để đi.

Bạn có thể sử dụng eval:

var code = "this.f = function " + instance + "() {...}";
eval(code);

1
đó là những gì tôi yêu cầu, cảm ơn! (Dù sao thì tôi sẽ không sử dụng tính năng này vì nó quá chậm)
Totty.js

3
Tôi biết đây là những gì OP yêu cầu, nhưng đây là một ý tưởng kinh khủng. Chỉ vì bạn có thể không có nghĩa là bạn nên làm điều gì đó như thế này. Có nhiều lựa chọn thay thế tốt hơn gần như giống hệt nhau về chức năng.
Thomas Eding

4
@ sg3s: bạn có thể đề xuất giải pháp khác không?
Tom,

2
@ sg3s: Cảm ơn đã trả lời bình luận của tôi! Hãy để tôi giải thích ý tôi và điều tôi thực sự muốn hỏi: giải pháp của Marcosc có thực sự khác biệt đáng kể so với eval không? Nó có thực sự tạo ra sự khác biệt nếu bạn đánh giá một thứ gì đó hoặc đưa nó vào hàm tạo Hàm? Nếu vậy, bạn có thể giải thích sự khác biệt và phân nhánh của nó? Cảm ơn!
Tom,

5
@Tom Đối với độc giả trong tương lai: giải pháp này không thực sự khác với câu trả lời của Marcosc, cả hai đều sử dụng eval()(hàm Functiontạo thực hiện điều đó bên trong).
kapa

126

Về cơ bản, điều này sẽ thực hiện ở cấp độ đơn giản nhất:

"use strict";
var name = "foo";
var func = new Function(
     "return function " + name + "(){ alert('sweet!')}"
)();

//call it, to test it
func();

Nếu bạn muốn lạ mắt hơn, tôi có một bài viết về " Tên hàm động trong JavaScript ".


Công việc tốt đẹp! Tôi vừa mới phát hiện ra điều này một mình và định đăng nó lên một trong những câu hỏi này, nhưng bạn đã đánh bại tôi. Gần đây, tôi đã làm việc rất nhiều với backbone.js và cảm thấy mệt mỏi khi thấy 'con' ở khắp mọi nơi trong trình gỡ lỗi chrome của mình. Điều này giải quyết vấn đề đó. Tôi tự hỏi nếu có bất kỳ tác động hiệu suất nào như sử dụng eval.
webXL

Cũng có những tác động bảo mật. Tôi nhận được "Hàm tạo hàm là eval" từ jsHint, vì vậy tôi đang gói nó trong một kiểm tra chế độ gỡ lỗi, vì đó là lý do duy nhất để sử dụng điều này. Tôi đoán "sử dụng nghiêm ngặt" sẽ ngăn chặn bất kỳ liên kết nào với đối tượng toàn cục, nhưng bất kỳ đối số nào đối với hàm tạo Hàm đều có thể được sửa đổi và bất cứ điều gì 'this' được đặt thành.
webXL

Có, điều này cho những tình huống khắc nghiệt mà bạn cần phải xây dựng một cái gì đó đang bay.
Marcosc

1
Tôi thành thật nghĩ rằng stackoverflow.com/a/40918734/2911851 là một giải pháp tốt hơn, không cần phải bao gồm phần thân của hàm dưới dạng một chuỗi (trừ khi tôi thiếu thứ gì đó, nhưng tôi đã thử và hoạt động tốt).
Gian Franco Zabarino

2
AirBnB đặc biệt khuyên bạn nên chống lại điều này , vì hàm tạo Hàm sẽ sử dụng evalđể đánh giá javascript - do đó mở mã của bạn cho một loạt các lỗ hổng.
Philippe Hebert

42

Bạn có thể sử dụng Object.defineProperty như được lưu ý trong Tài liệu tham khảo JavaScript MDN [1]:

var myName = "myName";
var f = function () { return true; };
Object.defineProperty(f, 'name', {value: myName, writable: false});
  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Description

2
Có vẻ như điều này sẽ đặt thuộc tính tên như dự định, nhưng nếu tôi đăng nhập hàm trong trình duyệt của mình (phiên bản dành cho nhà phát triển Firefox mới nhất), nó sẽ in ra function fn(), fnlà tên gốc. Kỳ dị.
Kiara Grouwstra

cùng nhận xét trên google chrome evergreen. Thuộc tính được đặt đúng, nhưng tên trong bảng điều khiển, là tên ban đầu của hàm. Cf 2ality.com/2015/09/… Có vẻ như tên của hàm được gán lúc tạo và không thể thay đổi?
user3743222 Ngày

Trên trang 2ality.com đó, hãy xem đoạn tiếp theo "Thay đổi tên của các hàm" [1] mô tả kỹ thuật tương tự được tìm thấy trong Tham chiếu Javascript MDN. 1. 2ality.com/2015/09/…
Darren

35

Trong các công cụ gần đây, bạn có thể làm

function nameFunction(name, body) {
  return {[name](...args) {return body(...args)}}[name]
}



const x = nameFunction("wonderful function", (p) => p*2)
console.log(x(9)) // => 18
console.log(x.name) // => "wonderful function"


1
Sau hàng giờ đồng hồ cố gắng tìm ra giải pháp, tôi thậm chí còn không nghĩ đến việc sử dụng một đối tượng có tên thuộc tính được tính toán. Chính xác những gì tôi cần. Cảm ơn!
Levi Roberts

7
Trong khi điều này hoạt động hiệu quả, tôi đã bắt đầu sử dụng Object.defineProperty(func, 'name', {value: name})mã của riêng mình, vì tôi nghĩ nó có thể tự nhiên và dễ hiểu hơn một chút.
kybernetikos

nó hoạt động với mã chuyển vị? (Kết quả đầu ra Babel hoặc
typecript

3
Trả lời câu hỏi của riêng tôi: {[expr]: val}là bộ khởi tạo đối tượng (đối tượng JSON) ở đâu exprlà một số biểu thức; bất cứ điều gì nó đánh giá là chìa khóa. {myFn (..){..} }là viết tắt của {myFn: function myFn(..){..} }. Lưu ý rằng function myFn(..) {..}có thể được sử dụng như một biểu thức giống như một hàm ẩn danh, myFnsẽ chỉ có tên. Cuối cùng [name]chỉ là truy cập thành viên của đối tượng (giống như obj.keyhoặc obj['key']). ...là toán tử spread. (Nguồn chính: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Jason Young

1
Cảm ơn vì sự chú ý của bạn! Lưu ý: Điều này không bảo toàn giá trị của this. Ví dụ obj={x:7,getX(){return this.x}}; obj.getX=nameFunction('name',obj.getX); obj.getX();sẽ không hoạt động. Bạn có thể chỉnh sửa câu trả lời của mình và sử dụng function nameFunction(name, body) { return {[name](...args) {return body.apply(this, args)}}[name] }thay thế!
TS

11

Tôi nghĩ rằng hầu hết các đề xuất ở đây là không tối ưu, bằng cách sử dụng đánh giá, giải pháp hacky hoặc trình bao bọc. Kể từ ES2015, tên được suy ra từ vị trí cú pháp cho các biến và thuộc tính.

Vì vậy, điều này sẽ hoạt động tốt:

const name = 'myFn';
const fn = {[name]: function() {}}[name];
fn.name // 'myFn'

Hãy chống lại sự cám dỗ tạo ra các phương thức của nhà máy hàm được đặt tên vì bạn sẽ không thể chuyển hàm từ bên ngoài và trang bị thêm nó vào vị trí cú pháp để suy ra tên của nó. Vậy thì đã quá muộn. Nếu bạn thực sự cần điều đó, bạn phải tạo một trình bao bọc. Ai đó đã làm điều đó ở đây, nhưng giải pháp đó không hoạt động đối với các lớp (cũng là các hàm).

Một câu trả lời chuyên sâu hơn với tất cả các biến thể đã nêu đã được viết tại đây: https://stackoverflow.com/a/9479081/633921


1
Câu trả lời này cải thiện stackoverflow.com/a/41854075/3966682 như thế nào?
d4nyll

1
@ d4nyll Tôi đã trả lời rằng: Nó tạo ra một trình bao bọc, phá vỡ các hàm trạng thái (các hàm sử dụng "this") aka các lớp.
Albin

@Albin FWIW, tôi không rõ ràng câu trả lời của bạn nói lên điều đó như thế nào. Dù bằng cách nào, điều đó là tốt để biết.
Jason Young

@JasonYoung "Hãy chống lại sự cám dỗ để tạo ra các phương thức gốc của hàm được đặt tên vì bạn sẽ không thể chuyển hàm từ bên ngoài và trang bị thêm nó vào vị trí cú pháp để suy ra tên của nó. Vậy thì đã quá muộn rồi. Nếu bạn thực sự cần nó, bạn phải tạo một trình bao bọc. Ai đó đã làm điều đó ở đây, nhưng giải pháp đó không hoạt động đối với các lớp (cũng là các hàm). "
Albin

3

Thế còn

this.f = window["instance:" + a] = function(){};

Hạn chế duy nhất là hàm trong phương thức toSource của nó sẽ không chỉ ra tên. Đó thường chỉ là một vấn đề đối với trình gỡ lỗi.


điều đó không tốt vì lý do duy nhất tôi cần là xem nhanh hơn tên của các Lớp. Mỗi lớp học trong hệ thống của tôi là một chức năng ẩn danh và trong các chương trình gỡ lỗi tôi vô danh ..
Totty.js

1
Vậy thì bạn có thể đã nói điều đó trong câu hỏi.
entonio

3

Cú pháp function[i](){}ngụ ý một đối tượng có các giá trị thuộc tính là các hàm function[], được lập chỉ mục bởi tên [i],.
Như vậy
{"f:1":function(){}, "f:2":function(){}, "f:A":function(){}, ... } ["f:"+i].

{"f:1":function f1(){}, "f:2":function f2(){}, "f:A":function fA(){}} ["f:"+i]sẽ duy trì nhận dạng tên hàm. Xem ghi chú bên dưới về :.

Vì thế,

javascript: alert(
  new function(a){
    this.f={"instance:1":function(){}, "instance:A":function(){}} ["instance:"+a]
  }("A") . toSource()
);

hiển thị ({f:(function () {})})trong FireFox.
(Đây gần giống ý tưởng với giải pháp này , chỉ khác là nó sử dụng một đối tượng chung và không còn điền trực tiếp vào đối tượng cửa sổ với các chức năng.)

Phương thức này điền rõ ràng môi trường với instance:x.

javascript: alert(
  new function(a){
    this.f=eval("instance:"+a+"="+function(){})
  }("A") . toSource()
);
alert(eval("instance:A"));

màn hình

({f:(function () {})})

function () {
}

Mặc dù hàm thuộc tính ftham chiếu đến một anonymous functionvà không instance:x, phương pháp này tránh một số vấn đề với giải pháp này .

javascript: alert(
  new function(a){
    eval("this.f=function instance"+a+"(){}")
  }("A") . toSource()
);
alert(instanceA);    /* is undefined outside the object context */

chỉ hiển thị

({f:(function instanceA() {})})
  • Việc nhúng :làm cho javascript function instance:a(){}không hợp lệ.
  • Thay vì tham chiếu, định nghĩa văn bản thực tế của hàm được phân tích cú pháp và diễn giải bởi eval.

Những điều sau đây không nhất thiết phải có vấn đề,

  • Các instanceAchức năng không phải là trực tiếp có sẵn để sử dụng nhưinstanceA()

và do đó phù hợp hơn nhiều với bối cảnh vấn đề ban đầu.

Với những cân nhắc này,

this.f = {"instance:1": function instance1(){},
          "instance:2": function instance2(){},
          "instance:A": function instanceA(){},
          "instance:Z": function instanceZ(){}
         } [ "instance:" + a ]

duy trì môi trường điện toán toàn cầu với ngữ nghĩa và cú pháp của ví dụ OP càng nhiều càng tốt.


Độ phân giải này chỉ hoạt động đối với tên tĩnh hoặc tên thuộc tính động ES6. Ví dụ (name => ({[name]:function(){}})[name])('test')hoạt động nhưng (name => {var x={}; x[name] = function(){}; return x[name];})('test')không
William Leung

3

Câu trả lời được bình chọn nhiều nhất đã có thân hàm [Chuỗi] được xác định. Tôi đang tìm giải pháp để đổi tên tên của hàm đã được khai báo và cuối cùng sau một giờ vật lộn, tôi đã xử lý được nó. Nó:

  • lấy hàm đã khai báo alredy
  • phân tích cú pháp nó thành [String] bằng .toString()phương thức
  • sau đó ghi đè tên (của chức năng đã đặt tên) hoặc nối tên mới (khi ẩn danh) giữa function(
  • sau đó tạo một hàm mới được đổi tên với hàm new Function()tạo

function nameAppender(name,fun){
  const reg = /^(function)(?:\s*|\s+([A-Za-z0-9_$]+)\s*)(\()/;
  return (new Function(`return ${fun.toString().replace(reg,`$1 ${name}$3`)}`))();
}

//WORK FOR ALREADY NAMED FUNCTIONS:
function hello(name){
  console.log('hello ' + name);
}

//rename the 'hello' function
var greeting = nameAppender('Greeting', hello); 

console.log(greeting); //function Greeting(name){...}


//WORK FOR ANONYMOUS FUNCTIONS:
//give the name for the anonymous function
var count = nameAppender('Count',function(x,y){ 
  this.x = x;
  this.y = y;
  this.area = x*y;
}); 

console.log(count); //function Count(x,y){...}


2

Các phương thức động của một đối tượng có thể được tạo bằng Object Literal Extensions do ECMAScript 2015 (ES6) cung cấp:

const postfixes = ['foo', 'bar'];

const mainObj = {};

const makeDynamic = (postfix) => {
  const newMethodName = 'instance: ' + postfix;
  const tempObj = {
    [newMethodName]() {
      console.log(`called method ${newMethodName}`);
    }
  }
  Object.assign(mainObj, tempObj);
  return mainObj[newMethodName]();
}

const processPostfixes = (postfixes) => { 
  for (const postfix of postfixes) {
    makeDynamic(postfix); 
  }
};

processPostfixes(postfixes);

console.log(mainObj);

Kết quả của việc chạy đoạn mã trên là:

"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}

điều này giống với: o={}; o[name]=(()=>{})hơn làfunction <<name>>(){}
Sancarn 15/09/18

2

Để đặt tên của một hàm ẩn danh hiện có :
(Dựa trên câu trả lời của @ Marcosc)

var anonymous = function() { return true; }

var name = 'someName';
var strFn = anonymous.toString().replace('function ', 'return function ' + name);
var fn = new Function(strFn)();

console.log(fn()); // —> true

Bản trình diễn .

Lưu ý : Đừng làm điều đó; /


Khi bạn phản đối thì không sao. Nhưng bạn nên lịch sự suy luận của mình để chúng tôi có thể học hỏi từ bạn. OP hỏi tên hàm "động". Đây là một cách để làm điều đó, nhưng tôi không bao giờ khuyên bạn nên cũng như tôi chưa bao giờ làm điều đó.
Onur Yıldırım

1

Có hai phương pháp để đạt được điều này, và chúng có những ưu và khuyết điểm.


name định nghĩa tài sản

Định nghĩa thuộc name tính bất biến của một hàm.

Ưu điểm

  • Mỗi ký tự đều có sẵn cho tên. (ví dụ. () 全 {}/1/얏호/ :D #GO(@*#%! /*)

Nhược điểm

  • Tên cú pháp (“expressional”) của hàm có thể không tương ứng với namegiá trị thuộc tính của nó .

Đánh giá biểu thức hàm

Tạo một biểu thức hàm được đặt tênđánh giá nó bằng hàm tạo.Function

Ưu điểm

  • Tên cú pháp (“expressional”) của hàm luôn tương ứng với namegiá trị thuộc tính của nó .

Nhược điểm

  • Khoảng trắng (và v.v.) không có sẵn cho tên.
  • Biểu thức có thể tiêm (ví dụ: Đối với đầu vào (){}/1//, biểu thức là return function (){}/1//() {}, cho NaNthay vì một hàm.).

const demoeval = expr => (new Function(`return ${expr}`))();

// `name` property definition
const method1 = func_name => {
    const anon_func = function() {};
    Object.defineProperty(anon_func, "name", {value: func_name, writable: false});
    return anon_func;
};

const test11 = method1("DEF_PROP"); // No whitespace
console.log("DEF_PROP?", test11.name); // "DEF_PROP"
console.log("DEF_PROP?", demoeval(test11.toString()).name); // ""

const test12 = method1("DEF PROP"); // Whitespace
console.log("DEF PROP?", test12.name); // "DEF PROP"
console.log("DEF PROP?", demoeval(test12.toString()).name); // ""

// Function expression evaluation
const method2 = func_name => demoeval(`function ${func_name}() {}`);

const test21 = method2("EVAL_EXPR"); // No whitespace
console.log("EVAL_EXPR?", test21.name); // "EVAL_EXPR"
console.log("EVAL_EXPR?", demoeval(test21.toString()).name); // "EVAL_EXPR"

const test22 = method2("EVAL EXPR"); // Uncaught SyntaxError: Unexpected identifier

1

Nếu bạn muốn có một hàm động giống như __callhàm trong PHP, bạn có thể sử dụng Proxy.

const target = {};

const handler = {
  get: function (target, name) {
    return (myArg) => {
      return new Promise(resolve => setTimeout(() => resolve('some' + myArg), 600))
    }
  }
};

const proxy = new Proxy(target, handler);

(async function() {
  const result = await proxy.foo('string')
  console.log('result', result) // 'result somestring' after 600 ms
})()

1

Bạn có thể sử dụng Tên hàm động và các tham số như thế này.

1) Xác định chức năng Tách biệt và gọi nó

let functionName = "testFunction";
let param = {"param1":1 , "param2":2};

var func = new Function(
   "return " + functionName 
)();

func(param);

function testFunction(params){
   alert(params.param1);
}

2) Xác định mã chức năng động

let functionName = "testFunction(params)";
let param = {"param1":"1" , "param2":"2"};
let functionBody = "{ alert(params.param1)}";

var func = new Function(
    "return function " + functionName + functionBody 
)();

func(param);

0

Cảm ơn bạn Marcosc! Dựa trên câu trả lời của anh ấy, nếu bạn muốn đổi tên bất kỳ hàm nào , hãy sử dụng:

// returns the function named with the passed name
function namedFunction(name, fn) {
    return new Function('fn',
        "return function " + name + "(){ return fn.apply(this,arguments)}"
    )(fn)
}

0

Chức năng tiện ích này hợp nhất nhiều chức năng thành một (sử dụng tên tùy chỉnh), chỉ yêu cầu là các chức năng được cung cấp phải được "xếp hàng mới" đúng cách ở đầu và cuối của tin sốt dẻo.

const createFn = function(name, functions, strict=false) {

    var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];

    for(var i=0, j=functions.length; i<j; i++) {
        var str = functions[i].toString();
        var s = str.indexOf(cr) + 1;
        a.push(str.substr(s, str.lastIndexOf(cr) - s));
    }
    if(strict == true) {
        a.unshift('\"use strict\";' + cr)
    }
    return new Function(a.join(cr) + cr + '}')();
}

// test
var a = function(p) {
    console.log("this is from a");
}
var b = function(p) {
    console.log("this is from b");
}
var c = function(p) {
    console.log("p == " + p);
}

var abc = createFn('aGreatName', [a,b,c])

console.log(abc) // output: function aGreatName()

abc(123)

// output
this is from a
this is from b
p == 123

0

Tôi đã may mắn hơn khi kết hợp câu trả lời của Darrencâu trả lời của kyernetikos .

const nameFunction = function (fn, name) {
  return Object.defineProperty(fn, 'name', {value: name, configurable: true});
};

/* __________________________________________________________________________ */

let myFunc = function oldName () {};

console.log(myFunc.name); // oldName

myFunc = nameFunction(myFunc, 'newName');

console.log(myFunc.name); // newName

Lưu ý: configurableđược đặt để truephù hợp với thông số tiêu chuẩn của ES2015 cho Function.name 1

Điều này đặc biệt giúp khắc phục lỗi trong Webpack tương tự như lỗi này .

Cập nhật: Tôi đã nghĩ đến việc xuất bản này dưới dạng gói npm , nhưng gói này từ sindresorhus thực hiện chính xác điều tương tự.

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

0

Tôi đã đấu tranh rất nhiều với vấn đề này. Giải pháp @Albin hoạt động như một sự quyến rũ trong khi phát triển, nhưng nó không hoạt động khi tôi thay đổi nó thành sản xuất. Sau một số lần gỡ lỗi, tôi nhận ra cách đạt được những gì tôi cần. Tôi đang sử dụng ES6 với CRA (create-react-app), có nghĩa là nó được bao gồm bởi Webpack.

Giả sử bạn có một tệp xuất các chức năng bạn cần:

myFunctions.js

export function setItem(params) {
  // ...
}

export function setUser(params) {
  // ...
}

export function setPost(params) {
  // ...
}

export function setReply(params) {
  // ...
}

Và bạn cần gọi động các hàm này ở nơi khác:

myApiCalls.js

import * as myFunctions from 'path_to/myFunctions';
/* note that myFunctions is imported as an array,
 * which means its elements can be easily accessed
 * using an index. You can console.log(myFunctions).
 */

function accessMyFunctions(res) {
  // lets say it receives an API response
  if (res.status === 200 && res.data) {
    const { data } = res;
    // I want to read all properties in data object and 
    // call a function based on properties names.
    for (const key in data) {
      if (data.hasOwnProperty(key)) {
        // you can skip some properties that are usually embedded in
        // a normal response
        if (key !== 'success' && key !== 'msg') {
          // I'm using a function to capitalize the key, which is
          // used to dynamically create the function's name I need.
          // Note that it does not create the function, it's just a
          // way to access the desired index on myFunctions array.
          const name = `set${capitalizeFirstLetter(key)}`;
          // surround it with try/catch, otherwise all unexpected properties in
          // data object will break your code.
          try {
            // finally, use it.
            myFunctions[name](data[key]);
          } catch (error) {
            console.log(name, 'does not exist');
            console.log(error);
          }
        }
      }
    }
  }
}


0

cách tốt nhất là tạo đối tượng với danh sách các hàm động như:

const USER = 'user';

const userModule = {
  [USER + 'Action'] : function () { ... }, 
  [USER + 'OnClickHandler'] : function () { ... }, 
  [USER + 'OnCreateHook'] : function () { ... }, 
}

-1
function myFunction() {
    console.log('It works!');
}

var name = 'myFunction';

window[name].call();

-2

Tôi có thể thiếu điều hiển nhiên ở đây, nhưng có gì sai khi chỉ thêm tên? các hàm được gọi bất kể tên của chúng. tên chỉ được sử dụng vì lý do xác định phạm vi. nếu bạn gán nó cho một biến và nó nằm trong phạm vi, nó có thể được gọi. hat xảy ra là bạn đang thực thi một biến có thể là một hàm. nếu bạn phải có tên vì lý do nhận dạng khi gỡ lỗi, hãy chèn tên đó vào giữa hàm từ khóa và dấu ngoặc nhọn mở.

var namedFunction = function namedFunction (a,b) {return a+b};

alert(namedFunction(1,2));
alert(namedFunction.name);
alert(namedFunction.toString());

một cách tiếp cận thay thế là bọc hàm trong một miếng đệm được đổi tên bên ngoài, bạn cũng có thể chuyển hàm này vào một lớp bọc bên ngoài, nếu bạn không muốn làm bẩn vùng tên xung quanh. nếu bạn muốn thực sự tạo động hàm từ các chuỗi (mà hầu hết các ví dụ này đều làm), thì việc đổi tên nguồn để thực hiện những gì bạn muốn là rất nhỏ. Tuy nhiên, nếu bạn muốn đổi tên các chức năng hiện có mà không ảnh hưởng đến chức năng của chúng khi được gọi ở nơi khác, thì một miếng đệm là cách duy nhất để đạt được điều đó.

(function(renamedFunction) {

  alert(renamedFunction(1,2));
  alert(renamedFunction.name);
  alert(renamedFunction.toString());
  alert(renamedFunction.apply(this,[1,2]));


})(function renamedFunction(){return namedFunction.apply(this,arguments);});

function namedFunction(a,b){return a+b};


Hàm / method namerất hữu ích vì nó được suy ra từ biến và thuộc tính. Nó cũng được sử dụng trong dấu vết ngăn xếp. Ex var fn = function(){}; console.log(fn.name). Nó là bất biến, vì vậy bạn không thể thay đổi nó sau này. Nếu bạn viết một phương thức gốc đặt tên cho tất cả các hàm fnthì điều này sẽ khiến việc gỡ lỗi trở nên khó khăn hơn.
Albin

-3

Bạn đã ở gần:

this["instance_" + a] = function () {...};

{...};


-9

Đây là giải pháp TỐT NHẤT, tốt hơn hết new Function('return function name(){}')().

Đánh giá là giải pháp nhanh nhất:

nhập mô tả hình ảnh ở đây

var name = 'FuncName'
var func = eval("(function " + name + "(){})")

Ai đang đọc bài này thì hãy follow theo dõi câu trả lời này nhé.
Maxmaxmaximus

1
@majidarif anh chàng nói đúng, nó nhanh nhất: jsperf.com/dynamicariesnames/1 . Mặc dù cho đến nay không phải là an toàn nhất.
Sancarn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.