绑定、借用方式
Binding, borrowing method
你能解释一下区别吗:
var obj = {
0: "A",
1: "B",
2: "C",
length: 3,
print: function(){ console.log(this) }
};
//A (borrowing method. No changes in obj):
[].join.call(obj, "+"); //-> "A+B+C"
//B:
obj.join = [].join.bind(obj);
obj.join("+"); //-> "A+B+C"
var oj = obj.join;
oj("-"); //-> "A-B-C" (binded to obj)
//C:
obj.j = [].join;
obj.j("++"); //-> "A+B+C"
var j = obj.j;
j("-"); //-> "A-B-C" (it still binded!)
//D:
var join = [].join.bind(obj)
join("+"); //-> "A+B+C"
//E (not working: [] is a new array every time):
[].join.bind(obj);
[].join("+"); //expected: "A+B+C" but I have: ""
//F (Danger!)
Array.prototype.join = [].join.bind(obj);
[].join("+"); //"A+B+C"
请问A和B有区别吗?
B和C有什么区别?
为什么 E 不起作用?
(附加题)请问F后如何解除绑定方法?
Array.prototype.join = [].join.bind(null);
[].join([1,2,3,4],"+"); //-> "ABC"
1)A和B有区别吗
是的,A没有修改评论中提到的obj
。
2) B和C有区别吗
除了会打印 'A++B++C' 之外,是的。 B 是显式绑定的,而 C 不是,这意味着它可能会丢失上下文。尝试以下操作:
var fn = obj.join
var fn2 = obj.j
console.log(fn('+')) // works
console.log(fn2('+')) // error
3) 为什么 E 不起作用?
[].join.bind(obj);
// ^ this is an array instance
// calling `join.bind(obj)` makes no modification to that array instance or any other
[].join("+"); //expected: "A+B+C" but I have: ""
// ^ this is different array instance, unaffected by the above call
4) 能否解释一下F后如何解除绑定的方法?
您无法取消绑定使用 javascript 的本机 bind
方法绑定的绑定函数。您可以编写自己的不可绑定版本,但这不是本机的一部分 API.
这是一个简单的实现:
function bind(fn, context) {
var newFn = function () { return fn.call(context, arguments) }
newFn.unbind = function () { return fn }
return newFn
}
function checkCtx (a) { console.log(this, a) }
checkCtx(1); // Window, 1
bind(checkCtx, {})(1) // {}, 1
bind(checkCtx, {}).unbind()(1) // Window, 1
你能解释一下区别吗:
var obj = {
0: "A",
1: "B",
2: "C",
length: 3,
print: function(){ console.log(this) }
};
//A (borrowing method. No changes in obj):
[].join.call(obj, "+"); //-> "A+B+C"
//B:
obj.join = [].join.bind(obj);
obj.join("+"); //-> "A+B+C"
var oj = obj.join;
oj("-"); //-> "A-B-C" (binded to obj)
//C:
obj.j = [].join;
obj.j("++"); //-> "A+B+C"
var j = obj.j;
j("-"); //-> "A-B-C" (it still binded!)
//D:
var join = [].join.bind(obj)
join("+"); //-> "A+B+C"
//E (not working: [] is a new array every time):
[].join.bind(obj);
[].join("+"); //expected: "A+B+C" but I have: ""
//F (Danger!)
Array.prototype.join = [].join.bind(obj);
[].join("+"); //"A+B+C"
请问A和B有区别吗?
B和C有什么区别?
为什么 E 不起作用?
(附加题)请问F后如何解除绑定方法?
Array.prototype.join = [].join.bind(null);
[].join([1,2,3,4],"+"); //-> "ABC"
1)A和B有区别吗
是的,A没有修改评论中提到的obj
。
2) B和C有区别吗
除了会打印 'A++B++C' 之外,是的。 B 是显式绑定的,而 C 不是,这意味着它可能会丢失上下文。尝试以下操作:
var fn = obj.join
var fn2 = obj.j
console.log(fn('+')) // works
console.log(fn2('+')) // error
3) 为什么 E 不起作用?
[].join.bind(obj);
// ^ this is an array instance
// calling `join.bind(obj)` makes no modification to that array instance or any other
[].join("+"); //expected: "A+B+C" but I have: ""
// ^ this is different array instance, unaffected by the above call
4) 能否解释一下F后如何解除绑定的方法?
您无法取消绑定使用 javascript 的本机 bind
方法绑定的绑定函数。您可以编写自己的不可绑定版本,但这不是本机的一部分 API.
这是一个简单的实现:
function bind(fn, context) {
var newFn = function () { return fn.call(context, arguments) }
newFn.unbind = function () { return fn }
return newFn
}
function checkCtx (a) { console.log(this, a) }
checkCtx(1); // Window, 1
bind(checkCtx, {})(1) // {}, 1
bind(checkCtx, {}).unbind()(1) // Window, 1