在后台发生什么,以防止调用更改此对象的绑定方法
What happens under the hood to prevent calling a bound method changing the this object?
请考虑以下代码:
var o1 = { name: 'o1' };
var o2 = {
name: 'o2',
foo: function() { console.log(this.name); }.bind(o1)
}
o2.foo(); // o1 because of the 'bind'
o2.foo.call(o2); // o1 - why?
这是绑定方法的特定功能,其上下文中的 this 对象永远不能被调用或应用覆盖吗?
来自 MDN
bind()
函数创建一个新函数(绑定函数),其中 相同的函数体(ECMAScript 5 术语中的内部调用属性)为 正在调用它的函数(绑定函数的目标 函数),将 this 值绑定到bind()
的第一个参数, 无法覆盖
ECMA 规范 v5.1 的技术版本 - 在第 15.3.4.5 + 15.3.4.5.1 节中定义:
15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
bind
方法采用一个或多个参数,thisArg
和(可选)arg1, arg2, etc
,并通过执行 以下步骤:
- 让"目标"为
this
值。- 如果
IsCallable(Target)
为 false,则引发TypeError
异常。- 让 A 成为所有参数的新(可能是空的)内部列表 在
thisArg
(arg1, arg2 etc
) 之后按顺序提供的值。- 让我们
F
成为一个新的原生 ECMAScript 对象。- 按照指定设置
F
的所有内部方法(除[[Get]]
之外) 在 8.12 中。- 按照 15.3.5.4 中的规定设置
F
的[[Get]]
内部属性。- 将
F
的[[TargetFunction]]
内部属性设置为"目标"。- 将
F
的[[BoundThis]]
内部属性设置为值thisArg
.
...
15.3.4.5.1 [[调用]]
当函数对象的
[[Call]]
内部方法F时,它是 使用bind
函数创建的函数使用 this 值和列表进行调用 的参数 ExtraArgs,采取以下步骤:设 boundArgs 是 F
[[BoundArgs]]
内部属性的值。让 bound这是 F[[BoundThis]]
内部属性的值。让 目标是 F[[TargetFunction]]
内部属性的值。让 args 是一个新列表,其中包含与列表 boundArgs 相同的值 与列表中的 ExtraArgs 相同的顺序后跟相同的值 相同的顺序。返回调用内部[[Call]]
的结果 目标提供绑定的方法此作为此值并提供 参数作为参数。
它受闭包保护,你可以像这样实现同样的事情
Function.prototype.bind = function( obj ) {
var orig_function = this;
return function() {
return orig_function.apply(obj, arguments);
}
}
解释
了解Function.prototype.apply
使用 apply
或 call
可以调用具有特定上下文的函数,请参阅以下示例:
name = 'window';
obj = {name: 'obj'}
fn = function() {
return this.name;
}
fn() // => 'window'
fn.apply(obj) // => 'obj'
fn.call(obj) // => 'obj'
开头的代码返回一个新函数,该函数使用 apply
将上下文绑定到传递的对象。 希望这有帮助
- 从 javascript 中的对象方法返回一个对象
- 在Javascript中调用对象方法时不是函数类型错误
- Java Script将对象方法映射到数组中的对象
- 将数据从promise then方法传递到对象方法
- 设置显示后Flash对象方法不可用:无
- 通过引用Javascript中的另一个函数来传递对象方法
- Javascript库对象方法声明
- JavaScript对象范围-在对象方法中使用对象变量
- jQuery:如何使用文字对象方法中的方法来获取全局变量
- Javascript 对象方法不更新变量
- setInterval 只在对象方法上运行一次
- 对象方法中函数中的上下文
- 用JavaScript编写对象方法的最佳方式是什么
- 使用回调处理程序调用函数内部的父对象方法
- 从Javascript中的对象方法中访问全局变量
- 将此(对象)传递到一个对象方法嵌套方法中
- 为什么我得到“;不是函数错误”;对于我的对象方法
- 带有回调的Javascript对象方法中的递归
- 更正Node.js异步管道中的对象方法调用
- 如何在对象方法上调用requestAnimFrame