这种Javascript继承方法有什么问题吗
Is there something wrong with this approach to Javascript Inheritance?
我想用JavaScript进行一些继承,在搜索inter-web时,我发现了许多继承的例子、多种方法和实现。我最终找到了一个我喜欢的方法,因为它很简单,从所有的阅读和学习中,我想出了这个方法:
var Animal = function () {
var self = this;
self.legs = 4;
self.makeNoise = function () {
return "noise";
};
};
var Dog = function () {
var self = new Animal();
self.base = {
makeNoise: self.makeNoise
};
self.makeNoise = function () {
var noise = "bark 'n";
noise += self.base.makeNoise();
return noise;
};
return self;
};
var Monkey = function () {
var self = new Animal();
self.base = {
makeNoise: self.makeNoise
};
self.legs = 2;
self.makeNoise = function () {
var noise = "weird monkey sound 'n";
noise += self.base.makeNoise();
return noise;
};
return self;
};
$("#monkey").click(function () {
var monkey = new Monkey();
var result = "Legs: " + monkey.legs + "'n";
result += "Noise: " + monkey.makeNoise();
alert(result);
});
$("#dog").click(function () {
var dog = new Dog();
var result = "Legs: " + dog.legs + "'n";
result += "Noise: " + dog.makeNoise();
alert(result);
});
你可以在这里找到一个工作的JSFiddle。
正如您从代码中看到的,我在base
变量中保留了原始基函数的引用,这样我就可以调用base
。你认为这种方法有什么不对吗?有什么缺点,未来可能出现的监督问题,我遗漏了什么?
好吧,这里有一件事是错误的:
var dog = new Dog();
console.log(dog instanceof Dog) //=> false
问题是,您所做的实际上是而不是继承。您只是简单地使用函数来返回动物对象的修改版本。这导致了一种类似于继承但又不同的行为。
JavaScript的对象模型使用称为原型链的东西,这与典型的面向对象继承非常相似。Mozilla开发者网络在这方面有一篇很棒的文章:继承和原型链。
以下是如何在示例中使用原型继承的示例:
var Animal = function() {};
Animal.prototype = {
legs: 4,
makeNoise: function () {
return "noise";
}
};
var Dog = function () {};
// Notice: Dog.prototype is inheriting from Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.makeNoise = function () {
var noise = "bark 'n";
// Notice: calling Animal's makeNoise function with
// 'this' set to our dog object.
noise += Animal.prototype.makeNoise.call(this);
return noise;
};
var Monkey = function () {};
// Notice: Monkey.prototype is inheriting from Animal.prototype
Monkey.prototype = Object.create(Animal.prototype)
Monkey.prototype.legs = 2;
Monkey.prototype.makeNoise = function () {
var noise = "weird monkey sound 'n";
// Notice: calling Animal's makeNoise function with
// 'this' set to our monkey object.
noise += Animal.prototype.makeNoise.call(this);
return noise;
};
$("#monkey").click(function () {
var monkey = new Monkey();
var result = "Legs: " + monkey.legs + "'n";
result += "Noise: " + monkey.makeNoise();
alert(result);
});
$("#dog").click(function () {
var dog = new Dog();
var result = "Legs: " + dog.legs + "'n";
result += "Noise: " + dog.makeNoise();
alert(result);
});
$("#inheritance").click(function () {
var dog = new Dog();
var monkey = new Monkey();
var result = 'dog instanceof Dog = ' + (dog instanceof Dog) + "'n" +
'dog instanceof Animal = ' + (dog instanceof Animal) + "'n" +
'dog instanceof Monkey = ' + (dog instanceof Monkey) + "'n" +
'monkey instanceof Monkey = ' + (monkey instanceof Monkey) + "'n" +
'monkey instanceof Animal = ' + (monkey instanceof Animal) + "'n" +
'monkey instanceof Dog = ' + (monkey instanceof Dog) + "'n";
alert(result);
});
查看JS Fiddle
这是一篇优秀的文章:http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/
//Constructor/Object
function Animal(inNoise) {
this.legs = 4;
this.noise = inNoise;
}
//Set Objects prototypes
Animal.prototype = {
constructor: Animal,
changeNoise: function(newNoise){this.noise = newNoise;}
}
//Create some dogs
var dog = new Animal('bark');
var pitbull = Object.create(dog);
var chiahua = Object.create(dog);
//Change dogs noise
chiahua.changeNoise('littleBark');
alert(dog.noise); //bark
alert(pitbull.noise);//bark
alert(chiahua.noise); //littlebark
alert(chiahua.legs); //4
除了返回self
会破坏继承链之外,您可能对JavaScript的继承技术有误解:
JavaScript是一种基于原型的语言,这意味着正确的继承是这样设置的:
function Animal(){}
Animal.prototype.walk = function(){
console.log('walking...');
};
Animal.prototype.roar = function(){
alert('roar');
};
function Dog(){}
Dog.prototype = new Animal();
Dog.prototype.roar = function(){
alert('bark!');
};
var animal = new Animal();
var dog = new Dog();
animal.walk();
dog.walk(); // both can call the walk function
animal.roar(); // alerts roar
dog.roar(); // alerts bark
原型继承允许共享对象定义的内存(将一个对象记录到控制台以了解我的意思(。换句话说,Dog
的每个实例都将使用相同的roar
函数,但通过在构造函数中将属性直接附加到this
,可以防止原型链,并将函数的内存委派给该对象的每个实例。如果你要创建该对象的许多实例,应用程序的性能将反映这一点。
@在我的例子中,Thom正在展示经典继承与原型。两者都是对的,但这里有一个很好的Stack答案。
- 我不知道我的编码有什么问题.(JavaScript)
- 我的流星路线出了什么问题
- 此nodeValue替换代码有什么问题
- 这个正则表达式的日期/时间有什么问题
- 我的CSS/Javascript下拉菜单测试代码出了什么问题
- 这个代码出了什么问题?(Jquery)
- 下面的Reg表达式出了什么问题
- 鼠标事件,我的代码出了什么问题
- 这个javascript语法有什么问题
- 动态创建foreignGroup并将其添加到svg中有什么问题
- 此代码中动态生成选择框有什么问题
- 我的javascript有什么问题?.className
- 这个 ajax.js 代码有什么问题
- JS代码有什么问题,让我知道代码是否可以改进
- 我的 Browserify JavaScript 代码有什么问题
- 图像上传功能将++(+1)副本添加到下一次上传.出了什么问题或如何重置“选定图像”
- 使用 Javascript 动态删除行.我的代码有什么问题
- AngularJS:这个注入我的控制器有什么问题
- 这个jQuery if语句有什么问题
- JavaScript:有人能告诉我我的代码出了什么问题吗?