繁体   English   中英

有人可以向我解释function.prototype.call()和function.prototype = Object.create()吗?

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

我了解如何编写适当的继承,但是我正在尝试确切地了解编写本文时的工作,因此我完全理解了我的代码。 我已经阅读了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.prototype)创建一个新对象,因此它不引用原始函数原型并创建继承,它可以像我期望的那样工作并创建继承,它沿原型链走而不会复制属性变成新对象

   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.prototype = Object.create(super Function.prototype)的用途,我有些困惑。 那就是您似乎无法利用我的经验继承来创建原型链,例如以下内容对我不起作用

  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.prototype = Object.create(super function.prototype),它的工作方式似乎都是相同的,但是如果它走了,那将是更好的选择原型链,以便编码干燥。

call ,您可以明确设置什么this将是。

Employee.call(this); 是用所有Employee拥有的属性扩展当前正在创建的Managerthis )。

从某种意义上讲,您在继承属性,而这部分与JavaScript的原型继承无关。 这只是实现此目的的一种好方法:

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

但是,这似乎不适用于构造函数,因此对于我做错了什么或function.prototype = Object.create(super function.prototype)的用途,我有些困惑。 例如以下内容对我不起作用

 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); 

最后为了F.prototype=Object.create(Super.prototype);

请注意,如果直接分配原型,则上述示例将起作用,例如

Manager.prototype = Employee.prototype;

从本质上讲,这就是您要实现的目标-每当Manager的实例找不到自己的属性时,都应在Employee的原型中寻找它。

一旦开始扩展Manager的原型,问题就来了。 假设您要向经理添加功能fireEmployee 通常你会做

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

但是您的Manager.prototypeEmployee.prototype是同一对象。 没有办法只向其中一个添加属性,而对另一个不起作用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM