(三)个人JavaScript系列:不一样调用方式的this指向

人生自是有情痴,此恨不关风与月javascript

今天所写的内容,是对以前的内容的总结和扩展。老实说,对于本身以前的一些杜撰和臆测,我并非很满意。因此这篇博文,我但愿能来点干货。java

不一样调用方式的this指向

在JavaScript中,咱们能够用this来指代当前的对象。这种感受就像使用Java同样。不过与Java不一样的是,在Java中,this的指代老是很明显的;然而在JavaScript中,this的指代在不一样的调用方式下,其指代每每不一样。我为此分为四类:数组

1. 做为函数调用,指代的是全局对象

若是咱们定义如下函数:app

function f() {
    console.log(this);
}

而后将其做为普通对象调用,即f(),此时this指代的是全局对象window。函数

2. 做为对象的方法调用,指代是调用对象自己

若是咱们将f做为一个对象的方法,也就是说做以下改造:this

var a = {};
a.f = f;

而后经过对象a调用方法f,即a.f(),此时this指代的就是调用者a。prototype

3. 做为构造器函数使用,指代的隐含的新建对象

若是咱们用new语句调用函数f,即new f(), 则此时this指代的是新建的对象。code

4. call和apply的方式

除了上述几种方式外,咱们还能够任意指定this的指代,这就是call和apply发挥做用的地方了。call和apply是每一个函数对象都拥有的方法,其第一个参数就是要指定的this值,后面是函数正常的参数值。其细微的差异在于参见下面的示例:对象

function g(name, age) {
    this.name = name;
    this.age = age
}

var a = {};

g.call(a, 'xiaoming', 18);
g.apply(a, ['xiaoming', 18]);

即call的非this参数只需在后面列出就能够了,apply要把它们封装到一个数组里面去。ip

从某种程度上说,前面的三种函数调用形式都是call方式的一种语法糖:

  1. f() === f.call(window)
  2. a.f() === f.call(a)
  3. new f() === var _a = {}; f.call(_a)

call有很强大的能力,咱们经常使用的函数借用就是利用call能够动态指定this这一特性的。例如Array.prototype.slice.call(a)能够将看起来像数组的对象a转化为实际的数组对象。

var a={length:2,0:'first',1:'second'};
Array.prototype.slice.call(a);//  ["first", "second"]
 
var a={length:2};
Array.prototype.slice.call(a);//  [undefined, undefined]
相关文章
相关标签/搜索