深入浅出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 是动态绑定,或称为运行期绑定的 ...
随机推荐
- ThreadExecutorPool 线程池组件
ThreadExecutorPool是使用最多的线程池组件: Executor是用来执行提交的Runnable任务的对象,并以接口的形式定义,提供一种提交任务(submission task)与执行任 ...
- CSS day49
前端基础之CSS CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). CS ...
- jquery 进阶 bootstrap
. 样式操作 . 操作class . 操作CSS属性的 .css("color") .css("color", "green") .css( ...
- eclipse Tomcat和 MYSQL JAVA web新手开发示例--登录界面连接数据库
登录界面login.jsp 1 <%@ page language="java" import="java.util.*" contentType=&qu ...
- virtaulbox docker虚拟机使用主机代理shandowsocks
1.virtaulbox 配置NatNetwork File->Preference->network->add new nat network 2.virtaulbox 虚拟机配置 ...
- L1-030 一帮一(15)(代码)
L1-030 一帮一(15 分) "一帮一学习小组"是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组.本题就请你编写程序帮助老师自动完成这个分配工 ...
- Java.WeakReference-SoftReference-PhantomReference
Weak Reference, Soft Reference, Phantom Reference 1. Introduction "Weak reference objects, whic ...
- gdal source code c++ make windows
下载源码 GDAL源代码下载地址:http://trac.osgeo.org/gdal/wiki/DownloadSource,或者安装svn从源代码服务器下载,svn地址是:http://svn.o ...
- uuid唯一吗
是唯一的.我在几台硬件完全相同(同一批购买的).软件也完全相同(用同一个GHOST系统安装)的电脑上试过: 不同的电脑上,wmic csproduct get uuid 获取的UUID码是不同的.另 ...
- java CyclicBarrier的介绍和使用
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarri ...