网站建设维护员,google推广 的效果,口碑做团购网站,写轮眼python代码一、前言
关于JS中this对象指向问题#xff0c;相信做过项目的小伙伴多多少少都会遇到过#xff0c;明明感觉代码写的没问题#xff0c;可是运行的时候#xff0c;就会报错#xff0c;比如报错 xxx is not a function。 我最近也遇到了#xff0c;百度学习了不少前辈对于…一、前言
关于JS中this对象指向问题相信做过项目的小伙伴多多少少都会遇到过明明感觉代码写的没问题可是运行的时候就会报错比如报错 xxx is not a function。 我最近也遇到了百度学习了不少前辈对于this对象指向问题的解析于是总结了这篇文章。
二、多种情况下使用this指向有所不同
先简略概括下this在英文中的意思是“这这个”的意思在编程中我们通常把this成为当前对象。在这篇文章中我们从始至终都要记得一句话this永远指向调用它的对象默认指向window/全局对象。
如果有多层嵌套对象调用的话this指向最后一次调用这个方法的对象。
1全局作用域中的this
在全局作用域中this指向 window/全局对象。 console.log(this) // window对象console.log(this window) //true2函数调用中的this
当一个函数不是一个对象的属性时直接作为函数来调用 函数不是箭头函数时this指向window/全局对象 函数是箭头函数时绑定的是父作用域的this指向。
function func(){console.log(this) ; //this指向window对象
}
func();注意定时器内部的this永远指向window比如setTimeoutsetInterval setTimeout(function(){console.log(this); //window对象},1000)3对象中的this
如果一个函数作为一个对象的方法来调用时this 指向这个对象比如vue中的methods对象里面定义的函数方法 箭头函数除外因为它会捕获其所在上下文的this所以可能会指向window/全局对象。 let obj {func: function () {console.log(this)}}obj.func()在这段代码中我们看到了 obj.func()this 处在 func 函数的内部那到底是谁调用的 func() 哪显而易见是 obj因为 this 永远指向调用它的对象所以最后的打印结果应该是 obj。
4使用 new 实例化对象构造函数中的this
构造函数中的this指向实例出来的对象。
function Person () {console.log(this)this.name 铁锤妹妹
}
var obj new Person() // 得到一个实例化对象继承了Person函数的属性
console.log(obj)打印结果就是Person 5apply 、call 和 bind 调用中的this
apply和call 改变的是函数运行时的this指向bind返回一个this绑定了传入对象的新函数。 这个函数的this指向使用new时会被改变。
注意箭头函数中的this不能通过apply 、call 和 bind 改变因为箭头函数中的this指向在定义时已经确认了之后不会被改变。
const obj { name: 铁锤妹妹, age: 18 }
function Person () {console.log(this.name)
}
Person.apply(obj) //铁锤妹妹
Person.call(obj) //铁锤妹妹
Person.bind(obj)() //铁锤妹妹6事件中的this
在事件处理函数中this指向触发事件的目标对象div/div。
document.querySelector(div).onclick function () {console.log(this) //div/div
}总结 1. 全局作用域中的this指向window 2. 普通函数this指向window箭头函数指向它的上下文this 3. 对象中方法的this指向该方法所属的对象 4. 构造函数中的this指向实例出来的对象 5. 事件当中的this指向当前绑定的元素 6. 定时器中的this指向window 7. apply 、call 和 bind 调用中的this指向它想要指向的this 三、改变this指向的方法 使用 ES6 的箭头函数在函数内部使用 _this thisnew 实例化一个对象使用 apply、call、bind 1箭头函数不绑定this会捕获其所在上下文的this作为自己的this 这句话需要注意的是箭头函数的外层如果有普通函数那么箭头函数的this就是这个外层普通函数的this它会继承自己作用域上一层的this箭头函数的外层如果没有普通函数那么箭头函数的this就是window/全局对象。箭头函数中的this指向在定义时已经确认了之后不会被改变。 下面这个例子是箭头函数外层有普通函数。 var name windowsNamevar a {name: 铁锤妹妹,func1: function () {console.log(this.name)},func2: function () {setTimeout(() {this.func1()}, 100)}}a.func2() //铁锤妹妹如果不使用箭头函数运行会报错原因是使用普通函数时调用的setTimeout的对象是Window而Window中没有定义func1函数。 var name windowsNamevar a {name: 铁锤妹妹,func1: function () {console.log(this.name)},func2: function () {setTimeout(function () {this.func1()}, 100)}}a.func2()报错信息
2如果不想使用箭头函数也可以在函数内部使用var _this this var name windowsNamevar a {name: 铁锤妹妹,func1: function () {console.log(this.name)},func2: function () {var _this thissetTimeout(function () {_this.func1()}, 100)}}a.func2() //铁锤妹妹在 func2 中首先设置 var _this this这里的this是调用 func2 的对象a因为a是最后一次调用这个方法的对象 为了防止在 func2 中的 setTimeout 被 window 调用而导致 setTimeout 中的 this 指向变为 window对象。我们将this指向变量a赋值给一个变量 _this这样在 func2 中我们使用 _this 就是指向对象 a 了。
3如果一个函数用 new 调用时函数执行前会新创建一个对象this 指向这个新创建的对象
new操作符的执行过程 首先创建了一个空的对象创建一个新的存储空间设置原型将对象的原型设置为函数的 prototype 对象让函数的this指向这个新空对象执行构造函数的代码为这个新对象添加属性和方法返回新对象所以构造函数不需要return 因此使用new 实例化对象构造函数中的this指向实例化对象。 注意上面说的箭头函数除外因为箭头函数是匿名函数不能作为构造函数所以不能使用new命令否则抛出错误。 //箭头函数使用new实例化报错代码
let func1 () {}
let func2 new func1()
console.log(func2) // func1 is not a constructor4使用apply、call和bind指定 调用函数 的this指向 var year 2023function getDate (month, day) {return this.year - month - day}let obj { year: 1998 }getDate.call(null, 3, 8) // 2023-3-8getDate.call(obj, 3, 8) // 1998-3-8getDate.apply(obj, [6, 8]) // 1998-6-8getDate.bind(obj)(3, 8) // 1998-3-8使用 apply() 方法
apply接受两个参数第一个是this的指向第二个是函数接受的参数以数组的形式传入且当第一个参数为null、undefined的时候默认指向window(在浏览器中)使用apply方法改变this指向后原函数会立即执行且此方法只是临时改变this指向一次。 语法规则 函数名称.apply(obj,[arg1,arg2…,argN])参数说明: obj this要指向的对象 [arg1,arg2…argN] : 参数列表要求格式为数组 使用 call() 方法
call 方法的第一个参数也是this的指向后面传入的是一个参数列表。当第一个参数为null、undefined的时候表示指向window。和apply一样call也只是临时改变一次this指向并立即执行。 语法规则 函数名称.call(obj,arg1,arg2…argN)参数说明: obj this要指向的对象 arg1,arg2…argN : 参数列表参数与参数之间使用一个逗号隔开 注意call和apply的作用一致区别仅仅在函数实参参数传递的方式上
使用 bind() 方法
bind方法和call很相似第一参数也是this的指向后面传入的也是一个参数列表(但是这个参数列表可以分多次传入call则必须一次性传入所有参数)但是它改变this指向后不会立即执行而是返回一个永久改变this指向的函数调用新函数的时候才会执行目标函数。
三、关于setTimeout() 定时器的“this”指向问题 由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局) 对象这和所期望的this的值是不一样的。 var name windowsNamevar a {name: 铁锤妹妹,func1: function () {setTimeout(function () {console.log(this.name, name)}, 100)}}a.func1()//因为setTimeout所以this指向window//打印结果windowsName四、总结本文箭头函数需要注意的地方 1. 函数是箭头函数的话指向它的上下文对象的yhis 2. 箭头函数中的this不能通过apply 、call 和 bind 改变因为箭头函数中的this指向在定义时已经确认了之后不会被改变 3. 箭头函数使用new实例化对象时会报错