每个作用域里面都绑定了一个特别的值叫 this ,具体 this 表示的是什么要看函数是怎么被执行的。
this 翻译成中文就是“这…”,它本身并没有特殊的意义,它的意义完全取决于你在什么情景下使用它。比如你在跟朋友讨论一部电影:《Brother》,“这部电影是北野武的一部作用”,在这句话里,这(this),指的就是《Brother》这部电影。如果是在另一种语境下,这个 this 表示的可能是完全不同的意思。
在 JavaScript 里面,this 表示的东西也是要看所处的语境(context),也可以说上下文,情境,环境 …
情形一
在全局作用域的下面,this 一般表示的是 window 对象。打开浏览器的控制台,输入:
this
会返回 window 对象里的东西。
Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}
在全局作用域下定义一个变量,你可以在这个 window 对象里得到。试一下:
var name = '小猫'
this.name // '小猫'
window.name // '小猫'
情形二
再试一下:
var robot = function() {
console.log(this)
}
robot()
在定义的函数里面输出 this ,同样会得到一个 window 对象。但是如果代码使用了 ‘use strict’ ,像这样:
'use strict';
var robot = function() {
console.log(this)
}
robot()
返回的会是:undefined
再试一下:
var robot = {
greet(){
console.log(this)
}
}
robot.greet()
// this 表示的是 greet 方法所属的 robot 对象
robot 是个对象,里面有个 greet 方法,在这个方法的里面,this 表示的是方法所属的对象,这里 this 表示的就是 robot 这个对象。
情形三
假设页面上有个元素:
<button id="signup">订阅</button>
我的代码像这样
var signupButton = document.querySelector('#signup')
var signupLog = function() {
console.log(this)
}
signupButton.addEventListener('click', signupLog, false)
点击了页面上的 “订阅” 按钮,会在控制台上输出在 click 事件处理器,也就是 signupLog 函数里的 this 所表示的东西,这里 this 表示的是发生 click 事件的那个 button 元素。
情形四
这次 this 出问题了:
var signupButton = document.querySelector('#signup')
var signupLog = function() {
console.dir(this) // this 是发生 click 事件的元素
setTimeout(function () {
console.log(this) // this 表示的是 window 对象
}, 1000);
}
signupButton.addEventListener('click', signupLog, false)
这次在 signupLog 里的 setTimeout 里的 this 指的是 window 对象。想让这里的 this 表示发生 click 事件的元素,可以这样:
var signupButton = document.querySelector('#signup')
var signupLog = function() {
var _this = this
console.dir(_this)
setTimeout(function () {
console.log(_this);
}, 1000);
}
signupButton.addEventListener('click', signupLog, false)
改变 this 的值
call(),apply(),bind() ,这些方法都可以改变 this 表示的值。
var robot = function() {
console.log(this)
}
robot.call('hello')
// this 的值是 hello
call() 与 apply() 的用法:
.call(thisArg, arg1, arg2, arg3)
.apply(thisArg, [arg1, arg2])
参考资料
https://developer.mozilla.org/en/docs/Web/JavaScript/Closures
https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/
文章评论(0)