首先呢,我们知道return可以改变this指向
function Fn(name){ this.name=name; return {};//undefined,改变了this的指向,指向该未定义对象 } var fn=new Fn("maomin"); console.log(fn.name);
另一种是我们常用的方法,就是给将this赋值给一个变量。
function fn1(age) { var that=this; that.age=age; console.log(this.age)//21 } fn1("21");
但是上面的方法太low了。 接下来我们说一下关于改变this指向的三种高大上方法:
- call() (1)可以改变匿名函数this指向
var box=document.querySelector("#box"); box.onclick = function(){   (function(){     console.log(this); //box   }).call(this); };
(2)可以继承方法
function Fn8(name,girlfriend) { this.name=name; this.girlfriend=girlfriend; } function Fn9(name,girlfriend) { Fn8.call(this,name,girlfriend);//第一个传的是一个对象,就是你要借用的那个对象,除了第一个参数后面的参数将作为实际参数传入到函数中。 console.log(this.name,this.girlfriend);//maomin, xqm } var fn9=new Fn9("maomin","xqm");
(3)主动执行函数
function fnn() { var arr=[this.index,2,3] console.log(arr);//123 } var val={index:1}; fnn.call(val); //call就是挨个传值,apply传一个数组,bind也是挨个传值,但和call和bind还有多少不同,使用call和apply会直接执行这个函数,而bind并不会而是将绑定好的this重新返回一个新函数,什么时候调用由你自己决定。
2.bind() bind 的其中一个用法就是:绑定函数,使其无论怎么样调用都用相同的 this。
var obj={ ofn:function(){ console.log(this);//obj } } obj.ofn();
那如果这样呢 var ofn1=obj.ofn; ofn1();//然而这时,console.log(this);打印出来则是window。ofn1只是将obj对象中的方法复制过来,但是this指向变了。ofn1()可以看作成window.ofn1() 为了改变这种现状,可以用bind().
(1).
var objj={ ofnn:function(){ console.log(this); } } var oB=objj.ofnn; oB.bind(objj)();//ofnn
(2).
var obj = { num: 100, numFun: function(){ console.log(this.num);//100 } } var numFunCopy = obj.numFun; numFunCopy.bind(obj)(); var mName={name:"我是测试的值1"}; var nName={ name:"我是测试的值2", say:function(){ console.log(this.name);//我是测试的值1 }.bind(mName) } nName.say();
3.apply()
function f(x, y){ console.log(x + y); } f.apply(null, [1, 1]) // 2
apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined,则等同于指定全局对象。 第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。 原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。
var a = [24,30,2,33,1] Math.max.apply(null,a) //33 数组中最大值
总结:
- call 、 apply 、bind 均能改变this 指向
- apply 每次执行产生一个新函数,call、apply 不会
- call ,bind 接收多个参数绑定到函数,参数单一传入,apply 接收方式为数组