一、探索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的区别的更多相关文章

  1. javascript中call,apply,bind的用法对比分析

    这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们.   关于call,apply,bind这三个函数的用法,是学习java ...

  2. JavaScript中call,apply,bind方法的区别

    call,apply,bind方法一般用来指定this的环境. var a = { user:"hahaha", fn:function(){ console.log(this.u ...

  3. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  4. JavaScript中call,apply,bind方法的总结

    原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...

  5. JavaScript中call,apply,bind方法

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  6. js 中call,apply,bind的区别

    call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...

  7. JS中call,apply,bind的区别

    1.关于this对象的指向,请看如下代码 var name = 'jack'; var age = 18; var obj = { name:'mary', objAge:this.age, myFu ...

  8. javascript中call,apply,bind的使用

    不同点: 1.call():传参方式跟bind一样(都是以逗号隔开的传参方式),但是跟apply(以数组的形式传参)不一样, 2.bind(): 此方法应用后的情形跟call和apply不一样.该方法 ...

  9. JavaScript中的apply和call函数详解(转)

    每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,J ...

  10. JavaScript中的apply和call函数详解

    本文是翻译Function.apply and Function.call in JavaScript,希望对大家有所帮助 转自“http://www.jb51.net/article/52416.h ...

随机推荐

  1. cmake使用示例与整理总结

    转自: http://blog.csdn.net/wzzfeitian/article/details/40963457/ 本文代码托管于github  https://github.com/carl ...

  2. linux内核capable源代码分析【转】

    转自:https://blog.csdn.net/sanwenyublog/article/details/50856849 linux内核里对于进程的权限管理有一个很重要的函数capable,以前看 ...

  3. Python3学习笔记22-文件读写

    读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操 ...

  4. zabbix系列(十)zabbix添加对zookeeper集群的监控

    1.应用场景描述 在目前公司的业务中,有部分ESB架构用ZooKeeper作为协同服务的场景,做好ZooKeeper的监控很重要. 2.ZooKeeper监控要点 系统监控 内存使用量    ZooK ...

  5. InetAddress问题

    InetAddress的方法 当输入InetAddress.getByAddress(new byte[]{127.0.0.1})的时候不会报错, 但是ip的各段值是0-255,当new byte[] ...

  6. vue系列之获取多选框中被选中的值

    多个勾选框,绑定到同一个数组: <input type="checkbox" id="jack" value="Jack" v-mod ...

  7. Storm的部署

    配置方案如下 node1 Nimbus zookeeper node2 Supervisor zookeeper node3 Supervisor zookeeper node4 Supervisor ...

  8. 视觉显著性检测(Visual saliency detection)相关概念

    视觉显著性检测(Visual saliency detection)指通过智能算法模拟人的视觉特点,提取图像中的显著区域(即人类感兴趣的区域). 视觉注意机制(Visual Attention Mec ...

  9. 【mysql】一个很小但很影响速度的地方

    如果要插入一大批数据,千万不要一条一条的execute, commit.而应该是先全部execute,最后统一commit!!! 千万注意,时间差距还是很大的!! 正确示范:快 ): sql = &q ...

  10. C#之app.config、exe.config和vshost.exe.config作用区别

    vshost.exe.config是程序运行时的配置文本 exe.config是程序运行后会复制到vshost.exe.config app.config是在vshost.exe.config和exe ...