简体   繁体   English

原型内的Javascript对象

[英]Javascript Objects Inside Prototype

When learning angularjs I found out that if you put objects in a prototype object , the instances that inherit from that prototype would change the prototype's objects on assigning. 在学习angularjs时,我发现如果将对象放在原型对象中,则从该原型继承的实例将在分配时更改原型的对象。

Example : 范例:

function Person(name) {this.name = name;}
Person.prototype = {species : "homo-sapiens" , characteristics : { "legs" : 2 , "height" : 175}}
var joe = new Person("joe"); 
joe.characteristics.legs = 1 ; 
console.log(Person.prototype.characteristics) //Object {legs: 1, height: 175}

What I showed is that the prototype's instance (joe) changed the object's value on the prototype itself because it inherited an object (characteristics) and not a primitive. 我展示的是原型的实例(joe)更改了对象在原型本身上的值,因为它继承了对象(特征)而不是基元。

My question is as follows : Are prototypes meant most of the time to hold primitives? 我的问题如下:在大多数情况下,原型是否意味着保存基元? (in most cases , you would never want an instance to change the prototype's value. Angular.js actually does so , but it's in the rare case where you actually want a child instance to write to the prototype) . (在大多数情况下,您永远不会希望实例更改原型的值。Angular.js实际上会这样做,但是在极少数情况下,您实际上希望子实例写入原型)。 And what would you do if you actually wanted to put an object on the prototype without the instances writing to the prototype on assigning? 如果您确实想将对象放在原型上而实例没有在分配时写入原型,该怎么办?

This isn't really related to prototype , but just a general JS behavior. 这实际上与prototype无关,而只是一般的JS行为。

The solution would be to copy the object from the prototype in the constructor, 解决方案是从构造函数中的原型复制对象,

function Person() {
    this.characteristics = angular.copy(this.characteristics);
}

Person.prototype = { whatever };

The above assumes angular is available for the angular.copy function. 上面假设angular.copy函数可以使用angular.copy Otherwise you would need to manually do a copy of the object by iterating the properties and copying into a new one. 否则,您将需要通过迭代属性并将其复制到新对象中来手动复制对象。

To get the behavior you're expecting, try this: 要获得您期望的行为,请尝试以下操作:

function Person(name) {
    this.name = name;
    this.species = "homo-sapiens";  
    this.characteristics = { "legs" : 2 , "height" : 175};
}
// NOTE: line below is no longer needed, but I'm keeping it 
// here just so you can see its output for comparison below
Person.prototype = {species : "homo-sapiens", 
                    characteristics : { "legs" : 2 , "height" : 175}}

var joe = new Person("joe"); 

joe.species = "regular old joe"; 
console.log('Person.prototype.species:', Person.prototype.species); 
// Line above prints: Person.prototype.species: homo-sapiens
console.log('joe.species:', joe.species); 
//joe.species: regular old joe

joe.characteristics.legs = 1 ; 
console.log('Person.prototype.characteristics:', Person.prototype.characteristics); 
//Person.prototype.characteristics: Object {legs: 2, height: 175}
console.log('joe.characteristics:', joe.characteristics); 
//joe.characteristics: Object {legs: 1, height: 175} 

To clarify, your question really has nothing to do with angular, it just has to do with javascript's prototype based inheritance and how it works. 需要澄清的是,您的问题确实与angular不相关,仅与javascript基于原型的继承及其工作方式有关。

You may want to checkout this article on prototypical inheritance 您可能想查看这篇关于原型继承的文章

You may also want to check out this SO question on __proto__ vs prototype . 您可能还想__proto__ vs prototype上检查这个SO问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM