与关键字this相关的神秘“未定义”

时间:2019-04-14 01:08:13

标签: javascript

我刚开始使用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();

2 个答案:

答案 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