深入浅出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 是动态绑定,或称为运行期绑定的 ...
随机推荐
- php RSA加密传输代码示例(轉)
原文地址:http://www.cnblogs.com/firstForEver/p/5803940.html 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可 ...
- JFinal Web开发学习(八)后台集成H-ui-admin前端框架
h-ui-admin是一个很不错的前端框架h-ui实现的一个后台管理系统的前端. 1.在WebRoot目录下新建admin目录 2.下载h-ui-admin(当前最新是2.5版本)并解压至admin文 ...
- webstorm打开一个门户工程流程
1.电脑上安装了nginx ,进入conf目录下,找到nginx.conf打开 2.将原配置中server部分替换掉 server{ listen 80; server_nam ...
- 基于.net技术的 Rss 订阅开发
RSS(Really Simple Syndication,真正简单的连锁)是一种 Web 内容连锁格式.RSS 成为通过 Web 连锁新闻内容的标准格式.刚好我现在vs的环境也是.net,因为在.N ...
- Svn启动窗口报错 Could not load file or assembly 'SharpSvn.dll' or one of its
win10 64位系统生成没问题,测试都没问题,结果换到win7 64位系统上,点开就出现,网上搜了下,通过以下方式解决, 必须把bin 文件夹全部删除,重新生成.要不还是会报错. Solve it. ...
- BZOJ1059或洛谷1129 [ZJOI2007]矩阵游戏
BZOJ原题链接 洛谷原题链接 通过手算几组例子后,很容易发现,同一列的\(1\)永远在这一列,且这些\(1\)有且仅有一个能产生贡献,行同理. 所以我们可以只考虑交换列,使得每一行都能匹配一个\(1 ...
- Qt5+VS2010的安装及使用
在我的博客<Win7下Qt5的安装及使用>中讲解了win7下Qt5+MinGW的安装及使用,本节再讲解win7下Qt5+VS2010的安装及使用.利用Qt5+MinGW开发应用程序比较麻烦 ...
- Shortest Unsorted Continuous Subarray LT581
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- rap2与postman自动化测试
rap2的接口数据可以全部导入postman: 在collections集合里面点击run;
- Vue组件中引入jQuery
一.安装jQuery依赖 在使用jQuery之前,我们首先要通过以下命令来安装jQuery依赖: npm install jquery --save # 如果你更换了淘宝镜像,可以使用cnpm来安装, ...