Javascript中call()方法和apply()方法的作用与区别
ECMAScript规范所有函数都包含两个非继承的方法,分别为call()和apply(),这两个函数都是在特定的作用域中调用函数,能改变函数的作用域,实际上是改变函数体内“this”的指代的对象。
call(thisObject[,arg1,arg2,arg3...]):
释义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:call方法可以用来代替另一个对象调用一个方法,call方法将一个函数对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObject参数,那么Global对象被用于thisObject。
apply(thisObject[,argArray])
释义:调用对象的一个方法,另一个对象替换当前对象。
说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个
TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。
二者区别:
两者传递的参数不同,call传递的参数时一一列举出来的,apply传递参数形式是数组。
二者作用:
1、调用函数,传递参数
function add(x, y) { return x + y; } function myAddCall(x, y) { return add.call(this, x, y); } function myAddApply(x, y) { return add.apply(this, [x, y]); } console.log(myAddCall(10, 20)); //输出结果30 console.log(myAddApply(20, 20)); //输出结果40
2、改变函数的作用域
var name = 'Lilei'; var obj = {name:'Hmm'}; function Student() { return this.name; } console.log(Student.call(this)); //输出Lilei console.log(Student. call(obj)); //输出Hmm
3、模拟java中类的继承
function Flyer(fname,speed){ this.fname=fname; this.speed=speed; this.fly=function(){ console.log(this.fname+"以时速:"+this.speed+"飞行");//如果用到父对象的构造方法,构造方法不能放到原型对象中,因为子类型的__proto__与父类型的prototype无关 } } function Plane(fname,speed,capacity) { this.capacity=capacity; Flyer.call(this,fname,speed); delete this.fly;//如果父类型中有与之同名的构造函数,则需要先删除父对象中的构造函数 this.fly=function(){ console.log(this.fname+"搭载"+this.capacity+"名乘客以时速:"+this.speed+"飞行"); } } var A380=new Plane("A380",1000,555);