曾经我以为我掌握了this,直到不断学习,才发现真是个无知...
在前面的系列中我们已经知道,当函数被调用执行时,变量对象会生成,这个这时候,this的指向会被确定。因此我们首先要牢记一个非常重要的结论,当前函数的this是在函数被调用执行的时候才确定的。如果当前的执行上下文处于函数调用栈的栈顶,那么这个时候变量对象会变成活动对象,同时this的指向确认。
正是由于这个原因,才导致一个函数内部的this到底指向谁是非常灵活且不确定的,这也是this难以被真正理解的原因所在。例如,下面的例子,同一个函数由于调用的方式不同,它内部的this指向了不同的对象。
var a = 10;
var obj = {
a: 20
}
function fn() {
console.log(this.a);
}
fn(); //10
fn.call(obj);//20复制代码
通过a值的不同表现,我们可以知道this分别指向了window与obj。
接下来,我们一步步来分析this中的具体表现。
1. 全局对象中的this
在之前变量对象的笔记中曾提到过,全局对象的变量对象是一个比较特殊的存在。在全局对象中,this指向它本身,因此相对简单,没有那么多复杂的情况需要考虑。
//通过this绑定到全局对象
this.a1 = 20;
//通过声明绑定到变量对象,但在全局环境中,变量对象就是它本身
var a2 = 10;
//仅仅只有赋值操作,标识符会隐式绑定全局对象
a3 = 30;
复制代码
2. 函数中的this
在一开始的例子中,同一个函数中的this由于调用方式不同导致this指向不同,因此,this最终指向谁,与调用该函数的方式息息相关。
在一个函数的执行上下文中,this由该函数的调用者提供,由调用函数的方式来决定其指向。
function fn() {
console.log(this);
}
fn(); //fn为调用者复制代码
如果调用者被某一个对象所拥有,那么在调用该函数时,内部的this指向该对象。如果调用者函数独立调用,那么该函数内部的this则指向undefined。但是在非严格模式中,当this指向undefined时,他会自动指向全局对象。
//为了能够准确判断,我们在函数内部使用严格模式
//因为非严格模式会自动指向全局
function fn() {
'use strict';
console.log(this);
}
fn(); //fn是调用者,独立调用,this为undefined
window.fn(); //fn是调用者,被window所拥有,this为window对象复制代码
函数是独立调用,还是被某个对象所拥有,是非常容易辨认的。综合上面的结论,下面结合一些简单的例子来分析。
//demo01
var a = 20;
var obj = {
a: 40
}
function fn() {
console.log('fn this: ',this);
function foo() {
console.log(this.a)
}
foo();
}
fn.call(obj);
fn();复制代码
算了,不写了..................................................
越写下去,发现自己记录的这些,还不如'饥人谷方应杭'说的一句话:this 就是 call 的第一个参数!call 的其他参数统称为 arguments。
当你明白了方方说的,call/apply/bind都不是问题了...
这些都是我以往的学习笔记。如果您看到此笔记,希望您能指出我的错误。有这么一个群,里面的小伙伴互相监督,坚持每天输出自己的学习心得,不输出就出局。希望您能加入,我们一起终身学习。欢迎添加我的个人微信号:Pan1005919589