一、JS中this总是指向调用某个方法的对象,但是我们可以使用call()或apply()来改变this的指向
1、call()方法
语法:object.call(obj, arg1, arg2...) //obj:这个对象将代替object类里this对象,params:这个是一个参数列表
应用:obj1.(method).call(obj2,argument1,argument2) //call的作用就是把obj1的方法放到obj2上使用,后面的argument1..这些做为参数传入
举例:
function add (x, y) {
console.log (x + y);
}
function minus (x, y){
console.log (x - y);
}
add.call (minus , 1, 1); //2
解析:实际上就是用 add 来替换 minus ,add.call(minus ,1,1) == add(1,1) ,所以运行结果为:2
2、apply()方法
语法:object.apply(obj, args) //obj:这个对象将代替Function类里this对象,args:是一个数组,它将作为参数传给object(args-->arguments)
举例:
/*定义一个人类*/
function Person(name,age) {
this.name = name;
this.age = age;
}
/*定义一个学生类*/
functionStudent(name,age,grade) {
Person.apply(this,arguments);
this.grade = grade;
}
//创建一个学生类
var student=new Student("gao", 18, "大一");
console.log("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
//name:gao age:18 grade:大一
解析:学生类里面没有给name和age属性赋值,为什么会存在这两个属性的值呢?Person.apply(this,arguments); 其中this:在创建对象时代表的是student,
arguments:是一个数组:也就是[“gao”, ”18”, ”大一”];
也就是用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象上面。
如果用call()方法实现的话就是 Person.call(this, name, age) 即可
二、apply()方法的妙用
1、从上面的分析可以看出,apply在传参时,第二个参数是一个数组,但是最后会解析称一个一个的参数。在JS中有一些方法实际上是不接收数组作为参数的,但是我们可以通过apply()方法进行改造一下,如:Math.max()方法,其参数里面不支持
Math.max([param1,param2])
只支持
Math.max(param1,param2,param3…)
通过apply()方法改造:
console.log(Math.max.apply(window,[1,2,55,33,22,99,100])); // 100
同理Math.min也可以这样做。
2、用 Array.prototype.push 可以实现两个数组合并,因为push()方法不接收数组作为参数,但是它接收多个参数(push(param1,param,…paramN)),因此改造后:
var arr1 = new Array("1","2","3");
var arr2 = new Array("4","5","6");
console.log(Array.prototype.push.apply(arr1,arr2)); // 返回的其实是数组长度 6
因此:一般在目标函数需要n个参数列表,而不接收一个数组的形式的时候([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙的进行改造