原型属性如何在内存中工作?

时间:2014-08-16 00:22:02

标签: javascript

如果在所有实例之间共享原型,那么原型属性如何工作?

function Foo() { 

}

Foo.prototype.property = 1;

var a = new Foo();
var b = new Foo();

a.property = 50;

console.log(b.property) // why this line shows 1?

如果没有共享,那么原型属性和内存中的构造函数属性有什么区别?

function Foo() { 

}

Foo.prototype.property = 1;

vs

function Foo() {
     this.property = 1;
}    

其他疑问:

  • 这两种不同的方式如何在记忆中起作用?
  • 哪一个使用更多内存?为什么?
  • 当我在原型中创建一个方法时,我觉得它在所有实例之间共享是有道理的,我想我只会在内存中加载一个方法,但我无法理解属性是如何工作的。

3 个答案:

答案 0 :(得分:3)

function Foo() { 

}

// Hey, everybody, if anyone asks you about 'property'
// unless you have your own, use this one.
Foo.prototype.property = 1;

var a = new Foo();
var b = new Foo();

// Hey, you! You're special. You get your own property.
// This one covers the shared one.
a.property = 50;

// Hey you, B! You're using the shared one.
console.log(b.property) // why this line shows 1?

这是'原型'之间的基本区别。和当地的财产。

如果,在一个物体上,你要求一个物品不具有的物品,它就会跑到它的父母身边并问“嘿!”我可以用你的吗?"这就是他们回到根对象。

为了让真正的乐趣,以及让你的同事讨厌你的确定方法,请设置:

Object.prototype.something = true;

我随处都可以打破各种各样的东西。


// Everyone share this copy of property
function Foo() { 

}

Foo.prototype.property = 1;


// Hey everybody! You get your OWN copy of property! Ain't you special.
function Foo() {
     this.property = 1;
}    

答案 1 :(得分:1)

原型和构造函数之间的区别可以通过在创建对象后修改它们来显示:

var a = new Foo();
var b = new Foo();

Foo.prototype.property = 50;
console.log(b.property); // This will show 50

如果将赋值放在构造函数中,则更改它不会影响已创建的对象。

在内存中,原型是由它构建的所有对象共享的对象。因此,不是每个对象都有自己的property副本,它们都引用一个原型对象;这使用更少的内存。如果引用对象中的属性,它首先检查它是否具有该名称的属性。如果没有,它会通过原型链,寻找财产。

在这方面,方法和其他属性之间没有区别。方法只是一个属性,其值恰好是一个函数。只是在类的所有实例之间共享方法比共享值更常见。但是,原型属性是为每个实例提供该属性的默认值的有用方法。

答案 2 :(得分:1)

  

如果在所有实例之间共享原型,那么原型属性如何工作?

仅在将属性名称解析为获取属性值时才会访问对象的[[Prototype]]。分配给属性时,仅检查对象本身。

> function Foo() {}
> 
> Foo.prototype.property = 1;
> 
> var a = new Foo(); var b = new Foo();
> 
> a.property = 50;
> 
> console.log(b.property) // why this line shows 1?

该行显示1,因为在执行作业时

a.property = 50;

检查对象 a 是否有名为 property 的属性,由于它没有,所以添加并初始化为50的值。然后当你这样做:

console.log(b.property) // why this line shows 1?

对象 b 没有属性属性,因此检查了[[Prototype]],并在那里找到了值为{{1}的属性},所以返回。

  

如果没有共享,那么原型属性和内存中的构造函数属性有什么区别?

您的术语“构造函数属性”应该是“实例属性”。原型上的属性仅在获取值时访问,然后在设置值时永远不会被访问。

  

这两种不同的方式如何在记忆中起作用?

它们是分开的东西,在一种情况下,你在构造函数的原型上创建了一个属性,在另一种情况下,在对象本身上创建了一个属性。它如何“在内存中工作”取决于浏览器作者,而且无关紧要。

  

哪一个使用更多内存?为什么?

这真的无关紧要。即使存在差异,在事物计划中也会微不足道。

  

当我在原型中创建一个方法时,我觉得它在所有实例之间共享是有道理的,我想我只有一个方法加载到内存中,但我无法理解属性是如何工作的。

“方法”也只是属性。您可以通过读取值来访问它们,就像读取Object或其1链上的任何属性的值一样。但是当您分配给Object属性时,它直接放在对象本身上,不考虑[[Prototype]]链。