Javascript函数# 39;原型在对象之间共享

Javascript functions' prototype is shared between objects??

本文关键字:对象 之间 共享 原型 函数 Javascript      更新时间:2023-09-26

我找到的所有资源都说,如果我们使用Javascript原型模式,该函数的原型在该特定类型的所有对象之间共享。这意味着:

function TestObj(){
}
TestObj.prototype = {
    cVar: 15,
    increase: function(){
        this.cVar++;
    }
};
var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar); // 16
console.log(b.cVar); // 15 ??

现在我的问题是,b.cVar不应该是16吗?那为什么是15呢?如果它是15,这意味着带有prototype的TestObj不被对象共享。

你知道吗??

是的,对象的原型在对象的实例之间是共享的,但是this.cVar++看起来有点误导。

我想如果你重写的话会更容易解释

this.cVar++;

this.cVar = this.cVar + 1;

重要的是this指的是对象实例而不是原型。所以在this.cVar + 1中,它将检查对象实例,看看它是否具有cVar属性。第一次调用increase时,它没有。因此JavaScript将查找原型链,直到找到它为止。它找到了15。然而,当它实际赋值回this.cVar时,它在对象实例本身而不是原型上设置属性(各种各样的阴影)。

在你的例子中,

console.log(a.cVar); // returns property from `a` itself
console.log(b.cVar); // returns property from the prototype

我们可以通过使用hasOwnProperty:

来显示
console.log( a.hasOwnProperty( "cVar" ) ); // true
console.log( b.hasOwnProperty( "cVar" ) ); // false

事实上,正如你的研究让你相信的那样,对象确实彼此共享原型。然而,正如go-oleg所回避的那样,有一个原型链的概念。原型链有一些你必须理解的行为。

当您尝试访问对象上的属性时,它会从对象开始递归地查找链并查找属性,然后返回值(这是在read/get操作的情况下发生的情况)。

当您尝试在对象上设置属性的值时,它不需要在链中递归查找该属性。相反,如果它在对象上找不到属性,它只会添加属性以及你在对象本身上设置的值。这有效地隐藏了原型链上更高的属性(这就是在写/设置操作的情况下发生的情况)。

如果你把你的值放在一个对象中,然后试图设置这个值,但是,它会在读尝试中递归到对象引用,因为你有一个指向对象的引用指针,你会直接在对象上设置值,这会得到你期望的结果:

function TestObj(){
}
TestObj.prototype = {
    cVar: 15,
    obj: { val: 5 },
    increase: function(){
        this.cVar++;
    },
    objInc: function() { 
        this.obj.val++;
    }
};
var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar);
console.log(b.cVar);
b.objInc();
console.log(a.obj.val);
console.log(b.obj.val);
//output
//16
//15
//6
//6

要清楚,"a"是一个对象,"b"是另一个单独的对象。然后只在"a"上调用增加函数,而不是在"b"上调用。所以,除非我疯了,b.cVar = 15是有意义的,因为它从来没有增加过。

你对术语感到困惑,TestObject a是唯一一个你称之为increase()TestObject。所以a = 16b = 16是有意义的,因为你从来没有调用过b.increase()

…该函数的原型在该特定类型的所有对象之间共享。

这并不意味着每次任何TestObject调用increase()时,每个其他TestObject和自身也会增加它们的cVar。您的想法类似于EventListenerEventDispatcher系统的设置方式。该函数的原型在该特定类型的所有对象之间共享意味着每个TestObject实例都具有您定义的原型。