我无法理解某些事情。我一直在寻找差异,但我似乎无法找到我想要的答案。
我正在尝试学习OOP javascript,我在那里阅读的每个教程似乎都是一种不同的继承方式,并且通常以非常复杂的方式进行解释。我现在遇到的问题与为对象创建方法有关,我使用的是Mozilla开发人员文档中的代码。
您会在下面的大型代码块中看到我尝试在jump
中添加Person
方法,如下所示:
Person.prototype = {
jump: function() {
console.log("Jumping")
}
}
这不起作用它基本上打破了整个课程,告诉我student1.walk
不是一个函数。但是,如果我将方法的声明更改为
Person.prototype.jump = function() {
console.log("Jumping");
}
当我调用方法时,一切都会像它应该的那样工作。从个人风格的角度来看,虽然我喜欢创建方法的第一种方法,因为我不必继续重复Person.prototype
部分,我可以继续添加逗号,然后是我的方法声明。我想知道这两种创建方法的方法之间有什么区别,因为我无法在任何地方找到答案。我想了解为什么它也会使用第一种方法中断。
var Person = function(firstName) {
this.firstName = firstName;
};
Person.prototype.walk = function(){
console.log("I am walking!");
};
Person.prototype = {
jump: function() {
console.log("Jumping");
}
}
Person.prototype.sayHello = function(){
console.log("Hello, I'm " + this.firstName);
};
function Student(firstName, subject) {
Person.call(this, firstName);
this.subject = subject;
}
Student.prototype = Object.create(Person.prototype); // See note below
Student.prototype.constructor = Student;
Student.prototype.sayHello = function(){
console.log("Hello, I'm " + this.firstName + ". I'm studying "
+ this.subject + ".");
};
Student.prototype.sayGoodBye = function(){
console.log("Goodbye!");
};
var student1 = new Student("Janet", "Applied Physics");
student1.sayHello();
student1.walk();
student1.sayGoodBye();
student1.jump();
答案 0 :(得分:7)
问题在于您通过调用Person.prototype = {}
来覆盖整个原型链。这使得其他方法消失了,因为它们通过重置而从链中取出。
它与任何其他变量一样
let x = 5; //5
x = 6; // 6
这是一个简单的赋值语句,重新分配你的原型链。
答案 1 :(得分:3)
比较两个陈述:
Person.prototype = {
jump: function() {
console.log("Jumping");
}
};
在这里,您将原型设置为新的对象文字。在下一个声明中:
Person.prototype.jump = function() {
console.log("Jumping");
};
您正在将原型的跳转属性设置为函数。
如果要一次添加所有功能,请将原型声明一次:
Person.prototype = {
jump: function() {
console.log("Jumping")
},
walk: function(){
console.log("I am walking!");
},
sayHello: function(){
console.log("Hello, I'm " + this.firstName);
}
};
它们之间的区别仅仅在于将方法添加到原型中。我通常更喜欢一次将所有功能添加到原型中,以便我知道代码在哪里制作了sayHello
方法。如果我需要根据新信息重新定义方法,我偶尔会使用第二种方法。但这非常罕见。
答案 2 :(得分:2)
永远不要用不同的对象替换构造函数的prototype
,除非你知道自己在做什么。
它有这些问题:
instanceof
视为实例,并且他们不会从新对象继承属性。constructor
属性或内部[[Prototype]]。除非您将其复制到新对象,否则这将丢失。如果您只想向prototype
添加多个属性而不是每次都重复,请使用Object.assign
:
Object.assign(Person.prototype, {
jump: function() {
console.log("Jumping");
},
sayHello = function(){
console.log("Hello, I'm " + this.firstName);
}
});
答案 3 :(得分:1)
javascript中的OOP很难看。我会使用像ds.oop这样的类库。它类似于prototype.js和其他。使多重继承非常容易和极简主义。 (仅2或3 kb)还支持其他一些简洁的功能,如接口和依赖注入
/*** multiple inheritance example ***********************************/
var Runner = ds.class({
run: function() { console.log('I am running...'); }
});
var Walker = ds.class({
walk: function() { console.log('I am walking...'); }
});
var Person = ds.class({
inherits: [Runner, Walker],
eat: function() { console.log('I am eating...'); }
});
var person = new Person();
person.run();
person.walk();
person.eat();