转载声明:文章来源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指向该对象:
1 2 3 4 5 6 7 8 | const obj = { attr1: 3, func1: function () { console.log( this === obj) // 输出:true console.log( this .attr1) // 输出:3 } } obj.func1() |
2. 作为普通函数调用
当函数不作为对象的属性被调用时,也就是作为普通函数调用,此时的this总是指向全局对象。在浏览器的JavaScript环境中,这个全局对象是window对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // 假设这段代码在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> |
1 2 3 4 5 6 7 | window.name = 'globalName' let getName = function () { return this .name } console.log(getName()) // 输出:globaleName |
1 2 3 4 5 6 7 8 9 10 11 | 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 就指向返回的这个对象,见如下代码:
1 2 3 4 5 6 7 | <span style= "color: inherit; font-size: inherit;" >let Cls = function () {</span> 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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指向其上下文环境的特性更加重要。
帖子还没人回复快来抢沙发