this指向

4/7/2022 running

# 1. 严格模式和非严格模式下的this指向

下面答案输出什么?

function f1() {
  console.log(this)
}

function f2() {
  'use strict'
  console.log(this)
}

f1()
f2()
1
2
3
4
5
6
7
8
9
10
11
查看答案

// f1() => window
// f2() => undefined

函数在全局环境中简单调用,非严格模式下,this指向window,严格模式下this指向undefined

# 2. 对象中this指向

下面答案输出什么?

const foo = {
  bar: 10,
  fn: function() {
    console.log(this)
    console.log(this.bar)
  }
}
var fn1 = foo.fn
fn1()
1
2
3
4
5
6
7
8
9
查看答案

// window
// undefined
此时foo.fn赋值给了fn1,依旧在全局环境下执行,所以this指向window,window中没有bar那么第二个输出undefined

# 3. 对象中this指向2

下面答案输出什么?

const foo = {
  bar: 10,
  fn: function() {
    console.log(this)
    console.log(this.bar)
  }
}
foo.fn()
1
2
3
4
5
6
7
8
查看答案

// {bar: 10, fn: ƒ}
// 10

this指向调用它的对象,所以第一个是foo对象,第二个是foo中的bar属性,为10

# 4. 对象中this指向3

下面答案输出什么?

const student = {
  name: 'xm',
  fn: function() {
    return this
  }
}
console.log(student.fn() === student)
1
2
3
4
5
6
7
查看答案

// true
this指向student

# 5. 对象中setTimeout中的this指向

下面答案输出什么?

const foo = {
  bar: 10,
  fn: function() {
    setTimeout(function() {
      console.log(this.bar)
    })
  }
}
foo.fn()
1
2
3
4
5
6
7
8
9
查看答案

// undefined
虽然是foo方法调用,但是在setTimeout的匿名函数中,this指向全局window

# 6. 对象嵌套中的this指向

下面答案输出什么?

const student = {
  name: 'xm',
  brother: {
    name: 'xh',
    fn: function() {
      return this.name
    }
  }
}
console.log(student.brother.fn())
1
2
3
4
5
6
7
8
9
10
查看答案

// xh
当对象发生嵌套关系的时候,this会指向最后调用它的对象

# 7. 对象中this指向4

下面答案输出什么?

const o1 = {
  text: 'o1',
  fn: function() {
    return this.text
  }
}
const o2 = {
  text: 'o2',
  fn: function() {
    return o1.fn()
  }
}
const o3 = {
  text: 'o3',
  fn: function() {
    var fn = o1.fn
    return fn()
  }
}
console.log(o1.fn())
console.log(o2.fn())
console.log(o3.fn())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
查看答案

// o1
// o1
// undefined

  1. 第一个this指向o1,o1的属性text值为'o1'
  2. 第二个对象的调用发生了嵌套,指向最后一个调用的对象o1,o1的属性text值为'o1'
  3. 第三个对象是函数的简单调用,指向window,window没有text属性,返回undefined

# 8. 对象中this指向5

如何将上面的题,第二个输出'o2'

查看答案
  1. 方法一:使用call/apply/bind强制修改this
  2. 方法二:将o1.fn提前赋值
const o1 = {
  text: 'o1',
  fn: function() {
    return this.text
  }
}
const o2 = {
  text: 'o2',
  fn: o1.fn
  }
}
1
2
3
4
5
6
7
8
9
10
11

上面代码中,提前进行复制操作,将函数fn挂载到o2对象上,最终用o2对象的方法被调用

# 9. 使用call/apply/bind的this指向

下面答案输出什么?

const foo = {
  name: 'xm',
  logName: function() {
    console.log(this.name)
  }
}
const bar = {
  name: 'xh'
}
console.log(foo.logName.call(bar))
1
2
3
4
5
6
7
8
9
10
查看答案

// xh
最终执行的使用,将this指向了bar,所以输出的是bar的name属性

# 10. 构造函数中的this指向

下面答案输出什么?

function Foo() {
  this.bar = 'xm'
}
const foo = new Foo()
console.log(foo.bar)
1
2
3
4
5
查看答案

// xm
构造函数内部的this指向new出来的foo实例对象

# 11. 构造函数中的this指向2

下面答案输出什么?

function Foo() {
  this.bar = 'xm'
  const o = {}
  return o
}
const foo = new Foo()
console.log(foo.bar)
1
2
3
4
5
6
7
查看答案

// undefined
如果构造函数返回一个对象,那么foo则等于返回的对象o,o中没有bar,所以是undefined

# 12. 构造函数中的this指向3

下面答案输出什么?

function Foo() {
  this.bar = 'xm'
  return 1
}
const foo = new Foo()
console.log(foo.bar)
1
2
3
4
5
6
查看答案

