_________此篇日志属于重要记录,长期更新__________

thiscallapply这三个是进阶JS的重要一步,需要详细的记录。

➢ this

一、作为对象的方法调用。

当函数作为对象方法被调用时,this指向该对象。

首先,函数必须作为对象的方法。这句话很关键,因为函数的调用有很多种可能,在后面会展现。示例1-1:

  1. var o = {
  2. name: 'o',
  3. get: function () {
  4. return this.name;
  5. }
  6. }
  7. console.log(o.get());//输出'o'

get方法是被对象o调用的,所以this指向o,这是没有异议的。

现在把这个例子改下,示例1-2:

  1. var o = {
  2. name: 'o',
  3. get: function () {
  4. return this.name;
  5. }
  6. };
  7. var g = o.get; //将o的get方法赋给g;
  8. console.log(g()); //输出空;

o.get方法赋给g之后,现在这个方法g和原来的对象o已经没有关系了,因为g是全局的,所以它属于window的方法,结果导致方法内的this已经指向window,又,window没有定义name属性,所以输出为空。

从这两个例子的对比可以看出,this是随机而动的,谁绑定,this就指向谁。

二、做为普通函数调用

这里所说的普通函数调用主要是为了和狭隘的 ' 对象的方法调用 ' 来区别。因为无论函数怎么调用,它总属于一个对象,因为最外层总有一个window对象。

如上例所示,将函数赋值给另一个变量,就是将这个函数从对象中 ’ 复制一份 ‘ 出来,结果变成window对象的一个方法,因此this指向window。

示例2-1

1.创建变量o,因为是全局的,所以内部的this为window,其内部的g也属于普通函数调用,因此也指向this。

三、函数到底出现在哪儿?

函数到底出现在哪里,说的是函数究竟出现在哪种地方,只有将出现的这几种地方弄明白,才能对函数做更深入的了解,总结如下:

1 普通函数
2 普通函数内部的普通函数
3 对象内部
4 对象内部的函数的内部

➢ 四种可能:

普通函数

this=window

普通函数内部的普通函数

this=window

对象内部函数

this=对象

对象内部函数内部的普通函数

this=window

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

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

var o = {
  get: function () {
    console.log(this);
  }
};

var o = {
  get: function () {
    function g() {
      console.log(this);
    }
  }
};

现在可以推断两条结论:

一、凡是普通函数都指向window
二、凡是对象调用都指向对象。(这里的对象是狭隘的对象,即自创建的对象)

换句话说,凡遇到一个函数,首先两问:

一、这个函数是普通函数吗?[如果是,则this=window]

二、这个函数是被对象调用的吗?[如果是,则this=对象]

※ 回过头再看前面的一句话:当函数作为对象方法被调用时,this指向该对象,也就可以理解了。

四、做为构造函数

做为构造函数比较简单,this指定绑定的对象。仅示例:

  1. var F = function () {
  2. this.name = 'F';
  3. };
  4. var f=new F();

➢ apply和call

一、概述

apply就是函数调用,而调用的就是函数fn,也就是说执行fn( )。 apply后面是(对象,参数)。参数可以是数组,可以是类数组。

所以理解这个apply就是记住两个点:

1.调用函数fn.
2.传入对象,如果传入的对象为null,则this=window

apply概括:调用函数fn,fn需要依赖传入的对象来确定它内部的this到底指向谁。

示例1-1:

  1. window.name = 'window';
  2. function f() {
  3. console.log(this.name);
  4. }
  5. f.apply(null); //输出'window'

首次接触的时候有点点绕

示例1-2:

  1. function f() {
  2. console.log(this.name);
  3. }
  4. var o = {
  5. name: '对象o'
  6. };
  7. f.apply(o);

二、作用

1、改变this的指向

首先,这个this指的是谁呢?肯定是fn内部的this。如果函数没有this,那又何谈改变this的指向呢。现在先做一个带有this的函数。

  1. function f() {
  2. console.log(this.name);
  3. }

this是可以随意绑定的,这就是apply的作用,做个图示例一下:

  1. function f() {
  2. console.log(this.name);
  3. }
  4. var o = {
  5. name: 'o'
  6. };

如上代码所示,f.apply(o),f内部的this绑定了对象o。

2、借用其它对象的方法——继承

这种继承是继承方法中的一种 [ 关于Javascript继承详细,参看记录 ],其实说起来更像是 ‘复制’。即:将父类中的属性复制一份到子类,代码2-1:

  1. /***构造继承最简化的形式***/
  2.  
  3. //父类
  4. function subClass() {
  5. this.name = 'subClass';
  6. }
  7. //子类
  8. function superClass() {
  9. subClass.call(this);
  10. }
  11. var o = new superClass();
  12. console.log(o.name); //输出'subclass'

➢ 代码解析:

