我刚开始使用JS,却对为什么吃东西blackie
感到困惑,而不是看到对象显示的名称,结果如下:
未定义在吃饭
我假设没有显示该名称,因为this
未定义。有人可以告诉我这是怎么发生的吗?我不明白问题是什么,因为下面的构造函数返回一个animal
对象。
function Animal(name) {
let animal = Object.create(Animal.prototype)
this.name = name
return animal
}
Animal.prototype.eat = function() {
console.log(this.name +" is eating.")
}
let blackie = Animal("Blackie");
console.log(blackie.name);
blackie.eat();
答案 0 :(得分:3)
如果您希望能够创建带有或不带有new
关键字的Animal实例,则只需检查this
是否为instanceof Animal
-如果不是,则{{1 }}如此
return new Animal(name)
答案 1 :(得分:0)
OP发布的更新代码为某些实用主义提供了极好的机会,如下所示:
Animal.prototype.eat = function() {
console.log(this.name +" is eating.");
}
function Animal(name) {
let animal = Object.create(Animal.prototype);
animal.name = name;
return animal;
}
let blackie = Animal("Blackie");
console.log( blackie.name);
blackie.eat();
更改后的代码使用新创建的动物对象尝试访问其自己的名称。原型中的关键字this
现在指向有效对象,因此可以访问其name属性!
但是,还有另一种修复代码的方法,如下所示:
function Animal(name) {
Object.create(Animal.prototype);
this.name = name;
return this;
}
Animal.prototype.eat = function() {
console.log(this.name + " is eating")
}
let blackie = new Animal("Blackie");
console.log(blackie.name);
blackie.eat();
Object.create()将创建一个对象
...使用现有对象作为新创建的原型 对象。
查看更多信息here。
从本质上讲,此示例需要“ new”实例化Animal对象,以便它可以在构造函数中return this
。注意:关键字this
指向实例化的对象。(顺便说一句,如果您更改代码以遵循@Jaromanda的建议技术,则可以忽略关键字“ new”。)
由于使用Object.create()可以轻松地基于另一个对象创建对象,因此以下显示了 blackie 对象在这种情况下的另一种生成方式,如下所示:< / p>
const another_animal = {
name: "nobody",
activity: function() {
console.log(`${this.name}` + " is napping");
}
};
const blackie = Object.create(another_animal);
blackie.name = "Blackie";
blackie.drink = function() {
console.log(`${this.name}` + " came, he saw, he drank");
};
console.log(blackie.name);
blackie.drink();
blackie.activity();
因此,如果代码基于现有的 对象的代码(如本示例所示),则也可以省略“ new”关键字。请注意,blackie
对象扩展了它所基于的 another_animal 。