this
的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this
到底指向谁,实际上this
的最终指向的是那个调用它的对象(在非严格模式情况下), 如果函数的调用者不存在,那么它的调用者将会是全局window对象
1. 全局环境中
1 | console.log(this) // window |
2. 事件处理函数
DOM 事件处理函数
1
2
3
4
5
6
7box.onclick = function () {
// 事件处理函数中的this指向触发该事件的元素
console.log(this); // div
(function(){ // 函数自调用 this指向window
console.log(this) // window
})()
}
内联事件处理函数
1
2
3
4<!--当代码被内联处理函数调用时,它的this指向所在的DOM元素(即div) -->
<div id="box" onclick="console.log(this)">div</div>
<!--当代码被包括在函数内部或自执行函数内时指向window -->
<div id="box" onclick="(function(){ console.log( this ) }) ()">div</div>
3. 函数内部
- 函数直接执行
非严格模式下 this默认指向全局对象window
1
2
3
4
5
6// 非严格模式下 函数执行, 如果没有明确指定执行的主体, this统一指向window
function test () {
console.log(this)
}
test() // window
window.test() // window
严格模式下 this为undefined
1
2
3
4
5
6function test () {
// 开启严格模式
console.log(this)
}
test() // undefiend
window.test() // window
- 自执行函数(自调用函数表达式),
this
默认指向window
1 | !function(){ |
- call bind apply 改变函数体内部this指向
apply call 都会使该函数立即执行,bind不会立即执行,而是返回一个新函数
call 函数.call(obj,arg1,arg2)
会直接调用该函数且第一个参数就是函数执行时的this,后面的参数可有多个
1 | function test (m, n) { |
apply 函数.apply(obj,[arg1,arg2])
会直接调用该函数且第一个参数是函数执行的this,后面是一个数组,执行时会将数组变成参数列表
1 | function test (m, n) { |
- 借助
call apply
去使用Math
或Array
的方法案例
1 | console.log(Math.max.apply(null, [2, 9, 5])); // 9 |
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样
bind 函数.bind(obj)
创建一个新函数,并不会立即调用,但只能绑定一次
1 | function test () { |
箭头函数 =>
与定义时环境上下文中this
一致 ,不能用bind,call,apply
修改其内部指向,没有arguments
对象
1 | var fn = () => { |
1 | box.onclick = function () { |
- apply、call、bind比较
1
2
3
4// apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
// apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
// apply 、 call 、bind 三者都可以利用后续参数传参;
// bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
4. 对象内部
- 函数作为对象的方法调用
1 | // 作为对象的方法调用 this指向调用该函数的对象 |
1 | var a = 1 |
- 多层嵌套的对象
this
就近绑定
1 | var a = 1 |
- 函数作为返回值使用
1 | var a = 1 |
- 函数或方法被赋值于变量时 this指向这个变量的拥有者
1 | var tew = '111' |
5. 构造函数中
1 | function Person () { |
6. 原型链中
1 | // 原型链中的this指向调用它的对象 |