// xm
如果构造函数返回的不是一个对象,那么foo返回的是构造函数Foo的实例对象

# 13. this优先级

下面答案输出什么?

function foo(a) {
  console.log(this.a)
}
const obj1 = {
  a: 1,
  foo: foo
}
const obj2 = {
  a: 2,
  foo: foo
}
obj1.foo.call(obj2)
obj2.foo.call(obj1)
1
2
3
4
5
6
7
8
9
10
11
12
13
查看答案

// 2
// 1
显式绑定比隐式绑定的优先级更高,所以第一个this指向obj2,第二个this指向obj1

# 14. this优先级2

下面答案输出什么?

function foo(a) {
  this.a = a
}
const obj1 = {}

var bar = foo.bind(obj1)
bar(2)
console.log(obj1.a)
var baz = new bar(3)
console.log(baz.a)
1
2
3
4
5
6
7
8
9
10
查看答案

// 2
// 3

  1. 上述代码通过bind将foo的this指向obj1,执行bar(2)的使用,给obj1添加了一个值为2的属性a,所以打印obj1.a是2
  2. 尽管上面foo改了指向,但是new的优先级大于bind,new又修改了bind绑定的this指向,foo里面的this指向创建的实例baz,所以baz.a是3

# 15. 箭头函数this指向

下面答案输出什么?

const foo = {
  fn: function() {
    setTimeout(() => {
      console.log(this)
    })
  }
}
console.log(foo.fn())
1
2
3
4
5
6
7
8
查看答案

// {fn: ƒ}
箭头函数的this指向上级的this,这里this指的是foo

# 16. 箭头函数this指向2

下面答案输出什么?

function foo(a) {
  return a => {
    console.log(this.a)
  }
}
const obj1 = {
  a: 2
}

const obj2 = {
  a: 3
}

const bar = foo.call(obj1)
console.log(bar.call(obj2))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
查看答案

// 2
foo中this绑定到了obj1上,箭头函数的绑定无法更改,所以就算使用call也不行。

# 17. 箭头函数this指向3

下面答案输出什么?

var a = 123
const foo = () => a => {
  return a => {
    console.log(this.a)
  }
}
const obj1 = {
  a: 2
}

const obj2 = {
  a: 3
}

const bar = foo.call(obj1)
console.log(bar.call(obj2))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
查看答案

// 123
箭头函数的this指向外层的作用域,这里指的是window,且不能被call更改。

# 18. 箭头函数this指向4

下面答案输出什么?

const a = 123
const foo = () => a => {
  return a => {
    console.log(this.a)
  }
}
const obj1 = {
  a: 2
}

const obj2 = {
  a: 3
}

const bar = foo.call(obj1)
console.log(bar.call(obj2))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
查看答案

// undefined
箭头函数的this指向外层的作用域,const声明的变量不能挂载到window对象上,且不能被call更改,所以是undefined。

# 19. 箭头函数this指向5

下面答案输出什么?

const a = 13
const obj = {
  a: 12,
  b: () => {
    console.log(this.a)
  },
  c: function() {
    console.log(this.a)
  },
  d: function() {
    return () => {
      console.log(this)
    }
  },
  e: function() {
    return this.b
  }
}

obj.b()
obj.c()
obj.d()()
obj.e()()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
查看答案

// undefined
// 12
// {a: 12, b: ƒ, c: ƒ, d: ƒ, e: ƒ} // undefined

  1. 第一个,b虽然是方法调用,但是箭头函数的this指向外层作用域,外层作用域是window,const定义的变量不在window下,所以window下面没有a,返回undefined。
  2. 第二个,c是方法调用,this指向obj,所以是obj.a是12
  3. 第三个,d是方法调用,所以obj.d()中的this指的是obj,return里面是箭头函数,this指向外层,就是obj
  4. 第四个,e是方法调用,里面的return虽然也是箭头函数,但是this.b的作用域是window,因为箭头函数的this一旦确定不可更改,所以不可能变成obj,window下面没有a所以是undefined

# 20. arguments调用函数中的this指向

下面答案输出什么?

let length = 10
function fn() {
  console.log(this.length);
}
let obj = {
  length: 5,
  method(fn) {
    // 两次调用各输出什么
    fn()
    arguments[0](0)
  }
}
obj.method(fn, 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
查看答案

// 第一个输出的是当前window上挂载的iframe和frame框架数量 // 第二个输出2

  • 首先调用obj.method(fn, 1)这个语句的时候,fn是直接调用,里面的this指的是window,window.length指的是当前window上挂载的框架数量
  • 其次arguments调用函数,this指的是arguments,arguments.length指的是实参的数量,所以是两个
更新时间: 2022-04-10 13:23