所以我真的在互联网上看了很多不同的方法来设置javascript中的原型继承。
其中一些人使用call()
他们中的一些人使用这个sytnax:var rabbit.prototype = new Animal
其中一些在更改原型后更改了构造函数,有些则没有
有些设置了一个有助于设置继承的小功能。
有人可以对此有所了解吗?有很多关于这个的帖子,但好的帖子已经超过2年了,它们在我的脑海里引起了很大的混乱。
我想一劳永逸地知道如何在javascript中正确设置原型继承。
如果简单就更好了!
答案 0 :(得分:4)
实现了几种不同的javascript继承方式,这最终是我想要为浏览器RPG构建javascript游戏引擎的时候:
玩家基类:
function Player(name, type, gender, experience, avatar){
this.name = name;
this.type = type;
this.gender = gender;
this.experience = experience;
this.avatar = avatar;
this.stats ={//getter, setter}
//lots more code
}
向玩家类添加方法
Player.prototype.decrease_life = function(decrement){}
//note that the keyword this in the decrease_life function will
//refer to the player that the method is called on.
现在继承玩家类:
function Mage(name, type, gender, exp, avatar){
Player.apply(this, [name,type,gender,exp,avatar]);
//apply allows you to specify what the keyword
//this refers to in the Player super class.
}
Mage.prototype = new Player;
最后我们创建一个玩家:
current_player = new Mage(name,type,gender,0,avatar);
现在允许我们这样做:
current_player.decrease_life(20); //The mage loses 20 life!
或者这样做:
current_player.stats.get();
//returns the mages stats, it does that because we used apply, and
//this.stats in the player class is referring to our mage now
正如其他人所说,javascript继承没有最佳实践。我发现上面最接近的模仿了你如何期望继承在Java或C ++中工作,它们具有更多典型的继承结构。
答案 1 :(得分:2)
关于原型继承的重要一点是,你是从对象继承而不是从类继承。所以我的想法是tomsBankAccount
继承bankAccount
,这可能是通过基于类的语言中的即时性来完成的。如果你想要一个'类'的'实例',那就可以通过实现公共特征的对象完成,它是任何需要这些特征的对象的原型。
这是一个未经测试和错误的具体示例。但这是我错的原因。
var bankAccount = {
withdraw: function(amount) { this.balance -= amount },
deposit: function(amount) { this.balance += amount }
}
var account1 = {
balance: 50
}
account1.prototype = bankAccount
account1.deposit(100)
alert(account1.balance) // Displays 150
因此,对象有自己的东西,如balance
字段,但将常用功能委托给bankAccount对象。所以继承的等价物就是决定一个普通案例对象和原型。
实际上,上面的代码已经破了。 JavaScript不会让您只是原型化任何旧对象,或者至少较旧 JavaScript不会。它强制原型化只能从constructor functions
返回的对象完成,这些对象在您调用它们时在JavaScript中具有特殊语法,即new
关键字。
您可能已经看到类似这样的代码(再次,未经测试):
function BankAccount(balance) {
this.balance = balance
this.withdraw = function(amount) { this.balance -= amount }
this.deposit = function(amount) { this.balance += amount }
}
var account1 = new BankAccount(50)
account1.deposit(100)
alert(account1.balance) // Same result as last time
你还会注意到他们以大写字母开头。就是这样,基本上。 this
很奇怪 - 它带有对函数所包含的对象的引用。因此,带有deposit
方法的对象也会带有balance
属性,这就是我们可以通过方法balance
访问this
的原因。
但上面的代码不是惯用的JavaScript。一旦掌握了它,有些事情需要记住。例如,上面重新分配了每个对象构造的新方法,这显然不是很快。通过将方法分配给函数构造函数的原型来解决这个问题。还可以通过JavaScript的闭包来“私有化”属性。
你可能会怀疑JavaScript类似于Java的符号表示完全是误导,因为它在下面是如此不同......我同意。
答案 2 :(得分:1)
没有真正统一的'最佳方式'来做到这一点。来自2岁的“好答案”仍然具有相关性(如果它们很好,我个人会放弃任何试图模仿课程的东西),因为javascript(EcmaScript)已经很久了(十多年)。
call
用于传递this
的内容。
至于原型继承:我真的很喜欢YUI剧院的'crockford on javascript'。 您想要观看“Act III: function the ultimate”
最简单的设置原型的方法是:
objectIdentifier.prototype.methodIdentifier = function(args){ /* your code*/ }
有许多不同的“构造模式”,其中大部分都在特定的情况下使用。考虑一段代码将要做什么以及经常如何使用它通常是一个好主意。你也想看看像JQuery这样的流行图书馆,看看他们的模式。
希望这有帮助!