这边讲的是 JavaScript 的函数调用和 this

记读<<JavaScript语言精粹>>

不敢跳过,毕竟这个是 THE REAL GOOD PART OF JAVASCRIPT | XP 看完发现自己大部分也差不多了解了, 这个里面的火车图有点想吐槽啊...看得一愣一愣的...

函数调用的几种模式

  1. 方法调用(Method Invocation)
  2. 函数调用(Function Invocation)
  3. 构造函数调用(Constructor Invocation)
  4. apply 和 call 调用(Apply And Call Invocation)

方法调用函数调用构造函数调用的区别

方法调用 Method Invocation

var obj = {
  value: 0,
  increment: function() {
    this.value++
    //  this --> obj
  },
}
obj.increment()

函数调用

fucntion add( a, b ){
  return a + b;
}
add(1,2);  //函数调用

构造函数调用

混合了经典的面向对象的语法和自身原型性质(C++和 Java 中,实例是通过使用new操作符生成)

var instance = function() {
  return {
    name: "Nexus",
    model: "5x",
  }
}
var inst1 = new instance()

函数调用和 this

由于 js 一开始的设计缺陷,导致存在这个 bug:函数调用模式中 this 会指向一个全局变量window.xxx

'错误'代码

var value = 500
var obj = {
  value: 0,
  increment: function() {
    alert(this.value) //0  方法调用模式

    var innerFunction = function() {
      alert(++this.value) //501 函数调用模式
    }
    innerFunction()
  },
}
obj.increment()

运行之后可以很明显的看出来第二个 alert 居然指向了全局的变量 window.value 原因已经在上文中谈到

代码改进

利用 js 函数内声明的变量会存在运行域这个特性,来构造一个 that(约定俗成的一个变量名了= =)

var value = 500
var obj = {
  value: 0,
  increment: function() {
    alert(this.value) //0
    var that = this
    var innerFunction = function() {
      alert(++that.value) //1
    }
    innerFunction()
  },
}
obj.increment()

Reference

JavaScript: Function Invocation Patterns CoffeeXu