[英]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
拥有的属性扩展当前正在创建的Manager
( this
)。
从某种意义上讲,您在继承属性,而这部分与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.prototype
和Employee.prototype
是同一对象。 没有办法只向其中一个添加属性,而对另一个不起作用。
这就是为什么使用Object.create
的原因。 您创建一个空对象,该对象将存储所有特定于管理器的扩展,并且该对象的原型为Employee.prototype
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.