ope*_*sas 7 javascript prototype anti-patterns prototypal-inheritance prototype-programming
我经常看到这种模式来定义javascript对象
function Person(name) {
this.name = name;
}
Person.prototype.describe = function () {
return "Person called "+this.name;
};
Run Code Online (Sandbox Code Playgroud)
在本文中,它表示直接向原型对象添加属性被视为反模式.
来自"基于经典类"的语言,除了方法之外必须定义属性听起来不太正确,不过在javascript中,方法应该只是具有函数值的属性(我在这里吗?)
我想知道是否有人可以解释这个,甚至建议一个更好的方法来处理这些情况
在通常的面向对象语言中,您有一个描述成员,方法和构造函数的类的定义.
在JS中,"类"的定义(它实际上并不像其他语言中的类......有时使用术语伪类)是构造函数本身.如果您的对象是参数化的name,那么写入是有意义的
function Person(name) {
this.name = name;
}
Run Code Online (Sandbox Code Playgroud)
即name必须在构造函数中设置属性.
当然,你可以写
function Person(name) {
this.name = name;
this.describe = function() { ... };
}
Run Code Online (Sandbox Code Playgroud)
它会像你期望的那样工作.
但是,在这种情况下,您每次调用构造函数时都会创建一个单独的方法实例.
另一方面,这里:
Person.prototype.describe = function () {
return "Person called "+this.name;
};
Run Code Online (Sandbox Code Playgroud)
你只定义一次方法.所有实例Person都会收到一个指针(__proto__在大多数浏览器中被程序员调用并且无法访问)Person.prototype.所以,如果你打电话
var myPerson = new Person();
myPerson.describe();
Run Code Online (Sandbox Code Playgroud)
它会工作,因为JS直接在对象中查找对象成员,然后在其原型等中查找对象成员Object.prototype.
关键是在第二种情况下,只存在一个函数实例.你可能会认为这是一个更好的设计.即使你不这样做,也只需要更少的内存.
这段代码没有错.据说这意味着:
function Person(name) {
this.name = name;
}
Person.prototype.age = 15; //<= adding a hardcoded property to the prototype
Run Code Online (Sandbox Code Playgroud)
现在你会看到这个:
var pete = new Person('Pete'), mary = new Person('Mary');
pete.age; //=> 15
mary.age //=> 15
Run Code Online (Sandbox Code Playgroud)
大多数时候,这不是你想要的.分配给构造函数原型的属性在所有实例之间共享,构造函数(this.name)中分配的属性特定于实例.
| 归档时间: |
|
| 查看次数: |
1662 次 |
| 最近记录: |