子类构造函数使用父类.call,并将子类自己的this代入,结果就是将父类的属性 '复制' 了一份给子类。

3、类数组的使用(重要!)

补充于2018-10-23 20:12:51


类数组一个比较常见的例子是arguments。这个东西像数组但又不是数组,如果采用一般的数组方法是不可行的,必须采用数组的call调用。

示例如下:

arguments.join(","),#这条语句希望将函数参数用","连接起来形成字符串,但是代码错误不能通过。这里采用Array原型方法调用:

Array.prototype.join.call(arguments,",");

这一条的应用比较常用且重要,也是采用call调用的一个比较独特的例子。

4、

深入浅出javascript(八)this、call和apply的更多相关文章

  1. Javascript中call函数和apply函数的使用

    Javascript 中call函数和apply的使用: Javascript中的call函数和apply函数是对执行上下文进行切换,是将一个函数从当前执行的上下文切换到另一个对象中执行,例如: so ...

  2. 深入浅出 JavaScript 对象 v0.5

    JavaScript 没有类的概念,因此它的对象与基于类的语言中的对象有所不同.笔者主要参考<JS 高级程序设计>.<JS 权威指南>和<JS 精粹> 本文由浅入深 ...

  3. 从头开始学JavaScript (八)——变量

    原文:从头开始学JavaScript (八)--变量 一.变量分类: 基本类型值:null.undefined.number.string.Boolean: 引用类型值:保存在内存中的对象,如:Obj ...

  4. 深入浅出 JavaScript 关键词 -- this

    深入浅出 JavaScript 关键词 -- this 要说 JavaScript 这门语言最容易让人困惑的知识点,this 关键词肯定算一个.JavaScript 语言面世多年,一直在进化完善,现在 ...

  5. Javascript 中的 call 和 apply

    发表于 2012年02月1日 by 愚人码头   原文链接:http://www.css88.com/archives/4431 JavaScript 中通过call或者apply用来代替另一个对象调 ...

  6. 深入浅出JavaScript之this

    JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...

  7. 【转】深入浅出JavaScript之this

    JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...

  8. javascript中call函数与apply

    javascript中的call方法使当前对象可以调用另一个对象的方法,即改变this的指向内容 var first_object = { num: 42 }; var second_object = ...

  9. 深入浅出 JavaScript 中的 this

    在 Java 等面向对象的语言中,this 关键字的含义是明确且具体的,即指代当前对象.一般在编译期确定下来,或称为编译期绑定.而在 JavaScript 中,this 是动态绑定,或称为运行期绑定的 ...

随机推荐

  1. Ubuntu 16.04 更换阿里源

    vim /etc/apt/source.list deb-src http://archive.ubuntu.com/ubuntu xenial main restricted #Added by s ...

  2. Ionic3--数据存储

    1.使用sqlite cordova plugin add cordova-sqlite-storage --save npm install --save @ionic/storage (本地存储) ...

  3. MySql数据库 sql查询增加序号的伪列

    在查询数据库的时候,我们有时候需要对查询出来的数据加上序列,1,2,3,……n 例如:我们根据表的某个字段排序后,要对这些数据加上序列,这个时候序号常常不是我们建表时设置好的自增的主键id,怎么办呢? ...

  4. Business.Startup.Learning from Startup Mistakes at SpringSource

    http://www.infoq.com/news/2014/07/startup-spring

  5. 浅谈多重检验校正FDR

    浅谈多重检验校正FDR Posted: 四月 12, 2017  Under: Basic  By Kai  no Comments 例如,在我们对鉴定到的差异蛋白做GO功能注释后,通常会计算一个p值 ...

  6. 网页启用Gzip压缩 提高浏览速度

    启用Gzip压缩的好处 它的好处显而易见,提高网页浏览速度,无论是之前说的精简代码.压缩图片都不如启用Gzip来的实在.下图为启用Gzip后的效果. Gzip压缩效率非常高,通常可以达到70%的压缩率 ...

  7. [JAVA]多线程下如何确定执行顺序性

    最近在讨论一个下载任务:要求文件下载后进行打包,再提供给用户下载: 如何确保打包的线程在所有下载文件的线程执行完成后进行呢? 看看下面三个兄弟的本事: CountDownLatch.CyclicBar ...

  8. java进行3DES加解密

    import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.Secre ...

  9. 利用PHP脚本辅助MySQL数据库管理3-删除重复表索引

    <?php $dbi = new DbMysql; $dbi->dbh = 'mysql://root:mysql@127.0.0.1/coffeetest'; $map = array( ...

  10. SQL 中的Begin...End语句

    Begin...End通常用来表示一个语句块,其内部的代码可以包含一组T-SQL语句,可以理解为高级语言中的{},这样在使用while循环时才知道判断什么时候结束.