Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
原型javascript_Javascript - Fatal编程技术网

原型javascript

原型javascript,javascript,Javascript,无法理解: function Rabbit() { } Rabbit.prototype = { eats: true }; var rabbit = new Rabbit(); Rabbit.prototype = {}; alert(rabbit.eats); //true 及 为什么? 感谢大家的帮助,在“在第一个示例中,您将Rabbit.prototype更改为指向一个全新的、不同的对象。因此,现在Rabbit.prototype和Rabbit。[[Proto]]不再指向同一个对象”(

无法理解:

function Rabbit() { }
Rabbit.prototype = { eats: true };
var rabbit = new Rabbit();
Rabbit.prototype = {};
alert(rabbit.eats); //true

为什么?

感谢大家的帮助,在“在第一个示例中,您将Rabbit.prototype更改为指向一个全新的、不同的对象。因此,现在Rabbit.prototype和Rabbit。[[Proto]]不再指向同一个对象”(c)T.J.Crowder

在第一种情况下,构造的对象仍然与原始prototype对象链接,当然,它仍然具有“吃”的属性


在第二种情况下,您没有引入新的原型,因此更改其“eats”属性的值是通过实例可见的。

因为
rabbit
实例后面的原型是在通过
new rabbit
创建时分配的(来自
rabbit.prototype
),在第一个示例中,您使用一个全新的对象替换
Rabbit.prototype
,这对
Rabbit
实例没有影响。在第二个示例中,您只需修改现有对象,
Rabbit.prototype
Rabbit
后面的原型都指向该对象,因此由于它们指向同一对象,因此无论您遵循哪个引用,您都可以看到更改

让我们浏览一下
var rabbit=new rabbit()(省略一些不相关的细节):

  • 将创建一个新的空白对象

  • 它的底层原型通常称为
    [[Proto]]
    ,设置为
    Rabbit.prototype
    。(我之所以说“通常调用”,是因为规范就是这么称呼它的。你不能直接用这个名字访问它。不过,在支持ES5的环境中,你可以通过找到给定对象的名称。一些JavaScript引擎还通过实际调用的非标准属性[在代码中]
    \uu proto\uu
    使其可用)

  • 该新对象被返回并分配给
    rabbit

  • 现在,我们有两个对象指向原型对象:
    Rabbit.prototype
    ,和
    Rabbit。[[Proto]]

    在第一个示例中,您将
    Rabbit.prototype
    更改为指向一个全新的、不同的对象。所以现在
    Rabbit.prototype
    Rabbit.[Proto]
    不再指向同一个对象

    在第二个示例中,您只需更改共享对象的
    属性的值,这样,无论您遵循哪个对象引用,更改都自然可见

    基本上与此相同:

    var a = {eats: true};
    var b = a;
    a = {eats: false};
    console.log(a.eats); // false
    console.log(b.eats); // true
    

    相当于

    Rabbit.prototype = {};
    Rabbit.prototype.eats = true;
    

    只需将
    Rabbit.prototype.eats
    false
    (从而使先前的赋值无效)


    当js引擎查找属性时,如果在本地找不到它的原型(等等),它会使
    Rabbit.eats
    求值为false。

    ?您期望的是什么?基本上说,虽然prototype在object
    rabbit
    中被分配给了
    .prototype
    ,但对象实际上从
    [[proto]]
    中获取了它的属性?那么
    .prototype
    有什么意义呢?@freakish:
    Rabbit.prototype
    只是
    Rabbit
    函数对象的一个属性。它没有什么特别之处,只是
    newrabbit
    表达式使用了该属性。在
    Rabbit.prototype
    Rabbit
    上的
    [[Proto]]]
    属性之间根本没有持久的联系。他们只是碰巧(最初)指向同一个物体。哦,对不起,这让我有点困惑。现在一切都清楚了,谢谢。:)@古怪的:为了你和其他一群人。:-)我认为是函数对象上的属性名起了作用(几年前,这让我最初感到困惑)。如果他们把它称为
    原型来分配新对象
    或者类似的愚蠢行为,那么它可能会更清晰。但更笨重。:-)
    var a = {eats: true};
    var b = a;
    a.eats = false;
    console.log(a.eats); // false
    console.log(b.eats); // false
    
    Rabbit.prototype = { eats: true };
    
    Rabbit.prototype = {};
    Rabbit.prototype.eats = true;
    
    Rabbit.prototype.eats = false;