JavaScript 原型继承
JavaScript prototype inheritance
下面是一个简单的 JavaScript 继承示例。我们可以替换行:Dog.prototype = new Animal();
Dog.prototype = Animal.prototype?
我已经在浏览器中测试过,他们给我的结果是一样的。我很奇怪为什么我们需要创建一个新的 Animal 对象并将其分配给 Dog.prototype。
function Animal(age){
this.age = age;
}
Animal.prototype.walk = function(){
console.log("Walk");
}
function Dog(color, age){
this.color = color;
Animal.call(this, age)
}
Dog.prototype = new Animal(); //Why not Dog.prototype = Animal.prototype
Dog.prototype.constructor = Dog;
dog_b = new Dog("yellow", 9);
console.log("Age: " + dog_b.age + " Color: " + dog_b.color );
dog_b.walk()
在这种特殊情况下,您可以出于一个简单的原因替换这些行:
function Dog(color, age) {
this.color = color;
Animal.call(this, age); // This line
}
在这里,您使用 call
提供的 this
调用 Animal 的构造函数,从而手动建立 Animal 的上下文。因此 function Animal
中的 this
将始终引用 Dog
的对象。这就是为什么 new
根本不会产生任何影响。
严格来说,您实际上并没有进行适当的原型继承。您可以通过以下方式确认:
dog_b.hasOwnProperty('age'); // => true
这实际上称为 constructor stealing
,其中 Dog
窃取了 Animal
的构造函数。 walk
方法虽然在 Animal
的 ctor 上。
这意味着 age
属性 在 Dog
本身而不是 Animal
上。这是为什么?同样,因为您要手动将 Animal
的构造函数上下文建立为 Dog
.
的构造函数上下文
编辑:
在 Javascript 中有多种描述和获得继承的方法,由于这不是写书的地方,所以我会很快。
您正在做的事情叫做 Parasitic Combination Inheritance
(您不必记住这个词)。这并没有错,它只是获得继承的另一种方式(这只是 Animal.prototype
上的函数的原型)。如果它对你有用,我会说接受它。如果你真的真的想让Animal
的age
在Animal
上,那么你在使用构造函数获取继承时就会遇到问题
这样做的一种方法是:
function inherit(o){
function F(){}
F.prototype = o;
return new F();
}
var foo = {
name: 'some'
}
var bar = inherit(foo); // bar.name refers to the object on foo
如您所见,原型继承通常用于对象文字(想想 angular 的作用域对象)。
下面是一个简单的 JavaScript 继承示例。我们可以替换行:Dog.prototype = new Animal();
Dog.prototype = Animal.prototype?
我已经在浏览器中测试过,他们给我的结果是一样的。我很奇怪为什么我们需要创建一个新的 Animal 对象并将其分配给 Dog.prototype。
function Animal(age){
this.age = age;
}
Animal.prototype.walk = function(){
console.log("Walk");
}
function Dog(color, age){
this.color = color;
Animal.call(this, age)
}
Dog.prototype = new Animal(); //Why not Dog.prototype = Animal.prototype
Dog.prototype.constructor = Dog;
dog_b = new Dog("yellow", 9);
console.log("Age: " + dog_b.age + " Color: " + dog_b.color );
dog_b.walk()
在这种特殊情况下,您可以出于一个简单的原因替换这些行:
function Dog(color, age) {
this.color = color;
Animal.call(this, age); // This line
}
在这里,您使用 call
提供的 this
调用 Animal 的构造函数,从而手动建立 Animal 的上下文。因此 function Animal
中的 this
将始终引用 Dog
的对象。这就是为什么 new
根本不会产生任何影响。
严格来说,您实际上并没有进行适当的原型继承。您可以通过以下方式确认:
dog_b.hasOwnProperty('age'); // => true
这实际上称为 constructor stealing
,其中 Dog
窃取了 Animal
的构造函数。 walk
方法虽然在 Animal
的 ctor 上。
这意味着 age
属性 在 Dog
本身而不是 Animal
上。这是为什么?同样,因为您要手动将 Animal
的构造函数上下文建立为 Dog
.
编辑:
在 Javascript 中有多种描述和获得继承的方法,由于这不是写书的地方,所以我会很快。
您正在做的事情叫做 Parasitic Combination Inheritance
(您不必记住这个词)。这并没有错,它只是获得继承的另一种方式(这只是 Animal.prototype
上的函数的原型)。如果它对你有用,我会说接受它。如果你真的真的想让Animal
的age
在Animal
上,那么你在使用构造函数获取继承时就会遇到问题
这样做的一种方法是:
function inherit(o){
function F(){}
F.prototype = o;
return new F();
}
var foo = {
name: 'some'
}
var bar = inherit(foo); // bar.name refers to the object on foo
如您所见,原型继承通常用于对象文字(想想 angular 的作用域对象)。