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

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. go语言使用go-sciter创建桌面应用(三) 事件处理,函数与方法定义,go与tiscript之间相互调用

    sciter处理脚本tiscript,用于处理UI交互中的一些逻辑,跟js很像,但又有点区别,对前端熟悉的人应该能很快上手. tiscrip脚本文档 https://sciter.com/develo ...

  2. C#使用MiniDump捕获异常

    c/c++语言里MiniDump是一个重要的调试手段,他们没有C#/java这样语言有很多异常输出信息( JVM异常导出bug日志功能,通常在jdk目录,文件格式hs_err_%pid%.log,pi ...

  3. [转]slf4j 与log4j 日志管理

    log4j简易入门 package test.log4j; import org.apache.log4j.Logger; public class HelloLog4j { private stat ...

  4. python 计时程序运行时间

    import time time_start=time.time() time_end=time.time() print('totally cost',time_end-time_start)

  5. python Trie树和双数组TRIE树的实现. 拥有3个功能:插入,删除,给前缀智能找到所有能匹配的单词

    #coding=utf- #字典嵌套牛逼,别人写的,这样每一层非常多的东西,搜索就快了,树高26.所以整体搜索一个不关多大的单词表 #还是O(). ''' Python 字典 setdefault() ...

  6. activiti5.22整合modeler时出错TypeError: Cannot read property 'split' of undefined

    activiti5.22.0整合modeler时,打开的流程页面不显示工具栏和左边的控件栏,产生如下的错误: TypeError: Cannot read property 'split' of un ...

  7. 如何在Android平台上使用USB Audio设备

    http://blog.csdn.net/kevinx_xu/article/details/12951131 需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset ...

  8. NOIP2017普及组T2题解

    还是神奇的链接 上面依然是题目. 这道题依然很简单,比起2015年的普及组t2好像还是更水一些. 不过这道题能讲的比第一题多. 我们一起来看一下吧! 这一题,我们首先将书的编号全部读入,存在一个数组里 ...

  9. 20155312张竞予 20170510实践一:在IDEA中以TDD的方式对String类和Arrays类进行学习

    实践题目 在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常,错误和边界情况 String类 charAt split Arrays类 sort binarySea ...

  10. 20155312 2006-2007-2 《Java程序设计》第三周学习总结

    20155312 2006-2007-2 <Java程序设计>第三周学习总结 课堂内容总结 yyp复制上一行代码 5不是false statistics.sh换成.bat就可以在windo ...