2017-07-10 65 views
0

你能解释的区别:约束力,借款方法

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" 
+0

[请不要把问题标题标签(https://stackoverflow.com/help/tagging) – Liam

+0

嘛,E不因为工作' [] .join.bind(obj)'和'[] .join(“+”)'是两个完全独立的数组。 A和B之间的区别在于,你实际上是用'call'调用函数,而在B中你是用绑定的'this'上下文返回函数,并将对象的连接函数设置为新绑定的函数。 – mhodges

+2

你在问几个问题。 – canon

回答

-1

1)是否有A和B

之间的差别是,在注释中A不修改obj

2)是否有B和C

除了一个事实,就是将打印 'A ++ ++乙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 
+0

感谢您的解释和解决方案如何解除绑定方法: **您无法解除绑定**使用javascript的本地绑定方法绑定的绑定函数。 –