JavaScript中this指向问题
1、this指向window的情况
对于非箭头函数情况下,谁调用就指向谁,如果函数在全局作用域下调用,里面的this就是window。
在全局作用域下,this = window
function sum() {
console.log(this);
}
sum(); // window
console.log(this); // window
2、this指向对象的情况
- 当函数在对象中以方法的形式调用,this指向当前对象
function sum() {
console.log(this);
}
let obj = {
name : "sb",
sum, // 如果Key value名字相同,可以简写
add : function() {
console.log(this);
}
}
console.log(obj.add()); // this
console.log(obj.sum); // this
-
如果对象里面还有对象,里面的对象还有方法,此时这个方法就是指向最近的对象,
如果对象的方法里面,还有函数调用,该函数里面的this指向window对象,因为该函数是window调用,并执行的。
function deletex() {
console.log(this);
}
let obj = {
name :"sb",
add : function() {
console.log(this);
},
user : {
sum : function() {
deletex();
console.log(this);
}
}
}
obj.add(); // obj对象
obj.user.sum(); // 第一个window 第二个是user对象
- 通过构造函数,就是通过构造函数new对象时,this指向当前new的实例对象
function Person(name,age) {
this.name = name;
this.age = age;
let say = function() {
console.log(`${this.name} ${this.age} = ${this}`);
}
}
let person = new Person('lfj',26);
console.log(person.name); // 'lfj';
- 通过class 来构造对象,this指向的就是new出来的对象
class Person {
constructor(name,age) {
this.name = name;
this.age = age;
}
}
let person = new Person('lfj',20);
console.log(person.name); // lfj
console.log(person.age); // 20
3、借助函数的call、apply方法的调用
参数中传入了对象,this就是指传入的对象,参数为空,就是window
call()、apply()都是函数对象的一个方法,它们的作用是改变函数的调用对象,它们的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。
function sayHello() {
console.log(`hello ${this.name}`);
}
let obj = {};
obj.name = 'Tom';
obj.sayHello().apply(); // hello undefined 此时的this就是window
function sayHello() {
console.log(`hello ${this.name}`);
}
let object1 = {};
let object2 = {};
object1.name = 'Tom';
object2.name = 'Jack';
object2.sayHello = sayHello;
object2.sayHello.apply(object1); // hello Tom
4、借助函数的bind方法
bind方法和apply和call方法作用一样,区别就是不立即执行和立即执行
let object1 = {
name : "lfj",
say : function() {
console.log(this.name);
}
}
let object2 = {
name : "wmz",
say : function() {
console.log(this.name);
}
}
object2.say.bind(object1,object1.say);
// bind并不会立即执行
object2.say(); //
5、箭头函数中this的指向
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承 this
let obj1 = {
name : 'lfj',
say : () => {
console.log(this);
}
obj2 : {
name : 'wz',
eat : () => {
console.log(this); // obj1
}
}
}
obj.say(); // window // 会向上一层作用域链继承this,obj1作用域中的this就是window
obj1.obj2.eat(); // obj1 // 此时继承的this是上一层作用域链的对象,obj1
let obj1 = {
name : 'xx',
say : function() {
setTimeout(()=>{
console.log(this); // obj1.
},1000);
}
}