javascript原型链对象与功能对象

时间:2018-03-14 17:54:26

标签: javascript

我可能没有正确地标题,但请有人解释为什么我不能为人物对象创建原型?只有当我将命中符号放到Object.prototype链上时才有效。

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

//person.prototype.hit = function(){
//    console.log("hitting me");
//}

Object.prototype.hit = function(){
    console.log("hitting me");
}

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();

(更新)。为什么这个工作?不确定这个例子实际上有什么不同,但是这段代码可以工作。

function person {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
}();

person.prototype.hit = function(){

    console.log("hitting me");
}

/*
person.prototype.hit = function(){
    console.log("hitting me");
}
*/

Object.prototype.hit = function(){
    console.log("hitting me");
}

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();
// expected output: "My name is Matthew. Am I human? true"

更新2

好的,所以我让它像下面那样工作,但显然原型不能按照我预期的方式工作..所以我显然对原型感到困惑

function person(){
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}

person.prototype.hit = function(){
    console.log("hitting me1");
}

Object.prototype.hit = function(){
    console.log("hitting me2");
}

const me = Object.create(person);

me.hit();

更新3。

谢谢..这是我从下面得到的解释..谢谢你,现在很清楚。

function person(){
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}

person.prototype.hit = function(){
    console.log("hitting me1");
}

Object.prototype.hit = function(){
    console.log("hitting me2");
}

//const me = Object.create(person);
const me = new person;

me.hit();

3 个答案:

答案 0 :(得分:2)

如果你这样做(与你正在做的非常相似):

 const person = {
   isHuman: false,
   printIntroduction: function () {
     console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
   },
   prototype: {
     hit(){ console.log("hutting me"); }
   }
 };

然后,当您实例化对象时,获得了一个原型属性:

 const me = Object.create(person);
 me.prototype.hit();

继承链是:

 me -> person -> Object.prototype

而不是:

 me -> person -> person.prototype -> Object.prototype

prototype属性实际上没有对继承做很多事情,只是想象它不存在。

然而,在谈论构造函数时,这很重要。当你在前面调用一个带有new的函数时,它被视为一个构造函数,例如:

 var me = new Person()

这只是语法糖:

 var me = Object.create(Person.prototype /*!!!*/);
 Person.call(me);

因此,当您设置函数时,设置其 prototype 属性并使用new调用它,只有构造函数的prototype属性才能获得实例原型链:

function Person(){}

Person.prototype.hit = () => console.log("works");

const me = new Person();
 me.hit();

现在链是:

me -> Person.prototype -> Object.prototype

答案 1 :(得分:2)

  

为什么我不能为person对象创建原型?

因为person没有.prototype属性,并且不需要。{/ p>

person对象已经有一个继承它的原型:Object.prototype(所有对象文字的默认值)。你不应该改变它。

此外,person确实充当me对象的原型(即me继承自person)。所以如果你想给它另一种方法,你应该写

person.hit = function(){
    console.log("hitting me");
};

hit函数作为person的属性,与printIntroduction完全相同。

答案 2 :(得分:0)

因为JS试图访问名为prototype的属性而不是该对象的“原型”。

要定义原型,您需要使用函数setPrototypeOf()

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

Object.setPrototypeOf(person, {
  'hit': function() {
    console.log("hitting me");
  }
});

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();

或者,您可以将该函数直接声明到对象person

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  },
  'hit': function() {
    console.log("hitting me");
  }
};

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();