js(七)---关于this的问题
来源:互联网 发布:淘宝官方店都是正品吗 编辑:程序博客网 时间:2024/06/05 05:09
今天对this的指向做一下了解吧,好好学习一下这个问题,在平时中,这个问题很常见的。
1.全局变量默认挂载在window对象下
var a = 2;console.log(window.a)//=>2(function(){ b = 3 } ())console.log(window.b)//=>3
在全局下直接定义一个变量,还有在立即执行函数中没有定义变量也是挂载在全局下的,但是他们有些不同,之前也说过了,没有定义的变量可以删除掉,定义过的变量删除不了。
2.正常的函数中,this指向它的直接调用者。
function(){ console.log(this); } test();//=>相当于window.test(),所以指向window var obj = { say: function(){ console.log(this) } } obj.say()//=>obj
上面两个例子可以说明这个问题,一般单独调用的时候,这个时候window会省略掉。
3.call/apply来改变this指向
function person () { this.name = 'si'; console.log(this);}person(); // windowvar obj = {};person.call(obj); // Object {name: "si"}
我们可以看到,当使用了call方法之后,person函数内部的this就指向了我们传递的这个对象。现在这个函数就可以为obj来赋属性值了。
如果这个函数还有参数的话,我们只要把实参的值写在call后面并且用逗号间隔开就可以了。
function person(name, age) { this.name = name; this.age = age;}var obj = {};person.call(obj, 'si', 18);console.log(obj.name); // si
apply和call基本没有区别,唯一的区别是call后面的参数是一个一个传的,而apply后面的参数是放进一个数组里面然后传进去的。
还是上面那个例子,如果用apply来传递实参的话,将是下面这种形式。
person.apply(obj, ['si', 18]);
由于匿名函数、定时器中的函数没有默认的宿主对象,所以指向window。
var obj = { say: function(){ setTimeout(function(){ console.log(this) })}}obj.say()//=>window
如果想要在setTimeout/setInterval中使用这个对象的this引用,那该怎么办呢?
1. 用一个变量吧this保存起来,that = this保存我们需要的this指向,当使用的时候再去调用它。
2. function.bind(this) 给回调函数直接绑定宿主对象,bind绑定宿主对象后依然返回这个函数;
var obj = { say: function(){ setTimeout(function(){ console.log(this) }.bind(this))}}obj.say()//=>obj
接下来的例子来感受一下this指向:
var a = 1; var obj = { a : 2, say : function(){ this.a *= 2; a *= 2; console.log(a) console.log(this.a) } } obj.say(); var run = obj.say; run();
结果是:
2 4 8 8
那么就分析一下,到底是为什么?
obj.say();这个this指向是obj, this.a = 2; obj里面的a就会变成4,并保存下来。 a = 2;这个相当于window.a *= 2,所以window下的a就会变成2。
接下来,run = obj.say、 run(),这时候this指向是window,所以 this.a *= 2,这时候window下的啊变成4,a *= 2
;同样也是window下,这样window下的a就变成了8。
这就是对这题的分析。
接下来再享受一个例题:
var name = '222';var a = { name:‘111’, say:function () { console.log(this.name); }}var fun = a.say;fun(); // 222a.say(); // 111var b = {name: '333',say: function (fun) { fun(); }}b.say(a.say); // 222this-->b;fun();b.say = a.say;b.say(); // 333
这就留着自己去分析吧,如果这两题整明白的话,那么你的this指向就没有问题了。