对象方法函数:匿名还是命名? [复制]

Posted

技术标签:

【中文标题】对象方法函数:匿名还是命名? [复制]【英文标题】:Object method functions: Anonymous or named? [duplicate] 【发布时间】:2017-04-07 05:41:22 【问题描述】:

我已经看到了这两种类型的代码,我想知道是否有偏好;使用匿名或命名函数:

function myFunc() 
    this.myMethod = () => 
        //..
    


function myFunc() 
    this.myMethod = function() 
        //..
    

取自 MDN:

与函数相比,箭头函数表达式的语法更短 表达式并且不绑定它自己的 this、arguments、super 或 新目标。箭头函数始终是匿名的。这些功能 表达式最适合非方法函数,它们不能 用作构造函数。

匿名对我们来说是有意义的,因为您可能想要访问 myFunc 属性而不必执行_this = this。另一方面,它指出匿名函数最适合非方法函数(即回调)。

【问题讨论】:

你的myMethod 函数都是匿名表达式? ^ 没错,正如 MDN 所说,使用箭头语法可以让您免于将其引用到另一个变量以便以后使用它的麻烦。非箭头函数来自 ES5 语法,所以如果你使用 ES6 总是使用箭头函数,它不会破坏任何东西,但它会帮助你引用 this @Diabolic “如果你使用 ES6 总是使用箭头函数,它不会破坏任何东西” 这是不正确的。如果使用定义的this 值调用回调,则箭头函数将具有this 的“错误”值。 另见:Arrow function vs function declaration / expressions: Are they equivalent / exchangeable? 【参考方案1】:

这些并不矛盾。

使用 anonymous 箭头函数是有意义的,因为您可能想要访问 myFunc 实例属性而不必执行 _this = this

是的。虽然如果它是一个方法,你可以简单地在函数表达式中使用this 并且它会起作用。

另一方面,它指出 匿名函数 函数表达式最适合非方法函数(即回调)。

“非方法”是指不(总是)调用使用设置this 关键字的object.method(…) 模式的函数。函数是否存储作为对象属性并不重要。

顺便说一句,这些点都与命名和匿名表达式无关。

【讨论】:

【参考方案2】:

技术上 - 没关系。

var myFunction = function()   //anonymous

var myFunction = function myFunction()   //named

在所有方面都是相同的,但有一个 - 使用调试工具并查看堆栈跟踪将显示不同的标识符。第一个版本将显示为(anonymous function),而后者将显示为它的名称 - myFunction。因此,命名函数纯粹是为了方便开发人员和开发。

值得注意的是,函数的名称不需要与对它的引用相同,例如你可以有

var myFunction = function someOtherName()  /* ... */ 

然后这将在开发工具中显示为someOtherName。但是,您将 能够通过 someOtherName() 调用它 - 函数的名称和引用是不同的东西。为简单起见,它们通常设置为相同的标识符。

现在,以您的示例为例 - 与您发布的内容有所不同

function myFunc() 
    this.myMethod = () => 
        //..
    

这不等同于命名函数。这是使用 ES6 箭头函数 - 通常,它们将被命名为与分配给它们的变量相同:

var arrowFunction = () => ;

var obj = 
  arrowMethod: () => 


console.log("function name is: " + arrowFunction.name);
console.log("object property function name is: "+ obj.arrowMethod.name);

(请注意,由于某种原因,这在 Chrome 中有效,但在 Firefox 中无效 - 应该设置 .name 属性)

除了命名差异之外,箭头函数与“普通”函数还有其他差异。最值得注意的是,它们的上下文是词法绑定的。这在实践中意味着什么

function arrowExample() 
    this.data = "Hello arrow";
    this.myMethod = () => 
        return this.data;
    


function normalFunctionExample() 
    this.data = "Hello normal function";
    this.myMethod = function myMethod() 
        return this.data;
    


var arrowInstance = new arrowExample();
var normalFunctionExampleInstance = new normalFunctionExample();

console.log("Invoking arrow with context: " + arrowInstance.myMethod());
console.log("Invoking normal function with context: " + normalFunctionExampleInstance.myMethod());

var arrowReference = arrowInstance.myMethod;
var normalFunctionReference = normalFunctionExampleInstance.myMethod;

console.log("Invoking arrow without context: " + arrowReference());
console.log("Invoking normal function without context: " + normalFunctionReference());

【讨论】:

以上是关于对象方法函数:匿名还是命名? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

内置函数及匿名函数

内置函数随笔及匿名函数

性能方面哪个更好:对象原型还是构造函数本机函数? [复制]

使用对象和自执行匿名函数的 jQuery 命名空间

匿名实例化语法 - 好还是坏?

同步函数,还是锁定线程中的对象? [复制]