关键字this是什么?
用来表示一个上下文对象,用于“传递” 一个对象的引用。
观察以下例子,可以发现 add函数需要传递对象当作参数,而addNo函数仅需绑定对象,然后通过使用this就可以访问到对象内的属性。add函数这种显示传递上下文对象在复杂的模式中,也会导致混乱,反而使用this则不会这样。
function add(context) {
console.log(context.numA + context.numB);
}
function addNo(){
console.log(this.numA+this.numB)
}
var obj = {
numA: 1,
numB: 3
}
add(obj); // 4
addNo.call(obj); // 4
使用this时经常需要判断this是指向谁,经常有2个误解
1、误解一:指向自身this是否是指向函数本身呢?
我们可以从demo中找答案
function foo(i) {
console.log(`当前是:${i}`)
this.count++;
};
foo.count = 0;
(function main() {
for (let index = 0; index < 5; index++) {
foo(index);
}
})();
console.log(`count的值:${foo.count}`);
//运行得到的结果
当前是:0
当前是:1
当前是:2
当前是:3
当前是:4
count的值:0
Count的值是0,而不是5,因为执行道foo.count时是给函数对象foo增加了count属性,但是在for循环中执行foo(index),所指向的函数对象foo不是同一个;那怎么样才能让其指向同一个呢?
- 方法1:this.count++修改成foo.count++ 让其显示替代this来引用函数对象
- 方法2:foo(index)修改成foo.call(foo,index) ,通过绑定方式,强制让this指向函数对象foo
2、误解2:this指向函数的作用域
this在任何情况下都不指向函数的词法作用域
this到底指向谁?
This在运行时才进行绑定,所以在定义时this对指向谁是未知的,只有在运行时才能确认指向谁,且实际上this最终指向的是那个调用它的对象。
判断this,可以根据优先级来判断:
- 1、函数是在new中调用,是==this绑定的是新创建的对象 var foobj = new foo()
- 2、函数是通过call,apply(显示绑定)或硬绑定调用,是==this绑定的是指定的对象:var bar = foo.call(obj)
- 3、函数是否在某个上下文对象中调用(隐式绑定),是==》this绑定的是那个上下文对象 var bar = boj1.foo()
- 4、如果都不是,则使用默认绑定,严格模式(use strict)下绑定到undefined,否则绑定到全局对象
注意如果这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象