Javascript 之 this 关键字

2018 年 10 月 4 日 0 条评论 2.8k 次阅读 0 人点赞

每个作用域里面都绑定了一个特别的值叫 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)

(Spamcheck Enabled)