javascript中的call.apply方法是针对function本身定义的内容,并不能将
Posted Andrés
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript中的call.apply方法是针对function本身定义的内容,并不能将相关的知识,希望对你有一定的参考价值。
最近研究了js的继承,看了幻天芒的文章http://www.cnblogs.com/humin/p/4556820.html#3947420,明白了最好是使用apply或call方法来实现继承。
已知,call可以将function里的属性(所谓构造属性)赋给子类;但是对于call能不能将function的prototype内容(所谓的原型属性)一同复制,有疑惑,实验之后发现是不行的。看下面的代码:
g()是f()的原型中的方法。
c是f子类e的一个实例,ff是f的一个实例。
ff.g()系统不报错,正常运行,c.g()系统是报错不识别,不认为其是一个函数。
结论:e没有继承父类f的原型属性。
function f(){ this.a ="a"; this.b = function(){ console.log("b"); } /* this.g = function(){ console.log("this is g in f()."); } */ } f.prototype.g = function(){ console.log("this is g in prototype."); } function e(){ f.call(this); } var c = new e(); console.log(c.a); //弹出a c.b(); //弹出b var ff = new f(); ff.g();//this is g in prototype. c.g();//c.g is not a function
如果要实现对f的完全继承,还需要复制其原型链中的内容。参考以下代码:
function f(){ this.a ="a"; this.b = function(){ console.log("b"); } } f.prototype.g = function(){ console.log("this is g in prototype."); } function e(){ f.call(this); //f.prototype.call(this); } ( function(){ var Super = function(){}; Super.prototype = f.prototype; e.prototype = new Super(); } )(); e.prototype.constructor = e; //重新修复下构造函数 var c = new e(); console.log(c.a); //弹出a c.b(); //弹出b var ff = new f(); ff.g();//this is g in prototype c.g();//this is g in prototype
总结,f.call(this);只能将f的实例属性赋给e,原型属性需要使用别的方法复制过去。
另外,我又在chrome下最后使用代码:
console.log(c);
打印了一下实例c。看到如下内容:
a,b都好理解。a是父类f的一个实例属性,b是父类f的一个实例方法。e都继承了下来。可是问题来了:
__proto__是什么呢?
e继承的父类f的原型方法g()去哪里了呢?
回答以上问题,先看一看js对于__proto__的定义和解释:
即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。
现在我们来分析,实例c是e对象生成的,e的构造函数的原型(即e.prototype)是f。再点开来看:
__proto__.constructor = e(); 这个不就是我们设置的吗----》e.prototype.constructor = e; __proto__.__proto__.g = function 这个是构造函数原型的构造函数的原型,即f的构造函数原型,即f的原型链。g不就是f原型链中的方法吗。 所以,e继承的父类f的原型方法g()在这里。原来,使用c.g()时候,程序会一直沿着__proto__往前面的原型找。
以上是关于javascript中的call.apply方法是针对function本身定义的内容,并不能将的主要内容,如果未能解决你的问题,请参考以下文章
javascript中的call.apply方法是针对function本身定义的内容,并不能将
JavaScript中的call()apply()与bind():
javascript中的call(),apply(),bind()方法的区别