学习JavaScript之this,call,apply(转)
转自: http://www.h5cn.com/js/jishu/2016/0128/17884.html
在之前的JavaScript学习中,this,call,apply总是让我感到迷惑,但是他们的运用又非常的广泛。遂专门花了一天,来弄懂JavaScript的this,call,apply。中途参考的书籍也很多,以《JavaScript设计模式与开发实践》为主,《JavaScript高级程序设计》、《你不知道的JavaScript》为辅。这三本书对我理解this,call,apply都起了很大的帮助。
this
首先,我们先讲述this。
在《JavaScript设计模式与开发实践》关于this的描述中,我认为有一句话切中了this的核心要点。那就是:
JavaScript的this总是指向一个对象
具体到实际应用中,this的指向又可以分为以下四种:
作为对象的方法调用
作为普通函数调用
构造器调用
apply和call调用
接下来我们去剖析前3点,至于第4点的apply和call调用,会在call和apply部分详细讲解。
1.作为对象的方法调用
说明:作为对象方法调用时,this指向该对象。举例:
/**
* 1.作为对象的方法调用
*
* 作为对象方法调用时,this指向该对象。
*/
var obj = {
a: 1,
getA: function {
console.log(this === obj);
console.log(this.a);
}
};
obj.getA; // true , 1
2.作为普通函数调用
说明:作为普通函数调用时,this总是指向全局对象(浏览器中是window)。举例:
/**
* 2.作为普通函数调用
*
* 不作为对象属性调用时,this必须指向一个对象。那就是全局对象。
*/
window.name = 'globalName';
var getName = function {
console.log(this.name);
};
getName; // 'globalName'
var myObject = {
name: "ObjectName",
getName: function {
console.log(this.name)
}
};
myObject.getName; // 'ObjectName'
// 这里实质上是把function {console.log(this.name)}
// 这句话赋值给了theName。thisName在全局对象中调用,自然读取的是全局对象的name值
var theName = myObject.getName;
theName; // 'globalName'
3.构造器调用
说明:作为构造器调用时,this指向返回的这个对象。举例:
/**
* 3.作为构造器调用
*
* 作为构造器调用时,this指向返回的这个对象。
*/
var myClass = function {
this.name = "Lxxyx";
};
var obj = new myClass;
console.log(obj.name); // Lxxyx
console.log(obj) // myClass {name: "Lxxyx"}
但是如果构造函数中手动指定了return其它对象,那么this将不起作用。如果return的是别的数据类型,则没有问题。
var myClass = function {
this.name = "Lxxyx";
// 加入return时,则返回的是别的对象。this不起作用。
return {
name:"ReturnOthers"
}
};
var obj = new myClass;
console.log(obj.name); // ReturnOthers
Call和Apply
Call和Apply的用途一样。都是用来指定函数体内this的指向。
Call和Apply的区别
Call:第一个参数为this的指向,要传给函数的参数得一个一个的输入。Apply:第一个参数为this的指向,第二个参数为数组,一次性把所有参数传入。
如果第一个参数为null,则this指向调用的本身。
1.改变this指向
说明:这是call和apply最常用的用途了。用于改变函数体内this的指向。举例:
var name = "GlobalName"
var func = function {
console.log(this.name)
};
func; // "GlobalName"
var obj = {
name: "Lxxyx",
getName: function {
console.log(this.name)
}
};
obj.getName.apply(window) // "GlobalName" 将this指向window
func.apply(obj) // "Lxxyx" 将this指向obj
2.借用其它对象的方法
这儿,我们先以一个立即执行匿名函数做开头:
(function(a, b) {
console.log(arguments) // 1,2
// 调用Array的原型方法
Array.prototype.push.call(arguments, 3);
console.log(arguments) // 1,2,3
})(1,2)
函数具有arguments属性,而arguments是一个类数组。
但是arguments是不能直接调用数组的方法的,所以我们要用call或者apply来调用Array对象的原型方法。
原理也很容易理解,比如刚才调用的是push方法,而push方法在谷歌的v8引擎中,源代码是这样的:
function ArrayPush {
var n = TO_UINT32(this.length); // 被push对象的长度
var m = % _ArgumentsLength; // push的参数个数
for (var i = 0; i < m; i++) {
this[i + n] = % _Arguments(i); // 复制元素
}
this.length = n + m; //修正length属性
return this.length;
}
它只与this有关,所以只要是类数组对象,都可以调用相关方法去处理。
这部分内容比较复杂,再加上自己水平也不太够。所以推荐有条件的同学去购买相关书籍,或者等我的后续博客文章。
感想
通过对这部分的学习,算是加深了对JavaScript的理解。最直观的表现就是,去看一些优秀框架的源代码时,不再是被this,call,apply,bind绕的晕乎乎的。还是很开心的~
学习JavaScript之this,call,apply(转)的更多相关文章
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- 如何从源码中学习javascript
艾伦说啊,学习javascript,必须要学会看源码,通过高手的源码,你可以从中吸取很多书本上难以看到的技巧. 看源码就好像喝鸡汤,所有的营养都在这汤里了.这汤就是源码,高手写的源码,就是最好的鸡汤. ...
- 学习javascript基础知识系列第二节 - this用法
通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...
- 学习javascript 的一点感想
原文:学习javascript 的一点感想 //动态性是指,在一个Javascript对象中,要为一个属性赋值,我们不必事先创建一个字段,只需要在使用的时候做赋值操作即可,如下例:var obj=ne ...
- 从 prototype.js 深入学习 javascript 的面向对象特性
从 prototype.js 深入学习 javascript 的面向对象特性 js是一门很强大的语言,灵活,方便. 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽. 不过我接触的动态 ...
- 如何理解并学习javascript中的面向对象(OOP) [转]
如果你想让你的javascript代码变得更加优美,性能更加卓越.或者,你想像jQuery的作者一样,写出属于自己优秀的类库(哪怕是基于 jquery的插件).那么,你请务必要学习javascript ...
- Javascript中call()和apply()的用法 ----2
前言 call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受 ...
- 为什么学习JavaScript设计模式,因为它是核心
那么什么是设计模式呢?当我们在玩游戏的时候,我们会去追求如何最快地通过,去追求获得已什么高效率的操作获得最好的奖品:下班回家,我们打开手机app查询最便捷的路线去坐车:叫外卖时候,也会找附近最近又实惠 ...
- 面试官:能解释一下javascript中bind、apply和call这三个函数的用法吗
一.前言 不知道大家还记不记得前几篇的文章:<面试官:能解释一下javascript中的this吗> 那今天这篇文章虽然是介绍javascript中bind.apply和call函数 ...
随机推荐
- oracle的jdbc.properties文件配置
----------Oracle #do Oracle JDBC jdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc:o ...
- jQuery的ajax请求express服务器返回数据
html页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- P3956 棋盘——普及题,儿童搜索
P3956 棋盘 这道搜索弄得我很难受. 第一,一定要看清楚题在写.第二,弄清楚判断条件: 首先图的大小是m*m不是n*m; 然后就是当前有颜色的点是不用变颜色的: #include<cstdi ...
- Beyond compare4密钥
w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv1BM3+H1XygMtiE0-JBgacjE9tz33sIh542EmsGs1yg6 ...
- Arts打卡第6周
Algorithm.主要是为了编程训练和学习. 每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard). 进行编程训练,如果不训练你看再多的算法书,你依然不 ...
- Poseidon 系统是一个日志搜索平台——认证看链接ppt,本质是索引的倒排列表和原始日志数据都存在HDFS,而文档和倒排的元数据都在NOSQL里,同时针对单个filed都使用了独立索引,使用MR来索引和搜索
Poseidon 系统是一个日志搜索平台,可以在百万亿条.100PB 大小的日志数据中快速分析和检索.360 公司是一个安全公司,在追踪 APT(高级持续威胁)事件,经常需要在海量的历史日志数据中检索 ...
- GC的判定的2种方式
对象是否死亡的2中判定方法:引用计数和可达性分析(又称引用链) 1.引用计数 对象再被创建时,对象头里会存储引用计数器,对象被引用,计数器+1:引用失效,计数器 -1:GC时会回收计数器为0的对象.但 ...
- Linux堆的一些基础知识
目录 堆的概述 什么是堆 堆的基本操作 堆操作背后的系统调用 堆的相关数据结构 微观结构 malloc_chuck chunk相关宏 bin 宏观结构 arena heap_info malloc_s ...
- 研途APP——项目需求分析
研途APP--项目需求分析 1.作业描述 项目 内容 课程 软件工程实践 作业链接 团队作业第二次-需求规格说明书 团队名称 8rookies 作业目标 作业正文 研途APP--项目需求分析 其他参考 ...
- vue实现滚动条滚到相应高度触发动画的操作
一.vue项目引入animate.css 第一步:在命令行中执行: npm install animate.css --save 第二步:引入及使用: main.js中: import animate ...