JS中的this指的是什么?
JS中的this的含义非常多,可以是全局变量,当前对象,或者任意对象,这取决于函数的调用方式
无论怎么变,但是有个总的原则,this指的是调用函数的那个对象
JS函数的调用形式
JS(ES5)里面有三种函数调用形式:
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2) // 先不讲 apply
一二两种形式其实是第三种调用形式的语法糖,等价于
func.call(undefined, p1, p2)
obj.child.method.call(obj.child, p1, p2)
所以第三种形式才是JS的正常的调用形式,套用这种形式理解this就容易多了,this就是指的上面代码中的context
作为函数调用或者对象方法调用中的this
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
通过上一节的函数的调用形式来理解
(1) 先来看看bar()的结果是window
bar() 等价于
bar.call(undefined)// 可以简写为 bar.call()
按理说this应该是undefined啊,是这样的,浏览器里有一条规则
如果你传的 context 是 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)
所以bar() 打印出的 this 是 window,如果不想是window,很简单
bar.call(obj) // 那么里面的 this 就是 obj 对象了
(2) 再来看obj.foo()结果就更容易理解了
obj.foo() 等价于
obj.foo.call(obj)
所以obj.foo()打印出的 this 是 obj
(3) 上面两种形式已经会转换成func.call(context, p1, p2)形式了,那么看看下面这种[ ] 语法怎么转换
function fn (){ console.log(this) }
var arr = [fn, fn2]
arr[0]() // 这里面的 this 又是什么呢?
将arr[0]( )想象为arr.0( ),虽然后者的语法错了,但是形式容易转换
arr.0.call(arr)
那么里面的this就是arr了
setTimeout、setInterval中的this
document.addEventListener('click', function(e){
console.log(this); //this指的是document
setTimeout(function(){
console.log(this); //this指的是window
}, 200);
}, false);
setTimeout、setInterval中的this指的是window
作为构造函数调用中的this
var _this1, _this2, _this3, this4
function person(name, age){
this.name = name
this.age = age
_this1 = this
}
person.prototype.printName = function(){
_this2 = this
}
function male(name, age, sex){
person.call(this, name, age)
this.sex = sex
_this3 = this
}
male.prototype = Object.create(person.prototype)
male.prototype.printSex = function(){
_this4 = this
}
male.prototype.constructor = male
var m = new male('hsc', 25, 'man')
m.printSex()
m.printName()
console.log(_this1 === m) //true
console.log(_this2 === m) //true
console.log(_this3 === m) //true
console.log(_this4 === m) //true
var p = new person('Li',30)
p.printName()
console.log(_this1 === p) //true
console.log(_this2 === p) //true
从上面的例子可以看出,构造函数中的this,无论是构造函数上的,还是原型链上的,指的都是通过该函数构造出来的那个实例对象
DOM对象绑定事件中的this
document.addEventListener('click', function(e){
console.log(this); //document
}, false);
在事件处理程序中的this指代的是绑定事件的DOM对象
值得注意的是: jquery的事件代理中的this,jquery事件代理中的this指的的点击的DOM元素,而不是绑定事件的DOM元素,这点与原生JS相反
jquery
$('ul').on('click', 'li', function(){
console.log(this)//点击每个li,显示的结果是每个li
})
原生JS
document.querySelector('ul').onclick = function(){
console.log(this)//点击每个li,显示的结果都是ul
}
最后,this也是可以改变的,改变this的方法见下一篇改变this的方法