原型中值类型的javascript属性

时间:2014-02-26 13:19:20

标签: javascript prototype value-type

我的理解是所有相同类型的对象将共享相同的原型。因此,改变原型将反映每个对象。但似乎并非属于价值类型的财产。这种财产是如何存储的?

function Person() {        
}

Person.prototype.name = "John";
var p1 = new Person();
p1.name = "Luke";
var p2 = new Person();
p2.name = "Mary";

console.log(p1.name);  // Luke instead of Mary
console.log(p2.name);  // Mary 

如果我想实现相同类型的对象计数。最好的方法是什么?在其他OO语言中,通常只使用静态成员来执行此操作。

enter image description here

2 个答案:

答案 0 :(得分:2)

原型属性访问是非对称

  • 当你获得一个属性时 - 如果对象没有它,它将从原型中获取它。这是specified
  
      
  1. 让proto成为O的[[Prototype]]内部属性的值。
  2.   
  3. 如果proto为null,则返回undefined。
  4.   
  5. 返回用参数P调用proto的[[GetProperty]]内部方法的结果。
  6.   
  • 设置属性时,始终将其设置在对象上而不是原型上。按照规定here

要说错话:

 var proto = {x:4};
 var child = Object.create(proto); // create object with prototype set to `proto`
 child.x; // 4, fetched from prototype
 child.x = 10;
 child.x; // 10, fetched from child
 proto.x; // 4, setting on child did not change the prototype
 Object.getPrototypeOf(child).x = 6; // you can get around it, and set on the proto.

您可以在Steve Yegge's excellent "the universal design pattern"中了解有关它的更多信息,以及它为何如此工作。

答案 1 :(得分:0)

当您尝试检索属性时,将询问该对象以查看它是否具有自己定义的属性。如果没有,则检查其构造函数的原型。这种情况一直发生在原型链上,直到找到一个值。

prototype chain explanation

这是一个例子。

// Person constructor.
var Person = function (name) {
    if (name) {
        this.name = name;
    }
};

// method to print the name in the console
Person.prototype.sayName = function () {
    console.log(this.name);
}

// create two people with names
var person1 = new Person('Nicholas');
var person2 = new Person('Greg');

person1.sayName();
person2.sayName();

// =========================================
// This dude has no name.
var person3 = new Person();
person3.sayName();

// Add a name to the prototype.
// This name is available to all Person instances if they
// don't define their own.
Person.prototype.name = 'Dick';

// These two have their own names.
person1.sayName();
person2.sayName();  

// This guy doesn't have his own name, so he
// uses the one from the prototype.
person3.sayName();