1 隐式this的确定规则

  • 函数的简单调用,this表示window/global对象(严格模式为undefined
    • fn(1, 2) <=> fn.call(undefined, 1, 2)
  • 通过对象调用方法时,this表示该对象
    • obj.method('hi') <=> Obj.method.call(obj, 'hi')
  • 箭头函数不接收this作为参数,由外层作用域决定
  • new关键字调用函数(构造函数)时,函数体内的this表示实例对象

2 例题

2.1 请描述以下代码的运行结果

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

    • 由o1对象执行method方法,method中的this指向o1对象,输出’o1'
    • 执行o2对象的method方法,最终调用的还是o1对象的method方法,由o1执行,this指向仍为o1对象,输出’o1'
    • 执行o3对象的method方法,最终直接调用method方法,此时this指向window对象,输出’undefined'
  • 如果想让第二句输出o2,不利用call/bind/apply,可以怎样改写

    1
    2
    3
    4
    5
    6
    
    const o2 = {
    	text: 'o2',
    	method: o1.method
    	// 将o1的method直接挂载到o2对象上,method最终作为o2的方法被调用
    }
    console.log(o2.method())
    

2.2 构造函数和this

  • 构造函数的this指向实例对象,但如果构造函数中出现了显式return的情况,需要分情况讨论

    • 如果构造函数显示地返回一个值,且返回的是一个对象(复杂类型),那么this就指向这个返回的对象;

      1
      2
      3
      4
      5
      6
      7
      
      function A(){
      	this.name = 'a'
      	const o = {}
      	return o
      }
      const a = new A()
      console.log(a.name)// undefined
      
    • 如果返回的不是一个对象(基本类型),那么this仍然指向实例

      1
      2
      3
      4
      5
      6
      
      function A(){
      	this.name = 'a'
      	return 1
      }
      const a = new A()
      console.log(a.name)// 'a'
      

2.3 箭头函数与this