深入浅出javascript(八)this、call和apply
_________此篇日志属于重要记录,长期更新__________
this,call,apply这三个是进阶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() { |
function f() { |
var o = { |
var o = { |
现在可以推断两条结论:
一、凡是普通函数都指向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的更多相关文章
- Javascript中call函数和apply函数的使用
Javascript 中call函数和apply的使用: Javascript中的call函数和apply函数是对执行上下文进行切换,是将一个函数从当前执行的上下文切换到另一个对象中执行,例如: so ...
- 深入浅出 JavaScript 对象 v0.5
JavaScript 没有类的概念,因此它的对象与基于类的语言中的对象有所不同.笔者主要参考<JS 高级程序设计>.<JS 权威指南>和<JS 精粹> 本文由浅入深 ...
- 从头开始学JavaScript (八)——变量
原文:从头开始学JavaScript (八)--变量 一.变量分类: 基本类型值:null.undefined.number.string.Boolean: 引用类型值:保存在内存中的对象,如:Obj ...
- 深入浅出 JavaScript 关键词 -- this
深入浅出 JavaScript 关键词 -- this 要说 JavaScript 这门语言最容易让人困惑的知识点,this 关键词肯定算一个.JavaScript 语言面世多年,一直在进化完善,现在 ...
- Javascript 中的 call 和 apply
发表于 2012年02月1日 by 愚人码头 原文链接:http://www.css88.com/archives/4431 JavaScript 中通过call或者apply用来代替另一个对象调 ...
- 深入浅出JavaScript之this
JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...
- 【转】深入浅出JavaScript之this
JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面是我的学习笔记 ...
- javascript中call函数与apply
javascript中的call方法使当前对象可以调用另一个对象的方法,即改变this的指向内容 var first_object = { num: 42 }; var second_object = ...
- 深入浅出 JavaScript 中的 this
在 Java 等面向对象的语言中,this 关键字的含义是明确且具体的,即指代当前对象.一般在编译期确定下来,或称为编译期绑定.而在 JavaScript 中,this 是动态绑定,或称为运行期绑定的 ...
随机推荐
- linux minitools+minicom 安装及使用
1,通过SSH将minitools的安装包传到ubuntu 文件下, 2, 解压minitools.tgz (具体方法见上一篇) 3,命令安装minicom : apt-get insta ...
- DOM心得
一.自定义属性值两种方法的注意事项 1.用元素节点.属性(元素节点[属性])绑定的属性值不会出现在标签上. 2.用get/set/removeAttribut(,)等绑定的属性会出现在标签上.且两种方 ...
- (转)EasyUI 分页总结
最近用到了easyui的分页和搜索栏功能,使用过程中由于运用不熟练导致其间也出现过一些问题,下面做个小结,供大家共同学习.1.首先使用EasyUI 的DataGrid分页,得加载其js类库:< ...
- eclipse中增加多个Tomcat
一.在eclipse中新增Tomcat,并增加在其上部署的工程 1.打开eclipse,并选择菜单中的 "Window" ---> "Show View" ...
- 利用gulp搭建less编译环境
什么是less? 一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, ...
- Hotspot参数分析
-XX:+HeapDumpOnOutOfMemoryError 让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析 -Xmx与-Xms 虚拟机堆参数 -Xoss 设置本地方法栈 ...
- Linux 内核态与用户态通信 netlink
参考资料: https://blog.csdn.net/zqixiao_09/article/details/77131283 https://www.cnblogs.com/lopnor/p/615 ...
- Spring Environment(二)源码分析
Spring Environment(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Envi ...
- JS closure
闭包的概念 闭包,不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍可访问非本地变量. --维基百科 闭包就是能够读取其他函数内部变量的函数. --阮一峰 由于在Javascript语言中, ...
- spring学习 六 spring与mybatis整合
在mybatis学习中有两种配置文件 :全局配置文件,映射配置文件.mybatis和spring整合,其实就是把mybatis中的全局配置文件的配置内容都变成一个spring容器的一个bean,让sp ...