当前位置: IT培训 > HTML5培训 > 前端开发 > JS > 用简单的方法判断JavaScript中this的指向
用简单的方法判断JavaScript中this的指向 时间:2017-09-14     来源:JS开发教程

都说 JavaScript 是一种很灵活的语言,这其实也可以说它是一个混乱的语言。它把 函数式编程 和 面向对象编程 糅合一起,再加上 动态语言 特性,简直强大无比。

JS 里的 this

在 function 内部被创建

指向调用时所在函数所绑定的对象(拗口)

this 不能被赋值,但可以被 call/apply 改变

目录

* 一个特例

* 开始判断

* 法则一:对象方法中的this指向对象本身(箭头函数形式的除外)

* 法则二:多层嵌套函数中的this指向等同于包含该this的近一个function的this

* 法则三:箭头函数以及非指向对象方法中的function的情况下this指向window

* 习题集

* 普通函数中的this

* 函数执行后返回另外一个函数中的this(普通函数中)

* 多层嵌套函数中的this(定时器&箭头函数)1

* 多层嵌套函数中的this(定时器&箭头函数)2

一个特例

在正式开始之前,我们先来说一个特例。

// 构造函数

function Student(name) {

this.name = name

}

// 创建小明和小红两个实例

var XM = new Student('xiaoming')

var XH = new Student('xiaohong')

// 输出信息

console.log(XM) // Student {name: "xiaoming"}

console.log(XH) // Student {name: "xiaohong"}

在构造函数中,this上的值会在创建实例的时候被绑定到新创建的实例上。不适用于下面的判断方法,所以特此说明。

开始判断

下面是一个典型例子,我们的分析从这里开始。

var x = {

name: 'bw2',

getName1: function() {

console.log(this)

},

getName2: function() {

setTimeout(() => {

console.log(this)

},0)

},

getName31: () => {

console.log(this)

},

getName32: function() {

return function() {

console.log(this)

}

}

}

x.getName1() // {name: "bw2", getName1: ƒ}

x.getName2() // {name: "bw2", getName1: ƒ}

x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}

x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}

法则一:对象方法中的this指向对象本身(箭头函数形式的除外)

var x = {

name: 'bw2',

getName1: function() {

console.log(this)

}

}

x.getName1() // {name: "bw2", getName1: ƒ}

法则二:多层嵌套函数中的this指向等同于包含该this的近一个function的this

箭头函数没有独立的this作用域,所以继续往外层走,走到了getName: function(){}。那么就是他了,this指向等同于这个function内部的this指向。根据法则一,this指向对象本身。

var x = {

name: 'bw2',

getName2: function() {

console.log(this) // 等同于此处的this

setTimeout(() => {

console.log(this) // 原始的this位置

},0)

}

}

x.getName2() // {name: 'bw2', getName1: ƒ}

我们可以试着在浏览器中运行,看看结果。

法则三:箭头函数以及非指向对象方法中的function的情况下this指向window

根据法则二,this是指向近的function,因此,这里的this等同于返回的函数中的this,不是对象方法中的this,所以,指向全局。

是不是感觉有点奇怪?不过实践证明确实如此。

var x = {

name: 'bw2',

getName31: () => {

console.log(this)

},

getName32: function() {

return function() {

console.log(this)

}

}

}

x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}

x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}

习题集

欢迎大家按照法则一到三依次判断,猜测结果,并在浏览器下测试。测试结果也可以回复,大家一起讨论。

因本人能力有限,该系列法则可能在部分情况下失效。欢迎大家一起讨论。

下面是做题时间。

普通函数中的this

function x() {

console.log(this)

}

x()

函数执行后返回另外一个函数中的this(普通函数中)

function xx(){

return function() {

console.log(this)

}

}

xx()()

多层嵌套函数中的this(定时器&箭头函数)1

var x = {

name: 'bw2',

getName: () => {

setTimeout(() => {

console.log(this)

},0)

}

}

x.getName()

多层嵌套函数中的this(定时器&箭头函数)2

var x = {

name: 'bw2',

getName: () => {

setTimeout(function() {

console.log(this)

},0)

}

}

x.getName()

再次说明,该法则为实验性法则,未进行大范围的测试,不保证在所有情况下都有一致的结果

X