this相关面试知识点

159 阅读2分钟

this

  • 在函数体中,非显式或隐式地简单调用函数时,在严格模式下,函数内的this会绑定到undeined,在非严格模式下则会绑定到全局对象window/global。
  • 一般使用new方法调用构造函数时,构造函数内的this会绑定到新创建的对象上
  • 一般通过call/apply/bind方法显式调用函数时,函数体内的this会绑定到指定参数的对象上
  • 一般通过上下文对象调用函数时,函数体的this会绑定到该对象上
  • 在箭头函数中,this的指向是由外层(函数或者全局)作用域决定的
全局环境中的this
function f1() {
    console.log(this)
}

function f2() {
    'use strict'
    console.log(this)
}
f1() //Window {window: Window, self: Window, document: document, name: "", location: Location, …}
f2() //undefined
const o1 = {
    text: 'ol',
    fn: function() {
        return this.text
    }
}
const o2 = {
    text: 'o2',
    fn: o1.fn
}
console.log(o2.fn())//o2
const foo = {
    bar: 10,
    fn: function() {
        console.log(this)
        console.log(this.bar)
    }
}
var fn1 = foo.fn
fn1()
//Window {window: Window, self: Window, document: document, name: "", location: Location, …}
//undefined

  • 这里的this仍然指向window,虽然fn函数在foo对象中用来作为对象的方法,但是赋值之后,fn1仍然是在window的全局环境中运行的。
构造函数和this
function Foo() {
    this.bar = "Lucas"
}
const instance = new Foo()
console.log(instance.bar)//Lucas
  • new 操作符号调用构造函数具体的操作
  1. 创建了一个新的对象
  2. 将构造函数的this指向对象
  3. 为这个对象添加属性和方法
  4. 最终返回新的对象
var obj = {}
obj.__proto__ = Foo.prototype
Foo.call(obj)
function Foo() {
    this.user = "Lucas"
    const o = {}
    return o
}
const instance = new Foo()
console.log(instance.user) //undefined
  • 如果构造函数返回一个值,且返回的是一个对象,那么这个this就指向返回的对象,如果返回的是不是一个对象,则this仍然指向实例
箭头函数中的this
  • this 出现在 setTimeout的匿名函数中,因此this指向window对象
const foo = {
   fn: function() {
       setTimeout(function() {
           console.log(this)
       })
   }
}
console.log(foo.fn()) 
//undefined
//Window {window: Window, self: Window, document: document, name: "", location: Location, …}
const foo = {
   fn: function() {
       console.log(2)
       setTimeout(() => {
           console.log(3)
           console.log(this)
       })
   }
}
console.log(1)
console.log(foo.fn())
   // 1
   // 2
   // undefined
   // 3
   // {fn:f}
  • 箭头函数的绑定无法修改
function foo() {
    return a => {
        console.log(this.a)
    };
}
const obj1 = {
    a: 2
}
const obj2 = {
    a: 3
}
var bar = foo.call(obj1)
console.log(bar.call(obj2))//2