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 ...
随机推荐
- ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(4)- 其它
1. 前言 2.可配置的指令使能/禁用控制和trap控制 指令使能/禁用 当指令被禁用,则这条指令就会变成未定义 指令Trap控制 控制某条或某些指令在运行时进入陷阱,进入陷阱的指令会产生trap异常 ...
- springboot系列四、配置模板引擎、配置热部署
一.配置模板引擎 在之前所见到的信息显示发现都是以 Rest 风格进行显示,但是很明显在实际的开发之中,所有数据的显示最终都应该交由页面完成,但是这个页面并不是*.jsp 页面,而是普通的*.html ...
- secureCRT连接linux系统
linux和secureCRT利用ssh协议22端口进行远程连接的 连接如果没有成功,请检查远程主机的端口和ssh是否开启 一.检查看SSH服务是否开启 当然有的linux系统使用的命令是/etc/i ...
- linux /proc目录说明(访问内核数据结构,修改内核设置)
1. /proc目录 Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以 ...
- 集成Struts2+Spring+Hibernate_两种方案
集成Struts2+Spring+Hibernate 第一种方案:让Spring创建Struts2的Action,不让Spring完全管理Struts2的Action Struts2 Act ...
- tomcat中gzip压缩
在tomcat中压缩文件,修改server.xml文件中的配置 <Connector port="8080" protocol="HTTP/1.1" co ...
- robotium之不标准select控件
今天写脚本,遇到一个联合查询框 即:下拉框选择,输入框输入搜索条件,点击查询按钮 如图样式: 用uiautomatorviewer查看元素:无ID,无name,无desc 看到这我瞬间尴尬了,该咋办呢 ...
- pandas使用lambda判断元素是否为空或者None
df2a_tp2 = df2a[df2a['combineIdentifyCode'].map(lambda x: len(str(x).strip())>0)].copy() #识别出合单的订 ...
- 在chrome开发者工具中观察函数调用栈、作用域链与闭包
在chrome开发者工具中观察函数调用栈.作用域链与闭包 在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量 ...
- 恋爱Linux(Fedora20)2——安装Java运行环境(JDK)
因为Fedora20自带OpenJDK,所以我们先删除掉自带的: 1)查看当前的jdk情况 # rpm -qa|grep jdk 2)卸载openjdk # yum -y remove java ja ...