js 5.14 this的引用
5.14.1、this引用 的规则
在最外层的代码中,this引用的是全局对象
在函数内,this引用根据函数调用方式不同而有所不同
函数的调用方式this引用的引用对象
构造函数调用 | 所生成的对象 |
方法调用 | 接收方对象 |
apply或是call调用 | 有apply 或call的参数指定对象 |
其他的方式的调用 | 对象全局 |
通过点运算符或中括号运算符调用对象的方法时,在运算符左侧所指定对象
下面方法和接受对象的具体例子
var obj={
x:3,
doit:function(){
console.log("method is called"+this.x);
}
}
obj.doit();//method is called 3
obj['doit']();//method is called 3
首先是将对象的引用赋值给了变量obj。这个对象有两个属性,属性x的值是数值3,属性doit的值是一个函数,将该函数称为方法doit
可以通过点运算符或中括号运算符对obj调用方法doit。这时方法调用的目标的对象被称为接收方对象(也就是obj引用的对象是一个接收方对象)。被调用的方法内引用改接受方对象。
5.14.2 this引用的注意点接上面的例子继续
var fn=obj.doit; //将obj.doit引用的Function对象赋值给全局变量
fn(); //函数内this引用了全局对象
var x=5; //确认this 引用全局对象
fn() ;
var obj2={x:4,doit:fn};//将obj的方法(function对象的引用)赋值给了另一个对象obj2的属性
obj2.doit()//方法内的this引用对象obj2
var obj={
x:15,
doit:function(){
console.log(this);
console.log("doit is called"+this.x);
this.doit2(); //如果写成doit(),则会在全局中搜索doit,则会报错 doit2 is not defined
},
doit2:function(){
console.log("doit2 is called"+this.x);
}
}
obj.doit();
////var x=2;
function f(){
var x=1;
console.log(x);
console.log(this,this.x);
}
f();
打印一下this指向this指向window未定义,var x=2打开在打印this.x是2
在function对象中包含apply,call,bind这三种方法,通过他们调用的函数的this引用,可以指向特定的对象也就是说可以理解位
显示的指定接收对象
function f(){
console.log(this.x);
}
var obj={x:4};
f.apply(obj) //通过apply调用函数f。函数内this引用了对象obj
f.call(obj) //通过call调用函数f。函数内this引用了对象obj
console.log(f.bind());//返回一个函数所以bind,因此后面还需要()来进行调用才可以。
f.bind(obj)()
运行结果:
4
4
var m={
x:3,
doit:function(){
console.log('method is called'+this.x);
}
}
var obj2={x:5};
m.doit.apply(obj2);
运行结果:
method is called 5
对function对象f使用apply或call方法就能调用该函数。不考虑函数内的this引用的话,这和f()的用法是一样的。
两者的区别再调用的函数(方法)内的this的引用,this引用的是作为apply/call的第一个参数被传递的对象。而apple与call之间的不同之处在于两者在于其他的参数的传递方式。对于apply来说,剩余的参数将通过数组来传递,而call是直接按原样传递形参。请通过下面的具体的例子来了解这一差异。
function f(a,b){
console.log('this.x='+this.x+',a='+a+',b='+b);
}
f.apply({x:4},[1,2]); //作为第二个参数的数列中的元素都是函数f的参数
f.call({x:5},1,2) //从第2个参数起的参数都是函数f的参数
运行结果:
this.x=4,a=1,b=2
this.x=5,a=1,b=2
在一个例子:
var m={
x:3,
doit:function(a,b){
console.log('method is called'+this.x+',a='+a+',b='+b);
}
}
var obj2={x:5};
m.doit.call(obj2,1,2);
m.doit.apply(obj2,[1,2]);
console.log(m.doit.bind());//但是由于bind返回的仍然是一个函数,所以我们还可以在调用的时候再进行传参。
m.doit.bind(obj2,1,2)();
m.doit.bind(obj2)(1,2);