当我们声明一个函数fun时,函数fun具有的属性、方法如下:
// 属性(常见) 1.name 2.length 3.arguments(对象,arguments.callee) 4.caller 5.this 6.prototype 7.[[prototype]]
// 方法(常见) 1.call() 2.apply() 3.bind() 4.toString()
由于经常使用this对象,加之this指向常常容易混淆,所以有必要梳理下;关于this指向,应记住这句话:
哪个对象(上下文)调用了函数,这个函数中的this就指向谁;如果没有对象调用,this默认指向window(非严格模式下);
this的指向跟函数在哪个作用域定义没有任何关系;只跟谁调用了它有关;
var name = "hello outSide"; var obj = { name: "hello inSide", getInfo: function(){ console.log( this ) // @1 obj function A(){ console.log( this ) // @2 window } A(); setTimeout(function(){ console.log( this ) // @3 window },1000) } }; obj.getInfo();
当obj.getInfo()执行时,是obj对象调用了getInfo();
@1 函数执行到这里时,由于obj调用了getInfo(),因此this指向obj
@2 在执行此处时,没有对象调用A函数,默认情况下this指向window(非严格模式下,严格模式时指向undefined)
@3 执行此处时,定时器中this指向window(不管是严格还是非严格模式下,定时器中回调函数都指向window)
如果有时候编写闭包的方式不同,不容易分辨this指向;
var name = "hello outSide"; var obj = { name: "hello inSide", getInfo: function(){ return function(){ console.log( this ) } } }; obj.getInfo()();
此时控制台打印的结果是:“window”,原因是,执行obj.getInfo()返回一个函数,然后再执行这个匿名函数,由于没有任何对象调用这个函数,因此默认情况下this指向window;
再来看一个例子:
var name = "hello outSide"; var objOne = { name: "hello objOne", getInfo: function(){ return objTwo; // 这里返回的是objTwo对象 } }; var objTwo = { name: "hello objTwo", getInfo: function(){ console.log(this) } }; objOne.getInfo().getInfo();
控制台打印的是 objTwo 对象;
首先: 执行objOne.getInfo()时,返回的是objTwo对象
接着:objTwo对象调用了getInfo函数,因此this指向objTwo对象
定时器回调函数、事件处理程序中的this
默认情况下,定时器回调函数中的this指向window对象(浏览器中);事件处理程序中的this指向DOM对象;
// 定时器 回调函数 this-->window setTimeout(function(){ console.log(this)// window },1000) // 事件处理函数 this document.addEventListener('click',function(){ console.log(this) // DOM 对象 })
参考:
[1] 别再为了this发愁了
[2] 掌握JS中的this