Hello World - 2024年3月
type: channel
link: https://blog.xunbaidu.com/2024/03/
description: ----------------------------------------------------------------------------------------
items: JS中this的指向问题

JS中this的指向问题
type: item
date: 2024-03-01T00:14:59+08:00
description: 最近碰到了一个问题，环境是vue2、ts、vue-class-component，写一个方法时发现声明的变量虽可以访问到但没有响应式，随后发现方法中的this不是VueComponent，在检查为什么this指向有问题时发现新写的方法用的是箭头函数，改成普通函数后就正常了，对于这块有点疑惑，因此整理记录关于this指向的情况。1.不同情况下this的指向方法/函数调用中的thiswindow.name = 'win' function fun () { console.log(this.name) } let obj1 = { name: 'jack', fun } let obj2 = { name: 'bob', } obj2.fun = obj1.fun fun() // win obj1.fun() // jack obj2.fun() // bob如上代码，直接执行fun函数，打印“win”，表明此时函数中的this指向的对象是window。而使用obj1.fun()调用fun函数，打印“jack”，此时this指向的对象是obj1。obj2.fun()的执行结果为“bob”，表明obj2对象的fun函数虽然是由obj1的fun函数赋值得到，但由于是obj2对象调用的，所以this指向obj2，打印了obj2的name属性。window.name = 'win' let fun = () => { console.log(this.name) } let obj = { name: 'jack', funA } obj.fun() // win如上代码，当fun函数为箭头函数时，因为定义funB时所在的作用域是在全局作用域window下，所以funB内的this是window，因此obj.fun()的打印结果是”win“而非”jack“。事件回调中的this行内绑定 直接将函数执行语句"handleClick()"作为属性绑定到dom标签上，当click事件触发时，语句可视为是在全局作用域下执行的，因此this指向window。 当回调函数是箭头函数时，函数内this也为window。js动态绑定 通过js赋值函数给dom对象的onclick属性的方式绑定回调函数，回调函数是被dom对象所调用的，因此this指向dom对象。 当绑定的回调函数是箭头函数时，函数内this指向window。事件监听 通过事件监听方法绑定的回调函数，this同样指向了dom对象。 当绑定的回调函数是箭头函数时，函数内this指向window。构造函数中的thisfunction Obj() { console.log(this) } let o = new Obj() // Obj {} console.log(this) // Window {}如上代码第五行执行new Obj()语句时，打印了“Obj {}”，这是因为在new关键字会首先创建一个空对象，并将控对象的隐式原型指向构造函数的显式原型，最后将构造函数中的this指向了这个新创建的对象，因此在构造函数中，this会指向一个新创建的对象，同时它也是new语句的返回值。另外箭头函数由于没有自己的this，是不可以作为构造函数的。call、apply、bindcall、apply和bind是js中三个很神奇的函数，使用它们可以改变函数体内部this的指向。let func = function() { console.log(this.name, [...arguments].join(',')) } let obj1 = { name: 'obj1', func } let obj2 = { name: 'obj2', } obj1.func(0) // obj1 0 obj1.func.call(obj2, 1, 2, 3) // obj2 1,2,3 obj1.func.apply(obj2, [4, 5, 6]) // obj2 4,5,6如上代码，call和apply方法都可以改变函数内部this的指向，区别在于call方法第一个参数是所要改变的this（上下文），其它参数是func函数的参数，apply方法的第二个参数是fun函数参数的数组。let func = function() { console.log(this.name, [...arguments].join(',')) } let obj1 = { name: 'obj1', func } let obj2 = { name: 'obj2', } let newFunc = obj1.func.bind(obj2) newFunc(1, 2, 3) // obj2 1,2,3bind方法可以返回一个新的函…