Javascript函数# 39;原型在对象之间共享
Javascript functions' prototype is shared between objects??
我找到的所有资源都说,如果我们使用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 = 16
和b = 16
是有意义的,因为你从来没有调用过b.increase()
。
…该函数的原型在该特定类型的所有对象之间共享。
这并不意味着每次任何TestObject
调用increase()
时,每个其他TestObject
和自身也会增加它们的cVar
。您的想法类似于EventListener
和EventDispatcher
系统的设置方式。该函数的原型在该特定类型的所有对象之间共享意味着每个TestObject
实例都具有您定义的原型。
- JavaScript中的函数和对象之间没有区别吗?
- 在控制器和数据对象之间同步数据
- 不同对象之间的递归,并将它们唯一地组合在一起,不重复
- 两个对象之间的Javascript原型
- 在window.onload之前/之后创建对象之间的区别
- 如何管理原始对象之间的数据依赖关系
- javascript中构造函数和对象之间的等价性
- 为什么 JSON 中的对象之间有逗号
- 对字符串对象调用 .localeCompare 与构造特制的 Intl.Collator 对象之间的性能差异
- 如何匹配两个对象之间的值并使用特定值创建新对象
- D3 - 在两个不与其他对象相交的对象之间绘制一条线
- 两个时间对象之间的差异
- 函数和对象之间的差异,以及它如何影响性能
- jQuery函数,用于计算两个JavaScript对象之间的差异
- jQuery 自定义事件在全局范围内工作,但在对象之间不起作用
- 以天为单位的 2 个 ember 日期时间对象之间的差异
- 使用原型和对象文字表示法创建对象之间的区别
- HTML/JS Canvas 在对象之间画线
- 在 jQuery 对象和纯 js 对象之间进行转换
- 循环遍历 JSON,在对象之间插入键/值