Javascript-在构造函数或构造函数中设置属性';什么是原型财产?

Javascript-在构造函数或构造函数中设置属性';什么是原型财产?,javascript,constructor,prototype,Javascript,Constructor,Prototype,所以我听说应该在构造函数的prototype属性中设置方法,这样它就不会有几个不同的实例。但是房产本身呢?哪一种是最佳实践?如果是这样的话,构造函数不应该总是空的吗 function Gadget(name, color) { this.name = name; this.color = color; this.whatAreYou = function(){ return 'I am a ' + this.color + ' ' + this.nam

所以我听说应该在构造函数的prototype属性中设置方法,这样它就不会有几个不同的实例。但是房产本身呢?哪一种是最佳实践?如果是这样的话,构造函数不应该总是空的吗

function Gadget(name, color) {
     this.name = name;
     this.color = color;
     this.whatAreYou = function(){
       return 'I am a ' + this.color + ' ' + this.name;
     }
}
这真的应该是

function Gadget(name,color){}

Gadget.prototype.name = name;
Gadget.prototype.color = color;
Gadget.prototype.whatAreYou = function() {
   return 'I am a ' + this.color + ' ' + this.name;
};

如果在原型上设置该属性,则该属性由所有实例共享。通常不是你想要的。我在博客上写了这个。您通常希望每个小工具都有自己的名称和颜色。使用您建议的代码,您将如何做到这一点

顺便说一下,您建议的代码有未定义的变量(名称、颜色)

通常的方法是在原型上设置方法,在对象本身上设置规则值。除非您确实希望一个属性被所有实例共享,否则这就像我们在静态类型语言中所称的静态属性一样

这里有一个例子

function Gadget(name,color){
    this.name = name;
    this.color = color;
    // Since all gadgets in on the prototype, this is shared by all instances;
    // It would more typically be attached to Gadget.allGadgets instead of the prototype
    this.allGadgets.push(this);
    // Note that the following would create a new array on the object itself
    // not the prototype
    // this.allGadgets = [];

}

Gadget.prototype.allGadgets = [];
Gadget.prototype.whatAreYou = function() {
    return 'I am a ' + this.color + ' ' + this.name;
};
需要记住的一个重要概念是,写入(赋值)始终应用于对象本身,而不是原型。但是,Reads将遍历原型链以查找该属性

就是

function Obj() {
   this.map = {};
}

function SharedObj() {}
SharedObj.prototype.map = {};

var obj1 = new Obj();
var obj2 = new Obj();
var shared1 = new SharedObj();
var shared2 = new SharedObj();

obj1.map.newProp = 5;
obj2.map.newProp = 10;
console.log(obj1.map.newProp, obj2.map.newProp); // 5, 10

// Here you're modifying the same map
shared1.map.newProp = 5;
shared2.map.newProp = 10;
console.log(shared1.map.newProp, shared2.map.newProp); // 10, 10

// Here you're creating a new map and because you've written to the object directly    
// You don't have access to the shared map on the prototype anymore
shared1.map = {};
shared2.map = {};
shared1.map.newProp = 5;
shared1.map.newProp = 10;
console.log(shared1.map.newProp, shared2.map.newProp); // 5, 10

对于属性,其行为可能与您期望的不同。方法应该在原型上声明为,因为您希望所有实例共享相同的函数引用。每个实例的属性通常不同。在处理原语时,您可能不会注意到这一点,但对于对象(或数组…)的属性,您将体验到“奇怪”的行为


注意:放置在原型上的属性可以作为实例值的默认值。Duh..感谢您指出这一点…所以说构造函数应该只为传入的值设置propertied是公平的吗?@Alnitak这很好,只要它不是引用类型(对象、数组),因为它将是sharedWeird behavior->Shared properties。当你明白发生了什么的时候就没那么奇怪了。现在我很困惑…哈哈。因此,您更改了bar的值,它更新了所有实例,因为它是对象引用。但是,这些属性没有改变,因为它们都有自己的属性?我用数组
Test.prototype.bee=[1,2,3]尝试了同样的方法然后
1.bee.push(8)这也只是更新/创建了“一”的bee属性,而不是“二”。所以这只适用于对象,而不适用于数组?@kingkongprog如果您在对象本身而不是原型上创建一个新数组,那么它不会被共享。如果执行
one.bee.push(8)
操作,则仅修改现有阵列。写入(赋值运算符)始终在对象本身上,但读取是通过原型链完成的。
function Test(){}
Test.prototype.foo = {bar: 1};
Test.prototype.baz = 1;

var one = new Test();
var two = new Test();
one.foo.bar = 3;
two.foo.bar === 3; // true, because of object reference
// BUT:
one.baz = 3;
two.baz === 1; // true