关于bind方法的polyfill问题

MDN的代码段,

    // 维护原型关系
    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    fBound.prototype = new fNOP();
  

我很疑惑:

问题1:此处为什么要判断 if (this.prototype) { 而不是直接指定 fNOP.prototype = this.prototype;?
我观察发现,Function.prototype也是个函数(有这个函数才有的Function 这个构造方法),也有bind方法,但没有prototype,所以要加判断,其实不加也没毛病;

问题2:为什么此处要多一个 fNOP 作为中转函数?

答案: 本来bound.prototype = self.prototype
就可以将原属性集成过来了,但是这样两个对象属性都指向同一个地方,修改 bound.prototype 将会造成self.prototype 也发生改变,这样并不是我们的本意。所以通过一个空函数 nop 做中转,能有效的防止这种情况的发生。

比如见如下代码段:


Function.prototype.bind = function (oThis) {
    if (typeof this !== 'function') {
        // closest thing possible to the ECMAScript 5
        // internal IsCallable function
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fBound = function () {
            console.log("21:53", fBound, this, this instanceof fBound);
            return fToBind.apply(this instanceof fBound
                ? this
                : oThis,
                // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
                aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fBound.prototype = this.prototype; //直接赋值prototype

    return fBound;
};




function Foo() {
    this.name = 'Lily';
}
Foo.prototype = { age: 90 };

var fn = Foo.bind({}, 123);

var p1 = new fn();
console.log(p1.age); // 90

fn.prototype.age = 70; // 不小心更改了 生成的函数的原型,导致原来的函数的原型也被修改
console.log(p1.age); // 70


var fn1 = Foo.bind({}, 1234);
var p2= new fn1();
console.log(p2.age); // 70   原型链被修改了  被影响了 这不是我期望的结果

如上,如果没有fNOP为中介,有人更改了生成的函数的原型,会导致原来的函数的原型也被修改。所以 需要一个fNOP为中介。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 8,085评论 2 17
  • 1、构造函数模式 [url=]file:///C:/Users/i037145/AppData/Local/Tem...
    横冲直撞666阅读 916评论 0 0
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,290评论 1 10
  • 继承6种套餐 参照红皮书,JS继承一共6种 1.原型链继承 核心思想:子类的原型指向父类的一个实例 Son.pro...
    灯不梨喵阅读 3,250评论 1 2
  • 关于男女,关于感情,关于,出轨。 我也不知道怎么了,现在看到的和书中之前说的不一样,执子之手与子偕老,白头到老,同...
    白桦树木阅读 701评论 0 2

友情链接更多精彩内容