一、探索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. 2017/05/03 java 基础 随笔

    1.硬盘500G 厂商是按照1000计算的 500g=500*1000*1000/1024/1024=465g 2.jdk1.7可以表示二进制了 0b001(b大小写无所谓) 3.进制转换 4.原码, ...

  2. MRPT 安装使用

    1. 安装mrpt ( apt-get ) $ sudo apt-get install mrpt-apps libmrpt-dev 2. 下载mrpt-1.3 链接:https://github.c ...

  3. latex对齐问题

    数学公式居中:可以在公式前后各加两个$$,就可以了 一行对齐:左对齐\leftline{内容} 居中\centerline{内容} 右对齐\rightline{内容} 多行或者段落对齐: 左对齐 \b ...

  4. np.mat()和np.transpose

    例子: import numpy as np dataSet = [] with open('/home/lai/下载/20081023025304.plt') as fr: for line in ...

  5. 定位内网中毒主机IP经历小记

    一.事件起因 客户向公司反映使用IDS设备捕获到木马上线域名需要处理,虽然是逆向岗但还是有预感未来应急响应的工作只会越来越多.所以作为新人的我选择了跟带头BOSS去现场学习,并且将自己参与应急响应中的 ...

  6. Python中的__init__()和__call__()函数

    Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...

  7. Kaggle Titanic补充篇

    1.关于年龄Age 除了利用平均数来填充,还可以利用正态分布得到一些随机数来填充,首先得到已知年龄的平均数mean和方差std,然后生成[ mean-std,  mean+std ]之间的随机数,然后 ...

  8. ARM40-A5应用——fbset与液晶屏参数的适配【转】

    转自:https://blog.csdn.net/vonchn/article/details/80784579 ARM40-A5应用——fbset与液晶屏参数的适配 2018.6.18 版权声明:本 ...

  9. eclipse自动生成变量名声明(按方法返回值为本地变量赋值)

    eclipse自动生成变量名声明(按方法返回值为本地变量赋值) ctrl+2+L 这个快捷键可自动补全代码,极大提升编码效率! 注:ctrl和2同时按完以后释放,再快速按L.不能同时按! 比如写这句代 ...

  10. Shell 中test 单中括号[] 双中括号[[]] 的区别

    Shell test 单中括号[] 双中括号[[]] 的区别 在写Shell脚本的时候,经常在写条件判断语句时不知道该用[] 还是 [[]],首先我们来看他们的类别: $type [ [[ test ...