有人能向我解释函数.protype.call()和函数.protype=对象.create()吗

can someone explain function.prototype.call() and function.prototype=Object.create() to me?

本文关键字:函数 protype 对象 create 解释 call      更新时间:2023-09-26

我知道如何编写正确的继承,但我在写这篇文章时试图准确地理解我在做什么,这样我就完全理解了我的代码。我读了一些MDN,但我还没有完全理解它,如果能提供帮助,我将不胜感激,谢谢,我有点困惑

我知道我应该写这样的继承

 function Employee(){
      this.pay=' ';
      this.dept=' ';
 }
 function Manager(){
     Employee.call(this);
     this.reports=[];
 }
 Manager.prototype=Object.create(Employee.prototype);

根据我的理解,function.call的工作原理与此类似,因此当您作为一个arg,它会更改为arg1指向的位置,例如,它基本上允许您更改为"this",指向

  function Employee(context,arg1,arg2,arg3){
     context.arg1=arg1;
     context.arg2=arg2;
     context.arg3=arg3;
  }

所以function.call不会创建继承,因为它只是将属性复制到新的函数和对象,而不会强迫它沿着原型链走,所以你在重复你的自我,据我所知,它的唯一用途是从另一个函数复制参数。

如果我只是将Function.call与构造函数一起使用,也就是说,如果我只是简单地将值复制到一个新对象中,比如

  function Employee(){
       this.pay=' ';
       this.dept=' ';
   }
  function Manager(){
      Employee.call(this);
      this.reports=[];
  }
  //this works!!
 /*but all the objects created with Manager() will have all the properties   from Employee copied directly into it, and it doesnt walk the prototype chain to find them*/

根据我的理解,Object.create(function.protype(创建了一个新对象,因此它没有引用原始函数原型并创建继承,这就像我所期望的那样工作并创建继承

   var animal={
       moves: true
    }
   var snake = Object.create(animal);
       snake.noLeggs=true;
       snake.coldBlooded= true;
   var python= Object.create(snake);
       python.size='large';
    //if I were to type python.moves it would return true
   //but python doesn't have a property named pay so its walking up the prototype chain to find it

然而,这似乎不适用于构造函数,所以我有点困惑,不知道我做错了什么,也不知道function.protype=Object.create(superFunction.protype(的目的是什么;也就是说,你似乎不能使用从我的经验继承来创建原型链,例如,以下对我不起作用

  function Employee(){
       this.pay=' ';
       this.depth=' ';
  }
  function Manager(){
      this.reports=[];
  }
  Manager.prototype=Object.create(Employee.prototype);
  //however if I were to type var tom= new Manager(); tom.pay, pay would return "undefined"
  //so it appears I need Function.call()

所以在我看来,这什么都没做,那么我错过了什么,我做错了什么,如果我没有做错什么,目的是什么,我不明白什么?我能让它工作的唯一方法是使用Function.call,无论是否使用Function.protype=Object.create(super-Function.protype(;,但最好是走上原型链,这样代码就干了。

call允许您显式设置this

Employee.call(this);的目的是用所有Employee都具有的属性来扩展当前正在创建的Manager(this(。

虽然从某种意义上说,您是继承属性,但这部分与JavaScript的原型继承无关。这只是实现这一目标的一种巧妙方法:

function fillEmployee( employee ){
  employee.pay=' ';
  employee.dept=' ';
}
function Employee(){
  fillEmployee(this);
}
function Manager(){
  fillEmployee(this);
  this.reports=[];
}

然而,这似乎不适用于构造函数,所以我是有点困惑于我做错了什么或目的是什么function.protype=Object.create(superfunction.protype(;对于以下示例对我来说不适用

function Employee(){
  this.pay=' ';
  this.depth=' ';
}
function Manager(){
  this.reports=[];
}
Manager.prototype=Object.create(Employee.prototype);
//if I were to type Manager.pay it would return undefined

首先,如果您打算将Manager.pay用作构造函数,则不应该直接访问它。其次,这里缺少call部分,这就是实例没有pay和depth属性的原因。

下面是一个工作示例:

function Employee() {
  this.pay = ' ';
  this.depth = ' ';
}
function Manager() {
  Employee.call(this);
  this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
var peter = new Manager();
console.log(peter.pay);

最后为了CCD_ 9的目的。

注意,如果你直接分配原型,前面的例子会起作用,比如这个

Manager.prototype = Employee.prototype;

这基本上就是你想要实现的——每当Manager的实例找不到自己的属性时,它应该在Employee的原型中寻找它。

一旦您开始扩展Manager的原型,问题就会出现。假设您想为管理者添加一个函数fireEmployee。通常你会做

Manager.prototype.fireEmployee = function(){ ... }

但是你的CCD_ 14和CCD_。没有办法只向其中一个添加属性,而不对另一个不产生影响。

这就是您使用Object.create的原因。您创建了一个空对象,该对象将存储所有特定于管理者的扩展,该对象的原型是Employee.prototype