Skip to content

Latest commit

 

History

History
82 lines (53 loc) · 3.08 KB

this-in-function.md

File metadata and controls

82 lines (53 loc) · 3.08 KB

"THIS" in Functon

function 里的 this 在不同的时候,会有不同的表现,一般会有以下四种情况

  • Invocation as a function
  • Invocation as a method
  • Invocation as a constructor
  • Invocatuon with the apply() and call() method

Invocation as a Function

这是最常见最普遍的一种,一般的形式是这样的

function ninja () {}
ninja();

var samurai = function () {};
samurai();

但这样子调用的时候,函数的上下文,也就是 this 的指向就是全局,即 window

Invocation as a method

当函数是一个对象的属性时并且通用该属性调用这个函数的时候,就是这种情况,像这样

var o = {};
o.whatever = function () {};
o.whatever();

这个时候,this 的指向就是对象 o

Invocation as a constructor

当我们把一个函数当作构造器的时候调用的时候,我们用 new 这个关键字

function Creep () {
      return this;
}
var creep = new Creep();

当我们想上面这个调用函数的时候,会有下面几个特殊的动作发生

  • 一个新的空对象会被创建 var o = {};
  • 这个对象会被传到这个构造器中的当作 this,所以这个对象就变成了此时构造器的上下文
  • 当返回值不是一个对象的时候,这个对象就会被返回

如果你在调用构造器函数的时候忘记了在前面加上 new 前缀,那个 this 将不会被绑定到一个新的对象上, this 将被绑定到全局对象 window 上,所以你不但没有扩充新对象,反而破坏了全局变量环境。

Invocation with the apply() and call() method

当我们想把函数的上下文换成我们任意的想要的时候,我们就可以用 apply()call() 方法

没错,函数也是有方法的,就像其他对象一样

  • apply() 方法接受两个参数,第一个是我们想要函数执行的上下文,第二个是执行这个函数的参数数组
  • call() 方法可以接受任意多个参数,第一个和 apply() 的一样,而后面的任意个参数就是执行这个函数的参数

How do we decide which to use?

回答这一类问题的一个高层次的答案就是,我们会用使用更能提高我们代码可读性的那一个方法。但更为实际的答案就是,我们会根据我们拿到的参数类型来决定我们使用哪个方法

如果我们拿到的参数是一串变量,call() 方法就可以让我们直接把他扔进去,如果我们拿到的参数已经是一个数组了,那很显然 apply() 会是更好的选择

Summary

函数可以通过多种方式去调用,不同的方式决定了上下文的不同,也就是 this 的指向

  • 当函数普通调用的时候,上下文就是全局变量 window
  • 当函数当成方法调用的时候,上下文就是拥有这个方法的对象
  • 当函数当成构造器成调用的时候,上下文就是刚刚分配的新对象
  • 当通过 apply()call() 调用的时候,上下文就是你传进去的第一个参数

Reference

Secrets of JavaScript Ninja