JavaScript中的对象继承
Object Inheritance in JavaScript
我的问题是关于一个子对象维护其父对象的原型链。
在John Resig的高级Javascript幻灯片中(http://ejohn.org/apps/learn/#76)他写道,为了维护子对象的原型链,必须实例化一个新的父对象。
然而,通过几次快速测试,我注意到原型链是通过将子对象原型设置为父对象原型来维护的。
如有任何澄清,我们将不胜感激!
原始代码
function Person(){}
Person.prototype.dance = function(){};
function Ninja(){}
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
assert( (new Ninja()) instanceof Person, "Will fail with bad prototype chain." );
// Only this maintains the prototype chain
Ninja.prototype = new Person();
var ninja = new Ninja();
assert( ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype" );
assert( ninja instanceof Person, "... and the Person prototype" );
assert( ninja instanceof Object, "... and the Object prototype" );
我的修改版本
function Person(){}
Person.prototype.dance = function(){console.log("Dance")};
function Ninja(){}
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
assert( (new Ninja()) instanceof Person, "Will fail with bad prototype chain." );
var ninja = new Ninja();
assert( ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype" );
assert( ninja instanceof Person, "... and the Person prototype" );
assert( ninja instanceof Object, "... and the Object prototype" );
ninja.dance();
在John Resig提供的代码中,他首先将Ninja.prototype
设置为Person.prototype
。然后他立即将其重置为{ dance: Person.prototype.dance }
:
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
结果是Ninja
构造函数创建的任何对象都将直接从{ dance: Person.prototype.dance }
继承,而CCD_5不是Person.prototype
的实例。因此(new Ninja) instanceof Person
将返回false。在这种情况下,原型链是:
null
^
|
| [[prototype]]
|
+------------------+
| Object.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Ninja.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| new Ninja |
+------------------+
在修改后的版本中,您删除了对Ninja.prototype
的第二个赋值,从而有效地将Ninja.prototype
设置为Person.prototype
。因此原型链是:
null
^
|
| [[prototype]]
|
+-------------------+
| Object.prototype |
+-------------------+
^
|
| [[prototype]]
|
+-------------------+
| Ninja.prototype / |
| Person.prototype |
+-------------------+
^
|
| [[prototype]]
|
+-------------------+
| new Ninja |
+-------------------+
注意,由于Ninja.prototype
与Person.prototype
相同,(new Ninja) intanceof Ninja
和(new Ninja) instanceof Person
都将返回true
。这是因为instanceof
运算符依赖于构造函数的prototype
。
然而,在JavaScript中实现继承的正确方法是将Ninja.prototype
设置为Object.create(Person.prototype)
(或者用老派的方法设置为CCD20),在这种情况下,原型链将是:
null
^
|
| [[prototype]]
|
+------------------+
| Object.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Person.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Ninja.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| new Ninja |
+------------------+
注意:永远记住,在JavaScript中,对象继承自其他对象。它们从不从构造函数继承。如果你想了解JavaScript中真正的原型继承,请阅读我的博客文章,了解为什么原型继承很重要。
如果你不喜欢JavaScript中原型设计的工作方式来实现你所需要的,我建议你看看这个:https://github.com/haroldiedema/joii
它基本上允许你做以下(以及更多):
var Employee = new Class(function() {
this.name = 'Unknown Employee';
this.role = 'Employee';
});
var Manager = new Class({ extends: Employee }, function()
{
// Overwrite the value of 'role'.
this.role = 'Manager';
// Class constructor to apply the given 'name' value.
this.__construct = function(name) {
this.name = name;
}
});
var myManager = new Manager("John Smith");
console.log( myManager.name ); // John Smith
console.log( myManager.role ); // Manager
- JavaScript对象不是从原型链继承的
- JavaScript对象继承问题
- 类中对象的奇怪问题(John Resig简单继承)
- 继承对象并将变量传递给它,javascript
- 继承对象.遍历所有对象
- 调用本机原型方法时扩展或继承对象原型
- 继承对象的最佳做法
- 从继承对象的函数调用原型的方法
- CoffeeScript类-循环遍历继承对象的数组
- 通过原型继承对象
- 在Javascript中继承对象的值
- 为什么不通过原型链继承对象方法?
- 原型继承对象的多个实例
- Javascript中继承对象的两种不同(?)方法
- 继承对象的变化反映到父对象
- Angularjs, JavaEE和http请求继承对象
- 继承对象
- 具有继承对象参数的Jquery AutoComplete
- 用nodejs封装继承对象的属性
- 如何在javascript的构造函数中重写继承对象的属性?