this小总结
在JavaScript中,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指的是谁。普通函数(非箭头函数)的this值是在函数被调用时确定的
几种情况总结:
独立函数调用:非严格模式的普通函数直接调用时,
this会替换为globalThis;严格模式下是undefined。ES Module 默认处于严格模式。不能笼统记成“浏览器是window、Node.js 是global”,因为模块类型和运行环境都会影响结果。function foo() { return this; } console.log(foo() === globalThis); // 经典非严格 script 中为 true对象方法调用: 当函数作为对象的方法被调用时,
this值是该对象。const obj = { foo() { return this; } }; console.log(obj.foo() === obj); // true构造函数调用: 当函数作为构造函数(使用
new关键字)调用时,this值是新创建的对象。构造函数内的属性和方法前面必须加this,表示当前对象的属性和方法
new关键字作用:让 this 指向这个新的对象。
function MyClass() { this成员 = '成员值'; } const实例 = new MyClass(); console.log(实例.成员); // '成员值'DOM 事件处理:用普通函数注册的监听器中,
this等于event.currentTarget(注册监听器的元素),不一定是实际触发事件的event.target。html <button id="myButton">点击我</button>javascriptdocument.getElementById('myButton').onclick = function(event) { console.log(this === event.currentTarget); // true };apply、call 和 bind 方法:
apply、call和bind方法可以用来设置this值。//apply方法 调用函数,同时指定被调用函数中this的值 //1.apply方法 const person = { age: 19 } function f(x,y){ console.log(this) console.log(x + y) //3 } //调用函数 f() f.apply() //改变this指向 f.apply(person) // 与 call 的区别:apply 的第二个参数是数组或类数组对象,也可以是 null/undefined f.apply(person,[1,2]) //call方法 调用函数,同时指定被调用函数中this的值 fun.call(thisArg,arg1,arg2,...) //thisArg,在fun函数运行时指定的this值 //arg1,arg2 : 传递的其他参数 //返回值就是函数的返回值,因为它就是调用函数 示例代码: const obj = { uname:'pink' } function fn(x,y){ console.log(this) //window } //使用函数的call方法 fn.call(obj,1,2) //此时this指向obj这个对象 //bind方法箭头函数中使用:箭头函数没有自己的
this,而是按词法作用域使用外层环境的this。它不是在定义时把某个“对象”永久绑定进去。const obj = { foo: function() { setTimeout(() => console.log(this), 1000); } }; obj.foo(); // 输出obj原型方法中的
this仍由调用方式决定。instance.method()通常指向实例,但把方法拆出来直接调用、用call调用或由其他对象借用时都会不同。
每一个构造函数都有一个prototype属性,指向一个对象,叫原型对象
把不变的方法定义在prototype对象上
function Star(starName,age){
this.starName = starName
this.age = age
}
Star.prototype.sing = function(){
console.log(this.starName)
}
const lce = new Star('Lce',18)
lce.sing() // 调用点的接收者是 lce,因此 this === lce箭头函数不可用:
1.定义对象的方法,且该方法内部包括this。
对象的属性建议使用传统的写法定义,不要用箭头函数定义。
const cat = {
lives: 9,
jumps: () => {
this.lives--;
}
}上例把需要动态接收者的对象方法写成箭头函数,因此得不到 cat 作为 this。顶层经典 script 中外层 this 常是 window,ES Module 中则是 undefined,所以不能一概写成“指向全局对象”。
2.需要动态this的时候,也不应使用箭头函数。
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});箭头函数会沿用外层 this,因此这里无法依赖 this.classList;在 ES Module 中通常会因 this 为 undefined 而报错。可改用普通函数读取 this/event.currentTarget,或在箭头函数中直接使用 button。
定时器的this指向问题:

普通函数的 this 由调用方式决定,箭头函数按词法作用域读取外层 this。浏览器定时器调用普通函数回调时 this 通常是 window,但 Node.js 中通常是 Timeout 对象,因此跨环境代码不要依赖定时器为回调提供的 this。
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42调用 foo.call({ id: 42 }) 时,foo 内部的 this 是该对象;随后创建的箭头函数捕获这个 this,所以稍后输出 42。关键是词法捕获发生在本次 foo 执行期间,而不是“箭头函数定义时所在的对象”。

这个写的非常好,多看
