两个 JavaScript 对象具有相同的属性实现方式,但原型不同
two javascript objects with same way of implementing properties but different prototype
我正在尝试创建 2 个共享相同实现方式的对象:
function Human(hand,leg,head,body,foot1,foot2){
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1,foot2];
}
function Robot(hand,leg,head,body,foot1,foot2){
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1,foot2];
}
我希望他们有不同的原型:
Human.prototype.scream = function(){
alert("HUMANNN");
//some other functions
};
Robot.prototype.scream = function(){
console.log("ROBOOBOT");
//some other functions
};
var Tom = new Robot(1,2,3,4,5,6);
Tom.scream();
var I = new Human(312314123,2141123,213131412,4121312,132124,12313);
I.scream();
有没有更好的方法来创建函数Human
和Robot
这样我就不必写两次了?
我试过了
function Robot(hand,leg,head,body,foot1,foot2){
Human(hand,leg,head,body,foot1,foot2);
}
var Micky = new Robot(1,2,3,4,5,6);
Micky.scream();
但它没有用。
我试过了
function Robot(hand,leg,head,body,foot1,foot2){ Human(hand,leg,head,body,foot1,foot2); }
这确实将Human
作为函数调用,而不是作为构造函数 - 不是在实例上,而是将全局对象作为this
值。您需要使用.call
:
function Robot(hand,leg,head,body,foot1,foot2) {
Human.call(this, hand,leg,head,body,foot1,foot2);
}
或者,如果您不想将它们写出来,可以使用 arguments
对象并apply
:
function Robot() {
Human.apply(this, arguments);
}
但是,与其从一个构造函数调用另一个构造函数,我建议将公共代码放入泛型构造函数中,并从Human
和Robot
调用它,以便您也可以将特定的实例初始化代码放在它们的构造函数中:
function Humanoid (hand, leg, head, body, foot1, foot2) {
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1, foot2]
}
function Human() {
Humanoid.apply(this, arguments);
…
}
// if you want Humans to inherit Humanoid prototype properties:
// Human.prototype = Object.create(Humanoid.prototype);
Human.prototype.… = …;
function Robot() {
Humanoid.apply(this, arguments);
…
}
// if you want Robots to inherit Humanoid prototype properties:
// Robot.prototype = Object.create(Humanoid.prototype);
Robot.prototype.… = …;
一种创建人类和机器人函数的方法,这样我就不必写两次了?
如果您确定构造函数代码始终完全相同,则还可以使用闭包:
function getConstructor() {
return function Human(hand,leg,head,body,foot1,foot2) {
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1,foot2];
}
}
var Human = getConstructor();
Human.prototype.… = …;
var Robot = getConstructor();
Robot.prototype.… = …;
您可以创建一个 mixin 函数,该函数将属性添加到构造函数并使用适当的上下文调用它。你也可以使用一个对象来代替这么多参数:
function mixin(props) {
for (var prop in props) {
this[prop] = props[prop];
}
}
function Human(props) {
mixin.call(this, props);
}
function Robot(props) {
mixin.call(this, props);
}
Human.prototype.scream = function() {
console.log('Human has '+ this.legs.length +' legs');
};
Robot.prototype.scream = function() {
console.log('Robot has '+ this.legs.length +' legs');
};
var human = new Human({
head: 1,
body: 1,
hand: 1,
legs: [1,2],
feet: [1,2]
});
var robot = new Robot({
head: 1,
body: 1,
hand: 1,
legs: [1,2,3],
feet: [1,2,3]
});
你需要的是申请或调用
// with call
function Robot(hand,leg,head,body,foot1,foot2){
Human.call(this, hand, leg, head, body, foot1, foot2);
}
var you = new Robot(1,2,3,4,5,6);
you.scream();
// with apply
function Robot(hand,leg,head,body,foot1,foot2){
Human.apply(this, arguments);
}
var you = new Robot(1,2,3,4,5,6);
you.scream();
使用 apply
,您基本上按照从原始函数获得的相同顺序传递所有参数。
更好的OOP方法
// From "Pro Javascript Design Patterns" by Ross Harmes and Dustin Diaz
function extend(subClass,superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superClass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
function Humanoid(hand,leg,head,body,foot1,foot2){
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1,foot2];
}
function Robot() {
Robot.superClass.constructor.apply(this,arguments);
}
extend(Robot,Humanoid);
function Human() {
Human.superClass.constructor.apply(this,arguments);
}
extend(Human,Humanoid);
var John = new Human(2,2,1,1,1,1);
console.log(John);
为什么不为人类和机器人创建一个通用原型,而只覆盖尖叫功能:
function HumanRobotProt(hand,leg,head,body,foot1,foot2){
this.hand = hand;
this.leg = leg;
this.head = head;
this.body = body;
this.feet = [foot1,foot2];
}
Human.prtotype = new HumanRobotProt;
Robot.prototype = new HumanRobotProt;
function Human(hand,leg,head,body,foot1,foot2){
Human.call(this, hand,leg,head,body,foot1,foot2);
this.scream = function(){
alert("HUMANNN");
}
function Robot(hand,leg,head,body,foot1,foot2){
Robot.call(this, hand,leg,head,body,foot1,foot2);
this.scream = function(){
alert("ROBOOOT");
}
相关文章:
- 在页面上记录数据并实现pushstate()的最佳方式
- 如何以最有效的方式实现这个多维数组
- 实现已验证用户更新状态的最佳方式,作为对系统中已更改状态的反应.(ASP.NET MVC网站)
- 使用ui路由器实现动态URL路由的最佳方式是什么
- 平滑滚动-实现方式相同,但效果不同
- Nodejs 实现数据库连接 (mysql) 的最佳方式
- 实现动态表单验证 Rails 的最佳方式
- 两个 JavaScript 对象具有相同的属性实现方式,但原型不同
- 最简单的实现方式是网页上的动态更新表(java/css)
- 如何以多个目标可以同时处于活动状态的方式实现“滚动间谍”
- 浏览器实现同源策略的方式是否存在实质性差异
- 如何以 Angular 方式实现 Twitter 按钮
- 如何以编程方式在 ADF 中实现未提交的数据警告
- 如何实现 emit 以同步方式工作
- 实现谷歌地图的最佳方式
- 用Javascript实现PHP常量的最佳方式
- 什么'这是实现这种特殊布局的最佳方式
- 如何更改Chrome'的键盘快捷方式;实现到HTML5语音输入API
- 频繁的轮询会使服务器过载吗?如果是的话;这是实现实时更新的最佳方式
- 用这种方式实现Javascript单例模式有什么问题吗?