js call和apply
官方定义:调用一个对象的一个方法,以另一个对象替换当前对象。
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
classA.apply(classB,arguments); 自己的理解:classB继承了classA的属性和方法
我对js里面call和apply的理解是回调父类的方法,并将父类实例化到当前对象的prototype上。
其实对此一直都比较模糊,只能通过一些例子来加深一些理解。
源码
1 var color = "red"; 2 function sayColor(p) { 3 alert(p + this.color); 4 }; 5 sayColor();//弹出undefinedred; 6 var obj = new Object(); 7 obj.color = "blue"; 8 sayColor.call(obj, "color is ");//弹出color is blue 9 //sayColor.apply(obj, ["color is "]);
/*
第一次 调用sayColor 里面的this 的上下文是window 所以this.color = red;
第二次 sayColor.call(obj, "color is ");obj是传过去的上下文,"color is "是参数(可传多个)
所以当执行sayColor的时候 this就是obj,this.color = blue;
*/
源码
1 function ClassA(c) { 2 this.color = c; 3 this.sayColor = function () { 4 alert(this.color); 5 }; 6 } 7 8 function ClassB(c, n) { 9 ClassA.apply(this, arguments); 10 this.name = n; 11 this.sayName = function () { 12 alert(this.name); 13 }; 14 } 15 var objA = new ClassA("blue"); 16 var objB = new ClassB("red", "John"); 17 objA.sayColor(); //输出 "blue" 18 objB.sayColor(); //输出 "red" 19 objB.sayName(); //输出 "John"
/*
以上的例子 我们可以知道
1.apply方法 改变 ClassA的 this 传过去的this==ClassB ; arguments == [c,n]
2.ClassB继承了 ClassA的sayColor方法
在这里就有一个疑问了 这样的继承是否就跟prototype 一样呢?
*/
源码
1 function ClassA(c) { 2 this.color = c; 3 } 4 ClassA.prototype.sayColor = function () { 5 alert(this.color); 6 }; 7 function ClassB(c, n) { 8 ClassA.call(this, c); 9 this.name = n; 10 } 11 var objB = new ClassB("red", "cxy"); 12 objB.sayColor(); //运行报错 不存在这个方法
/*
由此可见ClassB并没有完全继承ClassA。
有一种解释是 call/apply 是继承实例对象,而prototype是继承原型对象。
更通俗一些是 call/apply 是值类型的继承,而prototype是引用类型的继承。
*/
给一个完整的例子
源码
1 Java代码 收藏代码 2 3 function ClassA(c) { 4 this.color = c; 5 } 6 ClassA.prototype.sayColor = function () { 7 alert(this.color); 8 }; 9 function ClassB(c, n) { 10 ClassA.call(this, c); 11 this.name = n; 12 } 13 ClassB.prototype = new ClassA(); 14 ClassB.prototype.sayName = function () { 15 alert(this.name); 16 }; 17 18 var objA = new ClassA("blue"); 19 var objB = new ClassB("red", "cxy"); 20 objA.sayColor(); //输出 "blue" 21 objB.sayColor(); //输出 "red" 22 objB.sayName(); //输出 "cxy"