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

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

不同调用方式的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. [Forward]Improving Web App Performance With the Chrome DevTools Timeline and Profiles

    Improving Web App Performance With the Chrome DevTools Timeline and Profiles We all want to create h ...

  2. 清除@SessionAttributes 网站实现退出登录

    在网站实现登录时,我认识了@SessionAttributes,对我来说是真的好用,@SessionAttributes注解可以使得模型中的数据存储一份到session域中. 这样在页面跳转时可以直接 ...

  3. shader之顶点着色器

    Vertex Shader 是渲染管道中一个可编程的模块,用于处理独立的顶点.Vertex Shader接收Vertex Attribute Data,由定点数组对象通过渲染指令来生成. Vertex ...

  4. Celery 基本使用

    1. 认识 Celery Celery 是一个 基于 Python 开发的分布式异步消息任务队列,可以实现任务异步处理,制定定时任务等. 异步消息队列:执行异步任务时,会返回一个任务 ID 给你,过一 ...

  5. C#Timer停不住

    System.Timers.Timer timer1 = new System.Timers.Timer(); timer1.Interval = ; //1天循环一次 timer1.Elapsed ...

  6. 微信公众号授权登录,提示“redirect_uri 参数错误”

    做微信公众号开发授权登录的时候遇到的坑... 后台服务用node,index.js相关代码如下: const oauth = new OAuth(conf.appid, conf.appsecret) ...

  7. Python 获取页面title

    #!/usr/bin/python #coding=utf- #urllib2是python自带的模块,在python3.x中被改为urllib.request import urllib.reque ...

  8. 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)

    传送门 式子好麻烦orz……大佬好腻害orz->这里 //minamoto #include<iostream> #include<cstdio> #define ll ...

  9. git配置命令

    一.Git安装及密钥的生成 1.下载Git软件:http://msysgit.github.io/ 2.桌面右键 Git Bash Here 打开git命令行: 3.ssh-keygen -t rsa ...

  10. java基础第六篇之常用思想、封装、继承和多态

    a.累加求和思想:求1~100的和,求数组/集合中元素的和,求偶数的数,求总分 int sum=0//循环外部定义sum变量,循环里面对每个元素累加 for (; ; ) { //sum+=数据 } ...