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

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

不同调用方式的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]

(三)我的JavaScript系列:不同调用方式的this指向的更多相关文章

  1. JavaScript系列:函数调用方式

    有关JS的问题,持续更新.. 一,函数调用的4种方式 1,函数调用模式 //下面这种模式叫 “函数调用模式”:窗后window来调用 //函数调用四种方式的基础 //这tm不就是作用域this的问题吗 ...

  2. (一)我的Javascript系列:Javascript的面向对象旅程(上)

    今宵酒醒何处,杨柳岸,晓风残月 导引 我的JavaScript系列文章是我自己对JavaScript语言的感悟所撰写的系列文章.现在还没有写完.目前一共出了下面的系列: (三)我的JavaScript ...

  3. 【转】SVG与HTML、JavaScript的三种调用方式

    原文:https://www.cnblogs.com/guohu/p/5085045.html SVG与HTML.JavaScript的三种调用方式 一.在HTMl中访问SVG的DOM 1 2 3 4 ...

  4. javascript系列之DOM(三)---事件

    原文:javascript系列之DOM(三)---事件 事件是javascript跳动的心脏,是DOM所有成分结合的万金油.当我们在WEB 上进行某些交互时,事件也就发生了.点击某些内容,鼠标经过特定 ...

  5. JavaScript 系列博客(三)

    JavaScript 系列博客(三) 前言 本篇介绍 JavaScript 中的函数知识. 函数的三种声明方法 function 命令 可以类比为 python 中的 def 关键词. functio ...

  6. 深入理解javascript系列(4):立即调用的函数表达式

    本文来自汤姆大叔 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法 ...

  7. Javascript中函数的四种调用方式

    一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...

  8. [JS]深入理解JavaScript系列(4):立即调用的函数表达式

    转自:汤姆大叔的博客 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.在详细了解这个之前,我们来谈了解一下"自执行"这个叫法 ...

  9. Solidity的三种合约间的调用方式 call、delegatecall 和 callcode

    0x00 前言 Solidity(http://solidity.readthedocs.io/en/v0.4.24/) 是一种用与编写以太坊智能合约的高级语言,语法类似于 JavaScript. S ...

随机推荐

  1. 使用superobject 解析Json数据

    接口数据有如下规范{"error": 0, "msg": "", "data": ...} 其中数据data类型不确定. ...

  2. 【技巧】断点调试你的express项目

    目录(?)[-] 写在前面 node-inspector 全局安装node-inspector 以debug模式开启express服务 启动node-inspector 调试NodeJS程序   写在 ...

  3. 3-C++程序的结构1.5

    多文件结构和编译预处理命令 1.c++程序的一般组织结构 通常一个项目至少划分为三个文件:类定义文件(*.h文件).类实现文件(*.cpp文件)和类的使用文件(*.cpp,主函数文件).如下: 这三个 ...

  4. 下拉选择select和复选框checkbox的状态的各种方式

    复选框的状态 <input name="ck" value=" " type="checkbox"  checked> 或者&l ...

  5. 快速部署Kubernetes集群管理

    这篇文章介绍了如何快速部署一套Kubernetes集群,下面就快速开始吧! 准备工作 //关闭防火墙 systemctl stop firewalld.service systemctl disabl ...

  6. Microsoft EBooks

    Go pick up what you are interested J http://blogs.msdn.com/b/mssmallbiz/archive/2014/07/07/largest-c ...

  7. MVC+NHibernate笔记

    Nhibernate 要求model实体类对于lazy="true" ,字段属性前需要加 virtual sqlserver2005和oracle10g的hibernate.cfg ...

  8. 699. Falling Squares

    On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...

  9. ubuntu18.04安装配置opencv3.4.0

    1.安装配置相关工具及依赖库 sudo apt-get install build-essential # 必须的,gcc编译环境 sudo apt-get install cmake git lib ...

  10. [Xcode 实际操作]六、媒体与动画-(13)使用UIImageView制作帧动画

    目录:[Swift]Xcode实际操作 本文将演示如何将导入的序列图片,转换为帧动画. 在项目导航区打开资源文件夹[Assets.xcassets] [+]->[Import]->选择图片 ...