目录
总结:
总结:
1. 全局中,打印this 指向window
2. 全局中,函数方法全局调用 this指向window
3. class类方法中,调用 this指向实例化的类
4. call bind apply方法绑定调用函数时,this指向被传入的对象,
同时还可以传入参数。
call可以传入一个或者多个参数,
call调用的时候就执行,无需手动调用
bind可以传入一个或者多个参数,但必须手动调用
apply和call的区别就是,传入的参数必须是数组 不然就报错
5. 构造函数中,的this指向 new出来的实例
6. 前面四种this都是动态的,调用时才确定的。
箭头函数中this 指向父级的上下文中的this,是定义的时候就确定的。
---------------追问时补充
1. 为什么需要this?
语言的运行需要环境
环境 =》JS环境分为web浏览器和node环境
为什么需要环境?
函数可以在不同的运行环境执行,JS也允许当前函数体内部使用运行环境的其它变量,因此需要this指明代码到底在哪里执行。
1. 全局时,严格模式下,默认绑定全局是不合法的,this被置为undefined
2. 对象实例 调用对象里面的方法 记住原则 打印的是最后调用的对象
3. 构造函数中的this指向新对象的实例 是因为内部使用了new方法call 指向了新创建的对象
new一个构造函数的过程:
简单版本:
1. 创建一个新对象 新的内存空间
2. this指向这个对象空间 通过call办法
3. 执行构造函数里面的方法 给新的对象赋值
4. 返回这个实例对象
4. 类注意事项
如果类实例对象的方法存储 稍后调用会失去追踪 this指向undefiend
因此需要将bind方法指回实例对象
1. 直接打印一个this
// 1. 直接打印this
console.log(this); // // Window
2.普通函数的打印this
指向window
// 2. 直接调用函数
function fun() {
console.log(this);
}
fun(); // Window
3. 对象打印this
发现打印的是调用的对象本身
var obj = {
name: 'xxx',
star: function () {
console.log(this);
}
}
4. call apply bind都可以改变this指向
let prox1 = {
name: 'jmq'
}
let prox = {
name: 'lzh',
age: 18,
sayhello: function() {
console.log(this);
}
}
prox.sayhello()
prox.sayhello.call(prox1) // prox1
prox.sayhello.apply(prox1) // prox1
prox.sayhello.bind(prox1)() // prox1
// 不同点是bind需要手动调用
5. class类中 this指向new后的实例对象
class Person {
constructor(name, age) {
this.name = name;
this.age = age
}
sayhello() {
console.log(this); // 指向new之后的实例对象
}
}
const person1 = new Person('lzh', 19)
person1.sayhello()
// 5.1 类使用的注意情况 如果把方法存起来 会失去追踪 需要手动bind解决这个问题
const say = person1.sayhello
say() // undefined
const say2 = person1.sayhello.bind(person1)
say2() // 成功指回去
6. 箭头函数
let obj2 = {age: '123'}
var name = '杨志'
let pox = {
name: '小红',
run: () => {
console.log(this);
}
}
pox.run()
// 箭头函数的this指向父级的上下文对象
// 不可以被call apply bind改变
7. 特殊情况1
const zhangsan = {
name: '张三',
sayHi() {
console.log(this);
},
wait() {
setTimeout(function() {
console.log(this); // 指向window
})
}
}
zhangsan.sayHi() // zhangsan对象
zhangsan.wait() // window
// 定时器内部打印this
let timer = setTimeout(() => {
console.log(this); // window
}, 1000)
7. 特殊情况2
const zhangsan2 = {
name: '张三',
sayHi() {
console.log(this);
},
waitAgain() {
setTimeout(() => {
// this指向 当前对象
console.log(this);
})
}
}
zhangsan2.waitAgain()
// 箭头函数 this指向 当前函数所在父级的上下文对象
// 当前函数的父级是waitAgain函数 上下文是在zhangsan2这个对象
8. 按钮点击事件打印this
打印的是按钮本身。为什么?
因为是点击按钮而触发的点击事件,this指向按钮
// 5. 按钮点击事件
btn.addEventListener("click", function () {
console.log(this); // button这个按钮这个元素
})
本文章参考了:
一图搞懂javascript中的this与call/apply/bind的6中关系_田兴的博客-CSDN博客
关于call和apply和bind的用法可以查看:
「干货」细说 call、apply 以及 bind 的区别和用法 - 掘金
我的下面这篇文章有具体的习题
JavaScript 高级编程,this指向问题【2】_hangshao_123的博客-CSDN博客
结尾:
学习id: 201903090124-28
现在是大三学生,学习到了前后端交互阶段,如有不对的地方,欢迎指正,一起努力呀。如有转载请注明出处。