function fn(){ console.log(this) };
var fn1 = fn.bind(1);
var instance = new fn1();
console.log(instance.__proto__ === fn.prototype); // 原生的bind应该返回true,而文中bind的栗子返回的是false
var F = function(){};
var B = function(){console.log(this instanceof F);};
new B();//false
B.prototype = new F();//将B原型指向F去,那么new出来的实例 instanceof F,也就true了
new B();//true
发布评论
评论(4)
其主要原因里面也说了,你可能没有想一下真实调用的场景。
bind除了具有绑定this上下文的作用,其还具有类似于函数柯里化,提前绑定一些参数的作用。
如下场景:
如果我们没有你图中的红圈标注的,就会导致上面的代码报错。即使我们传入了一个已经声明好的对象obj进去,那么只会修改obj上的属性,不符合
new构造函数
实例化返回一个新对象的标准。搞了好久细节,终于搞清楚了跟你说说,也在这里做个笔记,不是很会描述,见谅:
首先,先看
bind
文档,经过bind
的方法,如果使用new
的话,会忽略bind
的context
,而是用新生成的实例对象作为this
。其次,再看看
instanceof
的文档,instanceof
返回的结果是:原型链中是否存在一个构造函数的 prototype 属性
。所以,这里用
F
先保存当前的prototype
,然后通过bound.prototype = new F()
让bound
继承this.prototype
里面的属性,而通过new bound()
生成的对象的原形链中就会含有this.prototype
。举个栗子说明继承原形链:最后,由于是通过
bound.prototype = new F()
,所以当使用new
的时候,this instanceof F
会返回true
。那么就会把方法内部的this
绑定成当前的实例,就达到了上面第一条说的效果几个问题:
他的这个栗子其实已经很好地实现了需要,不过吹毛求疵一点,讨论两个问题:
第一个问题:使用
context||this
是否合理?作者的目的是在不使用new
的情况下,没有传入context
时,使用自己的this
代替。这个其实有点多此一举,首先fn.apply(undefined)
也是可以的。而且当对fn
使用严格模式的时候,会出现this
指向window
的问题,应该是undefined
。第二个问题:使用
F
来传递原形的属性,而不是直接通过bound.prototype = this.prototype
,我看原作者说的是为了防止污染this
,但是我没有理解怎么污染this
的。反而会造成下面的问题:最后两句题外话
建议看看他的第二篇
es5-shims
的实现,还是挺有启迪性的。同时,今天我在讨论这个问题的细节的时候,被前辈们教训了,很多东西不需要考虑得过于全面,在写代码的时候,只要满足你的需要就够了,
选择实现我会用的方式,代码最少化
。然而我上面很多分析都有点过了~哈哈~共勉~~说下后面几个圈的知识点
看看代码:
通过整理原型链来做判断最终的bound是new 调用出来还是直接调用。
至于这块,没咋去理解= =
大概是保证new bound出来的实例能顺着原型链一直链到被绑定函数的原型链上,保证原型链一致吧。
其实你不用管那么多,只要是用new实例了一个函数,里面的this就会指向其自身,什么bind的一律失效