<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>this指向常见问题</title>
</head>
<body>
<script>
// 默认绑定
// 1. 严格模式下
var a = 10
console.log(this.a) // 10
function func(){
// "use strict" // 在严格模式下,函数体内的this指向undefined
var a = 12
console.log("func",this.a) // 10 -- this为window,this.a 为全局window下的a
}
func()
function foo(){
console.log("use strict")
}
(function(){
"use strict"
foo() // use strict -- 这里调用foo仍然是window , 若是this.foo() -- 的this指向undefined 找不到foo方法
})()
// 2. 全局下用let const声明的变量不会绑定在window上
// 3. 普通函数的嵌套
var a = 12
function func2(){
var a = 13
function inner(){
console.log(this.a) //12
}
inner()
}
func2()
// 隐式绑定 -- this指向最后调用的对象
var obj = {
name: "hh",
foo: function(){
console.log(this.name)
}
}
obj.foo() //"hh" -- this指向obj
// 隐式绑定的隐式丢失
// 隐式丢失1. 使用另外的变量给函数起别名
var name = "window name"
var foo = obj.foo
foo() // window name
// 隐式丢失2. 把函数作为参数进行传递 -- 作为参数传递的函数里的this指向为window
function foo2(foo){
foo()
}
foo2(foo) // window name: foo中的this指向window
// ⚠️ 作为参数来传递函数造成的函数隐式丢失,作为参数的函数的this指向window,与包裹它的函数的this指向无关
var obj2 = {
name: "obj2 name",
foo2
}
obj2.foo2(obj.foo) // window name
// 另外 settimeout中回调函数的this,也属于这种隐式丢失,this指向window
// 显示绑定 -- 通过call apply bind方法来改变this指向
// 函数返回的函数中的this指向为最后调用它的对象,与外层函数无关
var a = 11
function foo3(){
console.log(this.a)
return function(){
console.log(this.a)
}
}
var obj = {a: 22}
foo3.call(obj)()// 22 11 -- foo3的this指向obj,但是调用匿名函数的是window -- (匿名函数的this指向永远指向window)
// forEach map filter这些方法 的第二个参数可以用来绑定this
// new绑定 -- this指向new创建的对象(举例略)
// 箭头函数绑定 -- 箭头函数中的this由外层作用域决定,指向函数定义时的this而非执行时的this
// 对象字面量 & 箭头函数
var name = "window-name"
var obj = {
name: "obj-name",
func1: () =>{
console.log(this.name)
},
func2: function(){
console.log(this.name)
return ()=>{
console.log(this.name)
}
},
func3: () => {
console.log(this.name)
return ()=>{
console.log(this.name)
}
}
}
obj.func1() // window-name : 方法func1定义时的作用域为全局作用域,obj不是作用域,作用域仅分为全局作用域和局部作用域
obj.func2()() // obj-name obj-name : func2箭头函数在定义时,处于函数作用域,因此return的箭头函数中的this指向obj
obj.func3()() // window-name window-name: 两个箭头函数定义时的this执行都是全局window
// 构造函数 & 箭头函数
function Person(name){
this.name = name
this.func = ()=>{
console.log(this.name)
}
}
var person = new Person("person-name")
person.func() // person-name : 箭头函数定义时的this指向person
// 箭头函数与call结合 -- 箭头函数无法通过call apply bind方法直接进行this指向的修改,但是可以修改作用域的this指向来间接修改
// 易错题
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj',
foo1: function () {
return function () {
console.log(this.name)
}
},
foo2: function () {
return () => {
console.log(this.name)
}
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.obj.foo2()() // obj -- 箭头函数的作用域是foo2的作用域,foo2在this.obj内,this.name 执行obj
person1.obj.foo2().call(person2) //obj
</script>
</body>
</html>
this指向问题
最新推荐文章于 2024-06-14 21:00:00 发布