Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在原型继承中创建新对象时如何重写函数?_Javascript_Inheritance_Javascript Objects - Fatal编程技术网

Javascript 在原型继承中创建新对象时如何重写函数?

Javascript 在原型继承中创建新对象时如何重写函数?,javascript,inheritance,javascript-objects,Javascript,Inheritance,Javascript Objects,下面是JavaScript中原型继承的示例: var human = { name: '', gender: '', planetOfBirth: 'Earth', sayGender: function () { alert(this.name + ' says my gender is ' + this.gender); }, sayPlanet: function () { alert(this.name +

下面是JavaScript中原型继承的示例:

var human = {
    name: '',
    gender: '',
    planetOfBirth: 'Earth',
    sayGender: function () {
        alert(this.name + ' says my gender is ' + this.gender);
    },
    sayPlanet: function () {
        alert(this.name + ' was born on ' + this.planetOfBirth);
    }
};

var male = Object.create(human, {
    gender: {value: 'Male'}
});

var female = Object.create(human, {
    gender: {value: 'Female'}
});

var david = Object.create(male, {
    name: {value: 'David'},
    planetOfBirth: {value: 'Mars'}
});

var jane = Object.create(female, {
    name: {value: 'Jane'}
});

david.sayGender(); // David says my gender is Male
david.sayPlanet(); // David was born on Mars

jane.sayGender(); // Jane says my gender is Female
jane.sayPlanet(); // Jane was born on Earth
现在,我想知道的是一个如何正确地“覆盖”,例如,
sayPlanet
函数

我这样试过:

jane.sayPlanet = function(){
    console.log("something different");
};
var jane = Object.create(female, {
    name: {value: 'Jane'},

    sayPlanet: function(){
        console.log("something different");
    }
});
var jane = Object.create(female, {
    name: {
        value: 'Jane',
        writable: true
    }
});
这是有效的

不过,我也试过这样做:

jane.sayPlanet = function(){
    console.log("something different");
};
var jane = Object.create(female, {
    name: {value: 'Jane'},

    sayPlanet: function(){
        console.log("something different");
    }
});
var jane = Object.create(female, {
    name: {
        value: 'Jane',
        writable: true
    }
});
但是我得到了一个类型错误

我的问题是:

  • 如何在
    对象中添加
    sayPlanet
    函数。创建
  • 这到底是一种“好方法”还是有更好的(最佳实践)方法
编辑: 我想出了一种方法,可以在
对象中添加
sayPlanet
。创建

sayPlanet: {
    value: function(){
        console.log("something different");
    }
}
然而,第二个问题仍然存在。此外,如果有人能更深入地解释一下,如果这是一个“好方法”这样使用它,我将不胜感激

编辑#2:正如马哈维尔在下面指出的,这是一个可怕的例子,因为事实证明,一旦
jane
名称成为
对象,你就不能(如果我错了请纠正我)。创建
d

编辑#3:(老兄,这会让我进入一个人们穿白大褂的特定场所)。正如@WhiteHat在下面指出的,您确实可以将name属性设置为可更新,如下所示:

jane.sayPlanet = function(){
    console.log("something different");
};
var jane = Object.create(female, {
    name: {value: 'Jane'},

    sayPlanet: function(){
        console.log("something different");
    }
});
var jane = Object.create(female, {
    name: {
        value: 'Jane',
        writable: true
    }
});
然后您可以执行
jane.name=“jane v2.0”


老实说,这里的人们,我不知道该朝哪个方向走,似乎有这么多的选择。就在今天,我读了埃里克·埃利奥特(Eric Elliot),现在我不知道该怎么想了,因为他继续争辩说ES6的人做得不太对:哦,我想我必须再次重温克罗克福德(Crockfords)这本书,决定一个“单程”,看看我能走多远

1-它应该类似于下面的代码块:

var jane = Object.create(Female.prototype, {
    name: {value: 'Jane'},

    sayPlanet:{ value : function(){ alert("something different");}}
});
2-此解决方案很好,您可以从MDN中看到这一点

调用属性对象的第二个参数

的语法部分对其进行了最好的描述,请参见道具

简而言之,传递给
Object.create
的第二个参数应该具有可枚举属性,每个属性都具有以下一个或多个键

可配置的
可枚举的

可写的
获取
设置

您应该为您分配的每个班级成员解决这些问题。
根据预期的功能

根据问题中的示例,为了在创建对象后更改值,只需添加
writable:true

var human = {
    name: '',
    gender: '',
    planetOfBirth: 'Earth',
    sayGender: function () {
        console.log(this.name + ' says my gender is ' + this.gender);
    },
    sayPlanet: function () {
        console.log(this.name + ' was born on ' + this.planetOfBirth);
    }
};

var male = Object.create(human, {
  gender: {
    value: 'Male',
    writable: true
  }
});

var david = Object.create(male, {
  name: {
    value: 'David',
    writable: true
  },
  planetOfBirth: {
    value: 'Mars',
    writable: false  //only born once
  }
});

david.sayGender();
david.sayPlanet();

david.gender = 'Female';
david.name = 'Caitlyn';
david.planetOfBirth = 'Venus';  //(will not work, not writable)

david.sayGender();
david.sayPlanet();

我不确定javascript中是否有原型继承的最佳实践,但将原型分配给对象的经典方法是创建构造函数:

var human = {
  sayPlanet:function(){
    // old sayPlanet
  }
}

function Person(name, sayPlanet)
{
  this.name = name;
  this.sayPlanet = sayPlanet;
}

Person.prototype = human;

// use your constructor function
var david = new Person('david', function(){/*new sayPlanet*/});

ES6标准中也提出了这一点,但您必须记住,它是javascript现有的基于原型的继承之上的一种语法糖,javascript中仍然没有本机类

实现继承的方法非常糟糕,我对这个例子感觉不太好

如果要更改某些值,请在创建对象后的某个时间说“planetOfBirth/gender”

  • 由于对象属性默认不可枚举,因此 可配置,不可写
最佳实践始终取决于您的模型、结构和最终目标。 下面的分析是一种方法

//下面是同一个例子:让我们像理解现实生活中的问题一样来理解这一点
//创建人体对象
var人类={
名称:“”,
性别:'',
行星诞生:“地球”,
性别:功能(){
log(this.name+'表示我的性别是'+this.gender);
},
sayPlanet:函数(){
console.log(this.name+'出生于'+this.planetOfBirth');
}
};
//创建Person构造函数,稍后用于创建男性/女性对象,如David/Jane
var Person=职能(性别、姓名){
这个。性别=性别;
this.name=名称;
};
//将人指定为人构装师的原型
Person.prototype=Object.create(人);
//塞特函数可以改变一个人出生的星球
Person.prototype.setPlanetOffirt=函数(PlanetOffirt){
this.planetoforbirth=planetoforbirth;
};
//使用Person构造函数创建david对象
var david=新人(“男性”、“david”);
//将大卫的出生星球改为火星
大卫。赛特普兰托福出生(“火星”);
//使用Person构造函数创建jane对象
var jane=新人(“女性”、“jane”);
//特定于对象的函数仅可供Jane使用
jane.sayPlanet=函数(){
log(“不同的东西”);
};
david.sayGender();//大卫说我的性别是男性
david.sayPlanet();//大卫出生在火星上
jane.sayGender();//简说我的性别是女性

jane.sayPlanet();//使用
Object.create
肯定是一种有效的方法,但是在我看来,这个例子本身对于
Object.create的内部工作方式似乎有点误导。这篇博文在总结javascript中创建对象的不同方法方面做得非常好,但我认为
Object.create
的例子并没有很好地说明它是如何工作的,这与
新的/constructor
方法似乎更为相似

Object.create
允许基于
原型创建对象,但不使用
构造函数。这意味着所创建对象的
原型链
不依赖于
构造函数
,(这就是为什么它可能更容易遵循的原因,通过构造函数链接的这个原型不是很简单,也不容易遵循)。但是
Object.create
仍然创建
原型链
,方法与
new
相同

因此,在您的示例中,当您在
human
中定义
name
时,例如:

var human = {
    name: '',
然后当您创建
jane
时:

var jane = Object.create(female, {
    name: {value: 'Jane'}
你不是一个真正的艺术家