我正在学习Bind,Call和Apply,我有一个关于Bind的问题,我没有能够找到一个好的回应:
说我有以下代码
var Jim = {
firstName: 'Jim',
lastName: 'Bob',
fullName: function() {
return this.firstName + ' ' + this.lastName;
}
};
var fName = Jim.fullName; //now fName's context is window
//If I invoke fName here, I will get the expected 'undefined undefined'
console.log(fName());
但是,我也可以执行以下操作,并在传递新上下文后立即调用我的绑定方法:
fName.bind(Jim)(); //this returns 'Jim Bob'
我觉得这只是模仿call
或apply
可以(应该?)做什么。如果我在前一行之后再次调用fName()
,它仍然绑定到窗口对象(fName没有通过使用bind来修改)。这是不好的做法吗?
虽然如此:
var Jim = {
//same object definition as above
};
var Chris = {
firstName: 'Chris',
lastName: 'Smith'
};
var fName = Jim.fullName.bind(Jim); //now fName's context is the Jim object
console.log(fName()); //this will log 'Jim Bob' as expected
现在,如果我尝试将绑定方法绑定到另一个上下文,它就不起作用了:
fName.bind(Chris)(); //this still logs 'Jim Bob' from the original context
我相信第二种情况,这是因为我基本上创建了一个"函数绑定绑定",所以它有两个上下文,只是第一个。
对这两种情况有何看法?
答案 0 :(得分:0)
你基本上是全面的。做
var fName = Jim.fullName;
fName.bind(Jim)();
与
完全相同var fName = Jim.fullName;
fName.call(Jim);
我不确定我会把第一个例子称为“坏习惯”,但绝对不是“好习惯”。 call
完全符合您的要求而不会生成新的函数值,并且(在我看来)更好地描述了您的意图。
至于为什么你不能重新绑定一个功能,你非常接近正确。而不是fName
有两个上下文,它仍然只有一个。{1}}。但是bind
明确指出“这是这个功能的背景,对此毫无疑问。”
答案 1 :(得分:0)
您不再像以前那样绑定到同一个fName函数。 bind
返回一个新的绑定函数,其this
值无法被覆盖。
根据MDN docs,
bind()函数创建一个 new function (一个绑定函数),它具有相同的函数体(ECMAScript 5术语中的内部调用属性)作为它被调用的函数(绑定函数& #39; s target function)将此值绑定到bind()的第一个参数,无法覆盖。