function foo(x,y){
console.log(x,y,this);
}
//call的第一个参数是指想作为this的对象,如果不是对象会转成对象,所以100转为了Number(100)
foo.call(100,1,2);// 1,2,Number(100)
//call与apply的区别在于call的传参扁平化,而apply以数组的形式传入
foo.apply(100,[1,2]);// 1,2,Number(100)
foo.apply(true,[1,2]);// 1,2,Boolean(true)
//此处若传入null或undefined,这里的this就会指向全局对象,在浏览器中就是window
foo.apply(null);// undefined,undefined,window
foo.apply(undefined);// undefined,undefined,window
bind 方法属于ES5才提供的方法,在IE9及以上才支持
this.x=9;
var module={
x:81,
getX:function(){
return this.x;
}
}
/*
调用对象的属性方法,this指向的是module,
所以this.x为module中x的值,即为81
*/
module.getX();// 81
/*
将对象的方法赋值给变量getX,再通过getX()调用,
此时的this指向的全局对象,因此返回的是9
*/
var getX=module.getX;
getX();// 9
/*
通过bind方法可以改变函数中的this,将module绑定为this,
在通过boundGetX()去调用,此时this指向的是module对象,
所以this.x为module中的x,即为81
*/
var boundGetX=getX.bind(module);
boundGetX();// 81
利用bind实现柯里化
function add(a,b,c){
return a+b+c;
}
/*
不改变this指向,传入undefined或者null均可
100会赋值给第一个参数a,相当于a=100
因此func(1,2)=a+b+c=100+1+2=103
*/
var func=add.bind(undefined,100);
func(1,2);// 103
/*
对func再次bind,a已经被绑定,200会赋值给b,相当于b=100
因此func(10)=a+b+c=100+200+10=310
*/
var func2=func.bind(undefined,200);
func2(10);// 310
bind与new
上面我们可以知道bind可以改变this的指向,但是如果bind遇到new结果又会有什么不一样呢?
var a=200;
function foo(){
this.b=100;
return this.a;
}
/*直接调用函数,this指向的是全局对象,所以this.a=200*/
console.log(foo());// 200
/*通过bind改变了this指向,此时this指向的是作为参数传入的对象,所以this.a=1*/
var func=foo.bind({a:1});
console.log(func());// 1
/*这里通过new func()调用,如果是new的话除非返回的是对象,如果不是就会把this作为对象返回,并且this会被初始化为一个空对象,这个对象的原型是foo.prototype。
在这种情况下,即使有bind,此时的this还是会指向没有bind的对象,这个对象的原型是foo.prototype,这个对象有个b的属性,其值为100,然后作为整个对象返回*/
console.log(new func());// {b:100}
网友评论