zoukankan      html  css  js  c++  java
  • (三)我的JavaScript系列:不同调用方式的this指向

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

    今天所写的内容,是对之前的内容的总结和扩展。老实说,对于自己之前的一些杜撰和臆测,我并不是很满意。所以这篇博文,我希望能来点干货。

    不同调用方式的this指向

    在JavaScript中,我们可以用this来指代当前的对象。这种感觉就像使用Java一样。不过与Java不同的是,在Java中,this的指代总是很明显的;然而在JavaScript中,this的指代在不同的调用方式下,其指代往往不同。我为此分为四类:

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

    如果我们定义以下函数:

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

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

    2. 作为对象的方法调用,指代是调用对象本身

    如果我们将f作为一个对象的方法,也就是说作如下改造:

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

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

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

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

    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要把它们封装到一个数组里面去。

    从某种程度上说,前面的三种函数调用形式都是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]
    
  • 相关阅读:
    32位和64位系统区别及int字节数
    c语言指针占几个字节
    可重入和不可重入
    C中的volatile用法
    让你分分钟读懂CPU架构及芯片厂商
    手机CPU知识扫盲:谈谈手机CPU架构与原理 (全
    IO端口、IO内存、IO空间、内存空间的含义和联系
    IO端口和IO内存的区别及分别使用的函数接口
    linux终端下 编译c语言程序
    git各种撤销操作
  • 原文地址:https://www.cnblogs.com/starstone/p/4843965.html
Copyright © 2011-2022 走看看