在stackoverflow上读取What techniques can be used to define a class in JavaScript, and what are their trade-offs?我知道我可以通过
定义一个类方法1:
function Person(name, gender){
this.name = name;
this.gender = gender;
}
并在原型中添加函数,以避免每次实例化时重新创建成员函数。像
Person.prototype.speak = function(){
alert("my name is" + this.name);
}
并通过
创建其实例var person = new Person("Bob", "M");
我认为使用新的关键字
可以创建相同的对象方法2:
var Person = function (name, gender) {
return {name:name, gender:gender};
}
person = Person("Bob", "M");
第二种方法是否完成了第一种完全相同的操作?如果是这样的话,我将如何在第二种方法中通过原型模拟添加函数(正如我们在方法1中所说的那样)?
答案 0 :(得分:5)
否,方法2!=方法1.第二种方法是创建一个新的匿名对象,其原型指向Object.prototype
,而第一种方法创建一个新对象,其原型指向{{1} }。
在伪代码中:
Person.prototype
答案 1 :(得分:3)
正如Sean Vieira所解释的那样,第一种方法与第二种方法不同。在第一种方法中,实例继承自Person.prototype
。在第二种方法中,实例直接从Object.prototype
继承。
方法1:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| Person.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
方法2:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
有趣的是,上面的图表显示了对象继承自JavaScript中的其他对象,而不是来自构造函数。因此,当您创建new Person
时,实例将继承自Person.prototype
,而非来自Person
本身。
这些相关信息如何?对于初学者来说,它表明您不需要创建构造函数来创建对象的实例。而是直接创建原型对象,如下所示:
var person = {
create: function (name, gender) {
var person = Object.create(this);
person.gender = gender;
person.name = name;
return person;
},
speak: function () {
alert("My name is " + this.name + ".");
}
};
在上面的示例中,person
相当于Person.prototype
。您现在可以创建person
的实例,如下所示:
var bob = person.create("Bob", "M");
bob
的原型链将如下所示:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
^
|
| __proto__
|
+------------------+
| bob |
+------------------+
那么为什么要创建这样的对象呢?
new
来创建实例。这solves lot problems。{/ li>
醇>
有关此模式的详细信息,请阅读"Why Prototypal Inheritance Matters"上的博文。
答案 2 :(得分:0)
您的示例在访问属性方面实现了相同的目标,但它们并不相同,因为第一种方法具有基本的Object
原型。你的第二个问题的答案是:
function Person( name, gender ){
return {
name: name,
gender: gender,
speak: function(){
alert("my name is" + this.name);
}
};
}
这里没有原型。该函数被烘焙到对象文字中。使用文字而不是原型的唯一价值是创建一个闭包,这样你就可以拥有私有变量,例如:
function Person( name, gender ){
return {
speak: function(){
alert("my name is" + name);
}
};
}
答案 3 :(得分:0)
也许这个答案可以解释一下构造函数,继承,私有变量和重写方法:Prototypical inheritance - writing up
其他答案已经解决了你的问题;将对象创建为对象文字{prop:val,method:function(){}}
并使用构造函数创建对象:var MyObject=function(){this.prop=val};MyObject.prototype.method=function(){}
;