Javascript中call,apply,bind的区别
一、探索call方法原理
Function.prototype.call = function(obj) { // 1、让fn中的this指向obj // eval(this.toString().replace("this","obj")); // 2、让fn方法再执行 // this(); }
function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(); //1,this指向window fn1.call(fn2); //1,原来的this指向fn1,fn1.call(fn2)把this指向fn2,再让fn1方法执行。 fn1.call.call(); //报错了,fn1.call.call is not a function。 fn1.call.call(fn2); /*设fn1.call = test; test.call(fn2)原来的this指向test,test.call(fn2)把this指向fn2,再让test方法执行,即fn1.call的内部this()执行,即fn2()执行。 */
二、call,apply,bind的调用语法
function fn(num1, num2) { console.log(num1 + num2); console.log(this); } //call方法 fn.call(obj , 100 , 200); //apply方法 fn.apply(obj , [100, 200]); //bind方法 var tempFn = fn.bind(obj, 1, 2); tempFn(); //或者fn.bind(obj, 1, 2)();
1、相同点
- 函数钩子,本质是函数,为了调用其他函数;
- apply、call、bind三者都是用来改变函数的this对象的指向的;
- apply、call、bind三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply、call、bind三者都可以利用后续参数传参。
2、不同点
- call,bind在给fn传递参数的时候,以枚举形式传参;而apply以数组形式传参。
- 明确知道参数数量时用call;不确定参数数量时用apply,然后把参数push进数组并传递进去,函数内部也可以通过arguments这个数组来遍历所有的参数。
- bind是返回对应函数,便于稍后调用;apply、call则是立即调用。
- bind这个方法在IE6~8下不兼容。在Javascript中,多次bind()是无效的,因为bind的实现,相当于使用函数在内部包了一个call/apply,第二次bind()相当于再包住第一次bind(),故第二次以后的bind是无法生效的。
四、应用场景
1、验证是否是数组
function isArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]'; }
2、获取数组最大最小值
var numbers = [5, 458 , 120 , -215]; maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215);
3、数组追加
var arr1 = [12 , "foo" , {name "Camille"} , -2458]; var arr2 = ["HouYi" , 555 , 100]; Array.prototype.push.apply(arr1, arr2);
4、伪数组使用数组方法
//定义一个log方法,让它可以代理console.log方法,常见的解决方法是: function log(msg) { console.log(msg); } log('msg1'); //msg1 log('msg1','msg2'); //msg1
//当不确定传入参数的个数时,上面的方法就失效了,于是想到了apply. function log(){ console.log.apply(console, arguments); }; log('msg1'); //msg1 log('msg1','msg2'); //msg1 msg2
//如果给log消息添加一个"app_"前辍,这时可以想到Array.prototype.slice.call可以把arguments伪数组转化为标准数组,再使用数组方法unshift即可。 function log(){ var args = Array.prototype.slice.call(arguments); args.unshift('app_'); console.log.apply(console, args); }; log('msg1'); //app_ msg1
Javascript中call,apply,bind的区别的更多相关文章
- javascript中call,apply,bind的用法对比分析
这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们. 关于call,apply,bind这三个函数的用法,是学习java ...
- JavaScript中call,apply,bind方法的区别
call,apply,bind方法一般用来指定this的环境. var a = { user:"hahaha", fn:function(){ console.log(this.u ...
- JavaScript中call,apply,bind方法的总结。
why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...
- JavaScript中call,apply,bind方法的总结
原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...
- JavaScript中call,apply,bind方法
why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...
- js 中call,apply,bind的区别
call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...
- JS中call,apply,bind的区别
1.关于this对象的指向,请看如下代码 var name = 'jack'; var age = 18; var obj = { name:'mary', objAge:this.age, myFu ...
- javascript中call,apply,bind的使用
不同点: 1.call():传参方式跟bind一样(都是以逗号隔开的传参方式),但是跟apply(以数组的形式传参)不一样, 2.bind(): 此方法应用后的情形跟call和apply不一样.该方法 ...
- JavaScript中的apply和call函数详解(转)
每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,J ...
- JavaScript中的apply和call函数详解
本文是翻译Function.apply and Function.call in JavaScript,希望对大家有所帮助 转自“http://www.jb51.net/article/52416.h ...
随机推荐
- latex对齐问题
数学公式居中:可以在公式前后各加两个$$,就可以了 一行对齐:左对齐\leftline{内容} 居中\centerline{内容} 右对齐\rightline{内容} 多行或者段落对齐: 左对齐 \b ...
- python2 与 python3 语法区别
python2 与 python3 语法区别 概述# 原稿地址:使用 2to3 将代码移植到 Python 3 几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下.为 ...
- argv[1] 路径问题
在看<学习opencv>一书时遇到一个小问题:函数只是通过argv传递参数来读取图片并显示,但是却一直弹出画布,没有图像. 如下:test.c # include<stdio.h&g ...
- Ubuntu 16.04配置国内高速apt-get更新源【转】
转自:https://blog.csdn.net/twang0x80/article/details/79782753 Ubuntu 16.04下载软件速度有点慢,因为默认的是从国外下载软件,那就更换 ...
- linux /proc目录说明(访问内核数据结构,修改内核设置)
1. /proc目录 Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以 ...
- Android:ZoomControls控件
ZoomControls控件 //_ZoomControls.java public class _ZoomControls extends Activity{ @Override protected ...
- vue系列之vue-resource
vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应.也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且 ...
- 在 Win 7或8 下使用 VirtualBOX 虚拟机安装 OS X 10.11 El Capitan 及 Xcode 7.0
注:本文源自于: http://bbs.feng.com/read-htm-tid-9908410.html _____________________________________________ ...
- python魔法函数(二)之__getitem__、__len__、__iter__
魔法函数会增强python类的类型,独立存在 __getitem class Company: def __init__(self, employees): self.employees = empl ...
- JS中sort()方法原理及使用
说明 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较. arra ...