在JS的方法编写中我们总是会不停的用到关键词this,而this的指向总是会随着需求的改变而变化。
function sayHi(){
this.a = 1;
console.log(this.a); //1
}
console.log(window.a + 1); //2
sayHi();
console.log(window.a); //1
console.log(a); //1
sayHi()方法是全局变量window下的一个方法,而a也没有局部生命,从结果可以看出,this的指向的是window。
var person = {
name:"jack",
age:23,
func:function(){
console.log("He is "+this.name + " and his age is "+this.age); //He is jack and his age is 23
console.log(person=== this); //true
}
}
person.func();
func()方法是person对象的一个内部函数,调用这个方法必然会引用这个对象,因此函数中的this都指向生成它的person对象。
为什么要改变this的指向呢?我举个例子:A对象有一个方法,而B对象因为某种情况也需要用到一样的方法,那么这时候我们是单独为B扩展个方法呢,还是借用一下A的方法呢?如果我们为B对象也写一个同样的方法是否会让代码变得很平淡,而且会浪费内存?所以改变this的指向在这里变得尤为重要。
call()与apply()
call语法:function.call(obj[,arg1[, arg2[, [,.argN]]]]])
apply语法:function.apply(obj[,argArray])
call()与apply()的方法作用相同,它们的区别只在于接收参数的方式不同。对于call()来说第一个参数是this(即指向的对象),第二个及以后的参数必须与传递函数的参数个数类型一致,而apply的第二个参数必须是数组或者类数组(即arguments对象)。
function func(name1,name2){
return name1 + name2;
}
console.log(func.apply(this,[10,10])); //20(apply的数组参数)
console.log(func.apply(this,{0:10,1:20,length:2})); //30(apply的arguments对象参数)
console.log(func.call(this,10,30)); //40(call的函数对应参数)
科普一下类数组,类数组就是和json对象差不多的格式,不过类数组的下标对于json的属性,后面同为值,不同的是类数组最后有个length属性,记录类数组大小。
{
0:10,
1:20,
length:2
}
以下也为这两个方法的使用:
1.使用apply和call函数来进行判断类型:Object.prototype.toString.call(value);
2.继承:在子类中调用父类方法实现。Super.call(this,”111”,23);
3.向类数组中添加数据:Array.prototype.push.call(argument,”name”);
4.将数组合并:Array.prototype.push.apply(arr1,arr2);
5.将具有length的类数组转换成数组:Array.prototype.slice.call(arguments);