简体   繁体   English

bind() 与箭头 function + call() 有什么有意义的区别吗?

[英]Is there any meaningful difference bind() vs arrow function + call()?

Given ES6 code like给定 ES6 代码

let a = new SomeClass();
let b = new AnotherClass();

let x = a.someMethod.bind(b, 1, 2, 3);
let y = () => a.someMethod.call(b, 1, 2, 3);

is there any meaningful difference between x and y ? xy之间有什么有意义的区别吗? I know that bind() is a lot older function but is there any need to use it over arrow functions nowadays?我知道bind()是很多旧的 function 但是现在有没有必要在箭头函数上使用它?

At least for me the arrow function syntax is much easier to read than the bind() syntax, especially because you can often avoid using call() in practice when this still has the normal meaning from the lexical context.至少对我来说,箭头 function 语法比bind()语法更容易阅读,特别是因为你通常可以避免在实践中使用call() ,而this仍然具有词汇上下文的正常含义。 For example, will bind() have better performance (CPU or RAM) in practice?例如, bind() ) 在实践中会有更好的性能(CPU 还是 RAM)?

 let a = function(){}; let b = function(){}; am = 1 bm = 2 a.someMethod = function(x, y, z){ return this.m + x + y + z } let x = a.someMethod.bind(b, 1, 2, 3); let y = () => a.someMethod.call(b, 1, 2, 3) console.log( x(1,2,3) ) console.log( y(1,2,3) ) function goBind() { for (var i = 0; i < 1000000; i++) { x(1,2,3) } } function goArrow() { for (var i = 0; i < 1000000; i++) { y(1,2,3) } } function race() { var start = performance.now(); goBind(); console.log('bind: ' + (performance.now() - start)); start = performance.now(); goArrow() console.log('arrow: ' + (performance.now() - start)); start = performance.now(); goBind(); console.log('bind: ' + (performance.now() - start)); start = performance.now(); goArrow() console.log('arrow: ' + (performance.now() - start)); console.log('------'); }
 <button onclick="race()">RACE!</button>

Based on this: Are arrow functions faster (more performant, lighter) than ordinary standalone function declaration in v8?基于此: 箭头函数是否比 v8 中的普通独立 function 声明更快(性能更高、更轻)?

Regardless of the performance, for some use cases, arrow function cannot represent the same logic.不管性能如何,对于某些用例,箭头 function 不能代表相同的逻辑。 For example, when you use Promises you can have something like this ( source for this example ):例如,当你使用 Promises 时,你可以有这样的东西(这个例子的源代码):

function CommentController(articles) {
    this.comments = [];

    articles.getList()
        .then(function (articles) {
            return Promise.all(articles.map(function (article) {
                return article.comments.getList();
            }));
        })
        .then(function (commentLists) {
            return commentLists.reduce(function (a, b) {
                return a.concat(b);
            });
        })
        .then(function (comments) {
            this.comments = comments;
        }.bind(this));
}

Note the difference if the last bind(this) were removed.如果最后一个bind(this)被删除,请注意区别。 There's no simple way to use arrow function notation to change this without modifying the code a lot.没有简单的方法可以使用箭头 function 表示法来更改它而无需大量修改代码。 I personally prefer to use closure with variable name other than this for a code like this, though.不过,对于这样的代码,我个人更喜欢使用带有变量名的闭包而不是this

In addition, bind() can be used for partial application which may be easier to read for people with functional programming background .此外, bind()可以用于部分应用程序,对于具有函数式编程背景的人来说可能更容易阅读。

On the other hand, if a.someMethod is modified later, the version that used bind() will not see the change because it took the reference to the function during the binding.另一方面,如果稍后修改a.someMethod ,使用bind()的版本将不会看到更改,因为它在绑定期间引用了 function。 The variant with lambda function will see current value of a.someMethod when y() is called.调用y()时,带有 lambda function 的变体将看到a.someMethod的当前值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM