问答详情
源自:6-4 [JavaScript]函数属性arguments

对于prototype和new的疑问

我将

fNOP.prototype =  this.prototype;
fBound.prototype = new fNOP();

替换为

fBound.prototype = fNOP.prototype =  this.prototype;

使用 func() 或者 new func()结果都和没有改变,所以我不是太明白这里。

提问者:JFeng 2015-05-30 10:59

个回答

  • Bosn
    2015-06-05 10:34:12

    自問自答好開森哇

  • Nuono
    2017-02-19 05:04:04

    我来补充一下,不知道对不对:

    我纠结的地方主要是为什么要“中转”(fNOP.prototype =  this.prototype;)?

    • 根据知乎有关继承文章里的解释,简单来说:a.prototype = b.prototype 这种方式会导致一方修改值另一方也会跟着改变,不能算是继承,所以需要使用new XXX()的方式继承fBound(func)。

    • 但是因为this没有办法直接使用 a.prototype = new b() 的方式进行继承操作。

    • 所以需要进行“中转”操作,也就是“fNOP.prototype = this.prototype”,中转后就可以使用new XXX()的方式了。

    • 其实在ES5中相当于fBound.prototype = Object.create(this.prototype);,这样在ES5中对于this.prototype就不用“中转”操作了。


  • lmoyrd
    2016-04-19 23:24:01

    个人认为,

    fNOP.prototype = this.prototype;

    fBound.prototype = new fNOP();

    主要为了实现bind后返回的函数对原函数的原型继承。

    例子:

    如果上述代码不加上,那么:

    function foo(b){

    this.c = 100;

    return this.a+b;

    }

    foo.prototype.sayhi = function(){

    alert('hi');

    }

    var func = foo.bind({a:1},20);

    var t1 = func();

    var t = new func({a:10},300);

    alert(func.prototype===foo.prototype);//false

    alert(t.c);

    t.sayhi();//报错,sayhi is not a function

    但是如果加上了就bind后return回来的函数就拥有了foo的原型。

    其实光从这点讲,楼主的代码也可以改为:

    fBound.prototype =  this.prototype;

    然后运行上述代码后,t.sayhi()是执行成功的。这里存在的问题是我改变了func的prototype,foo的prototype也会跟着变,所以不推荐。

    最后说个题外话,在bind函数内部,fBound内部判断this instanceof fNop,个人觉得不清晰(虽然是正确的),改成 this instanceof fBound ,这样才更清晰,因为new函数生成的实例按理说应该指向它的构造函数。

  • JFeng
    2015-06-01 14:52:53

    我明白这里的区别是什么了,方法一会拷贝一个fNOP的prototype给fBound,由于是拷贝所以修改fBound的prototype不会影响到fNOP的prototype。

    其实这两种方法是等价的:

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();


    fBound.prototype = Object.creat(this.prototype);