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

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

不同调用方式的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. Docker入门(四):服务(Services)

    这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...

  2. algorithm-exercise

    https://github.com/billryan/algorithm-exercise Part I - Basics Basic Data Structure string: s2 = &qu ...

  3. java&nbsp;获取路径与各文件目录的…

    java 获取路径 博客分类: MyJava JavaJSPWebTomcat编程  转至:http://geeksun.iteye.com/blog/356339 (1).request.getRe ...

  4. 2014-10-22 NOIP模拟赛

    1 1 .传教士 (bishop) 问题描述:panzhili 王国的疆土恰好是一个矩形,为了管理方便,国王 jjs 将整个疆土划分成 N*M 块大小相同的区域.由于 jjs 希望他的子民也能信教爱教 ...

  5. [NOIP2012] 摆花

    1270. [NOIP2012] 摆花 http://cogs.pro/cogs/problem/problem.php?pid=1270 ★   输入文件:flower.in   输出文件:flow ...

  6. Node.js 内置模块crypto加密模块(2) AES

    AES:高级加密标准 ( Advanced Encryption Standard ) AES是一种对称加密算法:加密需要密钥,且加密密钥和解密密钥相同 下面是AES加密的Node实现: " ...

  7. Spring包的依赖关系以及提供下载

    https://www.jianshu.com/p/5b0c96975164 这篇简书叙述的很完整 一下是个人整和的炸包,里面有很全面的Spring包, 还有一些其他包,都是官网下载 emmmm... ...

  8. VxWorks实验六 基于优先级的抢占式调度及实验的源程序和实验步骤

    基于优先级的抢占式调度及实验的源程序和实验步骤 1 实验目的    1.学习并验证基于优先级的抢占式调度2 实验内容    在实验一建立的 project 中,创建3 个任务,对这三个任务使用基于优先 ...

  9. STP-8-RSTP中的提议/同意过程

    连接中断原因也可能是增加了新的链路,导致其中一台交换机重新选举根端口,最终认为新链路所连端口是根端口,RSTP在点到点链路上使用提议/同意(Proposal/Agreement)过程,让类似这种链路迅 ...

  10. 微信小程序 笔记

    1.Input 输入控件 <input type='digit' placeholder='0.00'></input> 如果要使用单纯的数字控件,使那么可以将type设置为d ...