js中this的指向性问题
现在已经 1202 年了,大家大多都富裕,能够用上 ES6 新特新了,所以对于this 的指向
问题也没有 ES5 时期关注了;再者,一般的开发过程中对于函数或者作用域的层级也没有嵌套太深,所以也不常遇到因为 this 指向不明产生的错误。常在河边走哪能不沾水,接触的项目多了,难免会遇到一些老代码,最好能够了解一下 this 的指向;再退一步说,面试中 this 指向可是避不开的点!但是,看到这篇文章只需要记住一句话就能解决所有 this 指向问题——this 永远指向它的左邻调用对象!
一、单层嵌套 this 指向
//浏览器环境 var name = "outer windows"; function a() { var name = "inner function"; console.log(this.name); console.log("inner:" + this); } a(); console.log("outer:" + this)
输出结果为:
outer windows inner:[object Window] outer:[object Window]
观察结果,在函数 a()中即使定义了name
变量,输出this.name
时显示的是外层定义赋值的outer windows
,从这里我们不难看出此时函数 a()中的this
实际上是代表了外层的作用域(该实例中也就是顶层作用域 window);依次在函数内部和外层对this
输出,指向同一个对象 window
。
回过头再看开篇的一句话:this 永远指向它的左邻调用对象!;该实例代码中函数 a()在哪里调用,它的左邻又是什么对象呢?我们对代码进行简单转化:
//浏览器环境 var name = "outer windows"; function a() { var name = "inner function"; console.log(this.name); console.log("inner:" + this); } //a()调用变形 this.a(); // 等价于 Window.a() console.log("outer:" + this)
注意:前面没有调用的对象那么可以默认就是全局对象 this/window
,这就相当于是 this/window.a()
;
二、多层嵌套 this 指向
1、形式一
//浏览器环境 var name = "outer windows"; var a = { name: "1 inner function", fn : function () { var name = "2 inner function" console.log(this.name); } } a.fn();
输出结果为:
1 inner function
这个结果和你想象的是不是一样的呢?如果你也是这个答案,那么你对 this 永远指向它的左邻调用对象 这句话应该是有了一定理解!同样,我们对上述实例进行解析:最后的函数调用为a.fun()
变形后等价于window.a.fn()
,函数 fn 的最左调用对象为对象 a,所以函数fn
中的this
指向其最左的对象 a,故this.name
为对象 a 的name
属性值。
2、形式二
//浏览器环境 var name = "outer windows"; var a = { name: "1 inner function", fn : function () { var name = "2 inner function" console.log(this.name); } } var b = a.fn; b();
输出结果为:
outer windows
小朋友,你是不是有好多问好???相较于形式一,该实例中要区分下变量赋值和函数执行两个概念!分析该实例代码:var b = a.fn;
实际执行的操作是声明全局变量 b,并对 b 进行赋值,赋值为a.fn
,也就是说此时 b 的值实际上是指向
function () { var name = "2 inner function" console.log(this.name); }
当代码执行到b()
时才是对上述函数进行了调用执行,同样我们对代码进行补充完整:this/window.b()
,this 永远指向它的左邻调用对象,此处指向的就是 window,其name
的属性值为outer windows
;为了验证 b 的实际值,我们不妨对其进行输出:console.log(b)
:
3、形式三
//浏览器环境 var name = "outer windows"; function fn() { var name = '2 inner function'; a(); function a() { var name = "2 inner function" console.log(this.name); } } fn()
输出结果为:
outer windows
看完形式一和形式二是不是觉得根据 this 永远指向它的左邻调用对象,自己对this
指向已经了如指掌了!但是看到形式三的例子是不是又有点迷糊!其实一切都离不开this
永远指向它的左邻调用对象这句话;对上述代码进行分析:fn()
等价于this/window.fn()
所以此时fn
中的this
指代的是window
,在函数 fn 中又立即调用执行了其作用域中定义的函数 a,此时 a 中的 this 指向函数 fn,前面提到 fn 的 this 其实是指向 window;所以 a 中的 this 其实是指向 window 的,可以简化为伪代码window.fn().a()
,符合 this 永远指向它的左邻调用对象!
4、形式四
//浏览器环境 var name = "outer windows"; function a() { var name = "2 inner function" console.log(this.name); } function fn() { var name = '2 inner function'; a(); } fn()
输出结果为:
outer windows
对于形式四大家可以自己进行分析下!
三、总结
无论代码中有多少层的且套,我们都可以运用 this 永远指向它的左邻调用对象进行分析得到正确的this
指向!最后再重申:this 永远指向它的左邻调用对象 !this 永远指向它的左邻调用对象!this 永远指向它的左邻调用对象!
码云笔记 » js中this的指向性问题