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

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

➢ this

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

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

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

        var o = {
name: 'o',
get: function () {
return this.name;
}
}
console.log(o.get());//输出'o'

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

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

        var o = {
name: 'o',
get: function () {
return this.name;
}
};
var g = o.get; //将o的get方法赋给g;
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指定绑定的对象。仅示例:

        var F = function () {
this.name = 'F';
};
var f=new F();

➢ apply和call

一、概述

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

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

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

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

示例1-1:

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

首次接触的时候有点点绕

示例1-2:

        function f() {
console.log(this.name);
}
var o = {
name: '对象o'
};
f.apply(o);

二、作用

1、改变this的指向

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

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

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

        function f() {
console.log(this.name);
}
var o = {
name: 'o'
};

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

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

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

        /***构造继承最简化的形式***/

        //父类
function subClass() {
this.name = 'subClass';
}
//子类
function superClass() {
subClass.call(this);
}
var o = new superClass();
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. php RSA加密传输代码示例(轉)

    原文地址:http://www.cnblogs.com/firstForEver/p/5803940.html 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可 ...

  2. JFinal Web开发学习(八)后台集成H-ui-admin前端框架

    h-ui-admin是一个很不错的前端框架h-ui实现的一个后台管理系统的前端. 1.在WebRoot目录下新建admin目录 2.下载h-ui-admin(当前最新是2.5版本)并解压至admin文 ...

  3. webstorm打开一个门户工程流程

    1.电脑上安装了nginx   ,进入conf目录下,找到nginx.conf打开 2.将原配置中server部分替换掉 server{ listen       80;     server_nam ...

  4. 基于.net技术的 Rss 订阅开发

    RSS(Really Simple Syndication,真正简单的连锁)是一种 Web 内容连锁格式.RSS 成为通过 Web 连锁新闻内容的标准格式.刚好我现在vs的环境也是.net,因为在.N ...

  5. Svn启动窗口报错 Could not load file or assembly 'SharpSvn.dll' or one of its

    win10 64位系统生成没问题,测试都没问题,结果换到win7 64位系统上,点开就出现,网上搜了下,通过以下方式解决, 必须把bin 文件夹全部删除,重新生成.要不还是会报错. Solve it. ...

  6. BZOJ1059或洛谷1129 [ZJOI2007]矩阵游戏

    BZOJ原题链接 洛谷原题链接 通过手算几组例子后,很容易发现,同一列的\(1\)永远在这一列,且这些\(1\)有且仅有一个能产生贡献,行同理. 所以我们可以只考虑交换列,使得每一行都能匹配一个\(1 ...

  7. Qt5+VS2010的安装及使用

    在我的博客<Win7下Qt5的安装及使用>中讲解了win7下Qt5+MinGW的安装及使用,本节再讲解win7下Qt5+VS2010的安装及使用.利用Qt5+MinGW开发应用程序比较麻烦 ...

  8. Shortest Unsorted Continuous Subarray LT581

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  9. rap2与postman自动化测试

    rap2的接口数据可以全部导入postman: 在collections集合里面点击run;

  10. Vue组件中引入jQuery

    一.安装jQuery依赖 在使用jQuery之前,我们首先要通过以下命令来安装jQuery依赖: npm install jquery --save # 如果你更换了淘宝镜像,可以使用cnpm来安装, ...