我最近Object.create()在JavaScript中偶然发现了这个方法,并试图推断它与创建一个对象的新实例有什么不同new SomeFunction(),当你想要使用另一个时.
请考虑以下示例:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2Run Code Online (Sandbox Code Playgroud)
请注意,在两种情况下都观察到相同的行为.在我看来,这两种情况之间的主要区别是:
Object.create()实际使用的对象实际上形成了新对象的原型,而在new …出于某种原因,看起来构造函数委派在以下代码段中不起作用:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
Run Code Online (Sandbox Code Playgroud)
运行这个给出The message is: ''.有关为什么,或者是否有更好的方法来创建新Error子类的任何想法?是否存在我不知道apply的本机构Error造函数的问题?
以下代码的作用如下:
WeatherWidget.prototype = new Widget;
Run Code Online (Sandbox Code Playgroud)
哪里Widget是构造函数,我想用新函数扩展Widget'类' WeatherWidget.
什么是new关键字在那里做什么以及如果被遗漏会发生什么?
我已经看过很多像这样的东西了,我正在寻找基本的JavaScript继承的正确解决方案:
function Food(){} // Food constructor (class)
function Bread(){} // Bread constructor (class)
var basicFood = new Food(); // Food classes will inherit from this basicFood instance.
Bread.prototype = basicFood; // Bread now inherits from Food.
var bread = new Bread(); // We create some bread!
bread.constructor == Food; // Though, now we feel very uneasy about how
// the constructor is wrong,
Bread.prototype.constructor = Bread; // So we explicitly set the prototype's constructor
bread = new Bread(); // and …Run Code Online (Sandbox Code Playgroud) 我创建了一个像下面这样的对象.
var BaseObject = function(){
var base = this;
base.prop;
base.setProp = function(val){
base.prop = val;
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用该setProp方法时,我得到以下内容.
var a = new BaseObject();
var b = new BaseObject();
a.setProp("foo");
b.setProp("bar");
console.log(a.prop); // outputs 'foo'
console.log(b.prop); // outputs 'bar'
Run Code Online (Sandbox Code Playgroud)
然后我创建了另一个继承自BaseObject这样的对象.
var TestObject = function(){
// do something
}
TestObject.prototype = new BaseObject();
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我得到了一个我没想到的结果.
var a = new TestObject();
var b = new TestObject();
a.setProp("foo");
b.setProp("bar");
console.log(a.prop); // outputs 'bar'
console.log(b.prop); // outputs 'bar'
Run Code Online (Sandbox Code Playgroud)
我不知道为什么.我最近一直在阅读很多关于闭包和原型继承的内容,我怀疑我已经把它弄得一团糟.因此,非常感谢任何有关此特定示例为何如此工作的指针.
好像我终于理解了JavaScript继承以及如何正确地完成它.这是我的代码:
function Human(eyes) {
this.eyes = eyes ? "Not blind" : "Blind";
}
Human.prototype.canSee = function () {
return this.eyes;
};
function Male(name, eyes) {
Human.call(this, eyes);
this.name = name;
}
Male.prototype = Object.create(Human.prototype);
var Sethen = new Male("Sethen", true);
console.log(Sethen.canSee()); //logs "Not blind"
Run Code Online (Sandbox Code Playgroud)
据我所知,使用Object.create创建继承的原型对象比使用new关键字要好得多.这引起了我脑子里的几个问题.
Male.prototype = Object.create(Human.prototype)将原型链Male.prototype --> Human.prototype --> Object.prototype --> null?Male我Human.call(this, eyes);用来调用超类的构造函数中,我必须在Male构造函数中再次传递眼睛以将其传递给Human构造函数.这似乎很痛苦,有没有更简单的方法呢?Male.prototype = new Human();...这似乎是不正确的.当我们这样做时,实际发生了什么?我一直在阅读使用Javascript的面向对象编程的MDN指南,其中在一个示例中显示继承,提到以下内容:
// Create a Student.prototype object that inherits from Person.prototype.
// Note: A common error here is to use "new Person()" to create the
// Student.prototype. That's incorrect for several reasons, not least
// that we don't have anything to give Person for the "firstName"
// argument. The correct place to call Person is above, where we call
// it from Student.
Student.prototype = Object.create(Person.prototype); // See note below
Run Code Online (Sandbox Code Playgroud)
我也研究了其他答案,但他们没有具体说明使用时会遇到什么问题 Student.prototype = new Person()
上面提到的一个问题涉及传球firstName,但这只是一个场景.
在任何人将此标记为重复之前.这里的问题使用"Object.create"而不是"new"处理通常使用 …