本文
前往“校招VIP”小程序,访问更方便

【校招VIP】JS中的this指向情况汇总

csdn 10月24日

转载声明:文章来源https://blog.csdn.net/a715167986/article/details/100666116 

对于我们开发人员来说,this这个关键字可以说是再熟悉不过了,几乎所有主流的程序开发语言都带有this关键字。今天我们来说说在JavaScript中的this指向都有哪些情况(这也是面试中常常会问到的问题)。

JS中的this指向对于刚刚学习这门的语言的同学来说,有时往往会让人感到很困惑:明明觉得自己在很多时候应该是知道this的指向的,可真正要你回答 this的指向到底有哪几种情况时,又往往说不全面,大有一种最熟悉的陌生人之感。其实在JavaScript中this指向情况常见的就是4种:1. 作为对象的方法调用;2. 作为普通函数调用;3. 构造器调用;4. Function.prototype.call或Function.prototype.apply调用

1.作为对象的方法调用

当函数作为对象的方法被调用时,this指向该对象:

const obj = {
attr1: 3,
func1: function() {
console.log(this === obj) // 输出:true
console.log(this.attr1) // 输出:3
}
}
obj.func1()

2. 作为普通函数调用

当函数不作为对象的属性被调用时,也就是作为普通函数调用,此时的this总是指向全局对象。在浏览器的JavaScript环境中,这个全局对象是window对象:

// 假设这段代码在vue文件中:xxx.vue
<script>
export default {
name: 'App',
data() {
return {
attr1: 'aaa',
attr2: 'bbb'
}
},
methods: {
funcA() {
console.log(this.attr1) // 输出:aaa, 该this指向当前vue组件的vue实例
setTimeout(function() {
console.log(this === window) // 输出:true, setTimeout函数是普通函数调用,所以其指向的是window对象
console.log(this.attr2) // 输出:undefined
}, 1000)
setTimeout(() => {
console.log(this === window) // 输出:false,箭头函数中的this为父作用域的this,不是调用时的this,所以这里this指向vue实例
console.log(this.attr2) // 输出: bbb
}, 1000)
}
},
mounted () {
this.funcA()
}
}
</script>
window.name = 'globalName'

let getName = function () {
return this.name
}

console.log(getName()) // 输出:globaleName
window.name = 'globalName'

let myObject = {
name: 'sven',
getName: function () {
return this.name
}
}

let getName = myObject.getName
console.log(getName()) // 输出:globalName

3. 构造器调用

JavaScript 中没有类,但是可以从构造器中创建对象,同时也提供了 new 运算符,使得构造器看起来更像一个类。

除了宿主提供的一些内置函数,大部分 JavaScript 函数都可以当作构造器使用。构造器的外表跟普通函数一模一样,它们的区别在于被调用的方式。当用 new 运算符调用函数时,该函数总 会返回一个对象,通常情况下,构造器里的 this 就指向返回的这个对象,见如下代码:

let Cls = function () {
this.name = 'cdk'
}

let obj = new Cls()
console.log(obj.name) // 输出:cdk

4. Function.prototype.call或Function.prototype.apply调用

跟普通的函数调用相比,用 Function.prototype.call 或 Function.prototype.apply 可以动态地 改变传入函数的 this:

let objA = {
name: 'cdk',
getName: function () {
return this.name
}
}

let objB = {
name: 'xzl'
}

console.log(objA.getName()) // 输出:cdk
console.log(objA.getName.call(objB)) // 输出:xzl

如上,我们日常编写代码过程中遇到的this的指向含义基本上不会脱离以上四种情况,尤其是前面3种情况十分常见,第4种利用call和apply函数改变this指向的手法在一些设计模式和其他高级写法里常常可以见到,这也是js比较灵活的一个方面。另外上面代码中关于vue函数的举例在我们日常开发中遇到的频率很高,我们应该要明确其中this的指向带来的一些问题,ES6新引入的箭头函数不仅使得我们书写函数更加简洁直观,很多时候箭头函数中的this指向其上下文环境的特性更加重要。

暂无回复