[英]adding prototype in class definition in javascript
reading the What techniques can be used to define a class in JavaScript, and what are their trade-offs? 阅读什么技术可以用来在JavaScript中定义类,以及它们的权衡是什么? on stackoverflow i understand that i can define a class via 在stackoverflow上,我知道我可以通过定义一个类
Method 1: 方法1:
function Person(name, gender){
this.name = name;
this.gender = gender;
}
and add functions in prototype so as to avoid member functions recreated every time its instantiated. 并在原型中添加函数,以避免每次实例化时重新创建成员函数。 like 喜欢
Person.prototype.speak = function(){
alert("my name is" + this.name);
}
and create its instances via 并通过创建它的实例
var person = new Person("Bob", "M");
I think the creation of same object is possible with out new keyword like 我认为无需使用新关键字即可创建相同的对象
Method 2: 方法2:
var Person = function (name, gender) {
return {name:name, gender:gender};
}
person = Person("Bob", "M");
Is the second method doing exactly the same thing done by the first one? 第二种方法执行的功能与第一种方法完全相同吗? Also if so how would i mock up addition of functions via prototype (as we see in method 1's speak) in the second approach? 如果是这样的话 ,在第二种方法中,我将如何通过原型(如方法1所示)来模拟附加功能?
No, Method 2 != Method 1. The second method is creating a new anonymous object with a prototype that points at Object.prototype
while the first is creating a new object with a prototype that points at Person.prototype
. 否,方法2!=方法1的第二种方法是创建与在点a原型新的匿名对象Object.prototype
,而第一是创建与指向在一个原型的新对象Person.prototype
。
In psuedo-code: 在伪代码中:
// Method #1
function Person(name, gender) {
// The magic JS does *for us* (but *only* when invoked with `new`)
var this = {};
// __proto__ is the *internal* prototype reference
// It's not required to be accessible unless you're in an ES6 environment.
this.__proto__ = Person.prototype;
// Person.prototype is also created by JS for us
// and provided with a reference (among other things)
// to this function as prototype.constructor.
// Our stuff
this.name = name;
this.gender = gender;
// More JS magic
return this;
}
// Method #2
function Person(name, gender) {
// Just our stuff - no magic JS goodness here
return {
name: name, gender: gender
};
}
As Sean Vieira explained the first method is not the same as the second method. 正如肖恩·维埃拉(Sean Vieira)解释的那样,第一种方法与第二种方法不同。 In the first method the instance inherits from Person.prototype
. 在第一种方法中,实例继承自Person.prototype
。 In the second method the instance inherits directly from Object.prototype
. 在第二种方法中,实例直接从Object.prototype
继承。
Method 1: 方法1:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| Person.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
Method 2: 方法2:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
Interestingly the above diagrams show you that objects inherit from other objects in JavaScript, and not from constructors. 有趣的是,上面的图向您展示了对象是从 JavaScript中的其他对象继承的 ,而不是从构造函数继承的 。 Hence when you create new Person
the instance inherits from Person.prototype
, not from Person
itself. 因此,当您创建new Person
该实例是从Person.prototype
继承的,而不是从Person
本身继承的。
How is this relevant information? 这些相关信息如何? For starters it demonstrates that you don't need to create a constructor to creates instances of an object. 对于初学者,它表明您不需要创建构造函数来创建对象的实例。 Instead you directly create the prototype object as follows: 而是直接按如下方式创建原型对象:
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 + ".");
}
};
In the above example person
is equivalent to Person.prototype
. 在上面的示例中, person
等同于Person.prototype
。 You may now create an instance of person
as follows: 您现在可以按以下方式创建person
实例:
var bob = person.create("Bob", "M");
The prototype chain of bob
will look like this: bob
的原型链看起来像这样:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
^
|
| __proto__
|
+------------------+
| bob |
+------------------+
So why should you create objects like this instead? 那么为什么要创建这样的对象呢?
new
to create an instance. 您不需要使用new
来创建实例。 This solves a lot of problems . 这解决了很多 问题 。 For more information about this pattern read my blog post on "Why Prototypal Inheritance Matters" . 有关此模式的更多信息,请阅读我的博客文章“为什么原型继承很重要” 。
Your examples are achieving the same thing with regards to accessing the properties, but they are not identical as the first method has the basic Object
prototype. 您的示例在访问属性方面实现了相同的目的,但是它们并不相同,因为第一种方法具有基本的Object
原型。 The answer to your second question is: 您的第二个问题的答案是:
function Person( name, gender ){
return {
name: name,
gender: gender,
speak: function(){
alert("my name is" + this.name);
}
};
}
Here there is no prototype. 这里没有原型。 The function is baked into the object literal. 该函数被烘焙到对象文字中。 The only value in using a literal instead of a prototype would be to create a closure so you can have private variables eg: 使用文字而不是原型的唯一价值是创建一个闭包,因此您可以拥有私有变量,例如:
function Person( name, gender ){
return {
speak: function(){
alert("my name is" + name);
}
};
}
Maybe this answer can explain a bit more about constructor functions, inheritance, private variables and overriding methods: Prototypical inheritance - writing up 也许这个答案可以解释更多有关构造函数,继承,私有变量和覆盖方法的信息: 原型继承-编写
The other answers already address your question; 其他答案已经解决了您的问题; creating an object as an object literal {prop:val,method:function(){}}
and creating an object using constructor functions: var MyObject=function(){this.prop=val};MyObject.prototype.method=function(){}
; 将对象创建为对象文字{prop:val,method:function(){}}
然后使用构造函数创建对象: var MyObject=function(){this.prop=val};MyObject.prototype.method=function(){}
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.