前端面试题 - 48. 对JS this的理解

375 阅读5分钟

this指向

在 JavaScript 中,this 是一个关键字,它代表当前函数的执行上下文对象。this 的指向是动态的,它的值取决于函数的调用方式和上下文环境。this 在不同的情况下有不同的指向,具体如下:

  • 全局环境下,this 指向全局对象(浏览器中是 window 对象)。
console.log(this); // 输出 window 对象(浏览器中)
  • 对象方法中,this 指向调用该方法的对象。
const obj = {
  name: 'test',
  sayName() {
    console.log(this.name);
  }
};
obj.sayName(); // 输出 'test'
  • 构造函数中,this 指向新创建的对象。
function Person(name) {
  this.name = name;
}
const p = new Person('Tom');
console.log(p.name); // 输出 'Tom'
  • apply、call、bind 方法中,this 指向方法的第一个参数所指向的对象。
const obj1 = {
  name: 'obj1'
};
const obj2 = {
  name: 'obj2'
};
function sayName() {
  console.log(this.name);
}
sayName.call(obj1); // 输出 'obj1'
sayName.apply(obj2); // 输出 'obj2'
const sayName1 = sayName.bind(obj1);
sayName1(); // 输出 'obj1'
  • 箭头函数中,this 指向定义时所在的作用域(词法作用域),而不是调用时的作用域。
const obj = {
  name: 'test',
  sayName: () => {
    console.log(this.name);
  }
};
obj.sayName(); // 输出 undefined

this 的指向在函数调用时确定,因此我们需要注意函数调用的方式和上下文环境,并根据实际情况选择合适的方式来使用 this。在实际开发中,我们可以通过使用箭头函数或者使用 bind、apply、call 等方法来控制函数中 this 的指向,以提高代码的可读性和可维护性。同时,我们也需要注意避免 this 的隐式绑定和误用,以避免出现意外的结果。

function 和 箭头函数的定义有什么区别? 导致了在this指向这块表现不同

在 JavaScript 中,function 和箭头函数的定义有很大的区别,这也导致了它们在 this 指向上表现不同。具体来说,区别主要有以下几点:

  1. 语法不同:function 是传统的函数定义方式,而箭头函数是 ES6 中新增的一种函数定义方式,其语法更加简洁。
  2. this 指向不同:function 中的 this 指向是动态的,它的值取决于函数的调用方式和上下文环境;而箭头函数中的 this 指向是静态的,它的值取决于函数的定义时所在的作用域(词法作用域)。
  3. arguments 对象的处理不同:function 中可以使用 arguments 对象获取函数的所有参数,而箭头函数中没有 arguments 对象,需要使用 rest 参数来获取函数的所有参数。 下面是一个示例,用于说明 function 和箭头函数在 this 指向上的区别:
const obj = {
  name: 'test',
  sayName1: function() {
    console.log(this.name);
  },
  sayName2: () => {
    console.log(this.name);
  }
};
obj.sayName1(); // 输出 'test'
obj.sayName2(); // 输出 undefined

在上面的示例中,sayName1 是一个 function,它的 this 指向是动态的,并且指向 obj 对象,因此输出 'test';而 sayName2 是一个箭头函数,它的 this 指向是静态的,并且指向定义时所在的作用域,由于它定义在全局作用域中,因此 this 指向的是全局对象,所以输出 undefined。

需要注意的是,箭头函数中的 this 指向是静态的,一旦定义了就不会再改变,而 function 中的 this 指向是动态的,它的值取决于函数的调用方式和上下文环境。因此,在使用 this 的场景中,我们需要根据实际情况选择合适的函数定义方式,以避免出现意外的结果。

导致js里this指向混乱的原因是什么?

在 JavaScript 中,this 的指向混乱主要是因为它的绑定规则比较复杂,同时也受到函数的调用方式、上下文环境等因素的影响。具体来说,导致 this 指向混乱的原因主要有以下几点:

  1. 函数的调用方式不同:this 的指向取决于函数的调用方式,例如函数调用、方法调用、构造函数调用、apply、call、bind 等方式都会影响 this 的指向。
  2. this 的隐式绑定:当函数作为对象的方法被调用时,函数中的 this 会自动绑定到该对象上,这种方式称为隐式绑定。但是,如果函数调用时没有对象可以绑定到 this 上,则会绑定到全局对象上。
  3. this 的误用:由于 this 的绑定规则比较复杂,很容易被误用,例如在回调函数中使用 this 时,可能会出现意外的结果。
  4. 箭头函数的使用:箭头函数中的 this 是静态的,并且指向定义时所在的作用域,因此在使用箭头函数时需要注意 this 的指向。

总之,JavaScript 中 this 的指向混乱主要是因为它的绑定规则比较复杂,同时也受到函数的调用方式、上下文环境等因素的影响。为了避免出现意外的结果,我们需要根据实际情况选择合适的方式来使用 this,并尽量避免 this 的隐式绑定和误用。

对象函数里的子函数输出

var name = '123';

var obj = {
	name: '456',
	print: function() {
		function a() {
			console.log(this.name);
		}
		a();
	}
}

obj.print();

代码输出结果为 '123'。这是因为在 print 函数中定义了一个内部函数 a,当调用 a 函数时,它的 this 指向的是全局对象 window,而不是 obj 对象。因此,在 a 函数中访问 this.name 时,它实际上是访问全局变量 name(即 '123'),而不是对象 obj 中的属性 name(即 '456')