一,三者共同点

js中的apply,call,bind是对于初学者比较难的概念之一,比如说我。。参考几篇文章之后,统一来讲,

1、这三个函数都属于Function.prototype下面的方法,如下图所示。从而可以被每一个函数实例所调用。

2、他们的作用都是改变函数的执行上下文。举个例子:

var a=1;
function printA(){
console.log(this.a);
}
var obj={a:2};
printA();//相当于window.printA(),此时this指向window/global对象

现在我想打印obj里面的a,可以这么做:

obj.printA=printA;//将函数作为obj对象的方法
obj.printA();//调用该方法

还可以这么做:

printA.call(obj); //利用call将obj作为printA的上下文,this指向obj
printA.apply(obj); //利用apply将obj作为printA的上下文,this指向obj
var objPrintA=printA.bind(obj); //利用bind将obj作为printA的上下文,this指向obj,并让objPrintA变量名作为返回的新函数的引用
objPrintA();

上面的三种方法都成功的访问到了obj里的a;

但是注意bind的用法,printA.bind(obj)仅仅将printA的上下文改变,并返回一个新函数,称为绑定函数。但是并没有立刻执行,需要手动调用新函数objPrintA来执行它。

3、call、apply、bind都可以在第一个参数后传入别的参数,作为函数的参数传入

第一个参数除了普通的对象之外,还可以传入以下值:

(1) 不传,或者传入null,undefined,函数中的this指向window对象。

(2)传递另一个函数的函数名,函数的this指向这个函数的引用。

(3)传递字符串、数值或者布尔值等基础类型,函数中的this指向其对应的包装对象,String,Number,Boolean

(4)传递一个对象,函数中的this指向该对象。

function printThis(){
console.log(this);
}
printThis.call(); //[object Window]
printThis.call(null); //[object Window]
printThis.call(undefined);//[object Window]
printThis.call(1);//[object Number]
printThis.call('1');//[object String]
printThis.call(true);//[object Boolean]
printThis.call({a:1});//[object Object]{a: 1}
printThis.call(function(a){console.log(a)});//function (a){console.log(a)}

二,call与apply的区别

前面区分了bind与call,apply的区别,bind会返回一个新的绑定上下文之后的函数,而call和apply是会立即执行函数。下面的例子实现了es3对原生bind()方法的模拟,更能说明这个区别。

function bind(f,o){
if(f.bind) return f.bind(o);//如果有原生bind,则直接调用
else return function(){//返回一个新的函数,调用这个函数会在o对象的上下文中执行
return f.apply(o,arguments);
}
}

call和apply的区别在于apply接受一个数组参数,所以当你的参数是明确知道数量时用 call,当参数不固定时应该用apply 。一个应用情景就是arguments和apply比较配

arguments是函数的一个内部属性:

function a(){
console.log(arguments);
console.log(a.arguments);
console.log(this.arguments);
}
obj={arguments:'arguments'}
a();
/*
[object Arguments]{length: 0}
[object Arguments]{length: 0}
undefined
*/
a(1,'1',true);
/*
[object Arguments]{0: 1, 1: "1", 2: true, length: 3}
[object Arguments]{0: 1, 1: "1", 2: true, length: 3}
undefined
*/
a.call(obj);
/*
[object Arguments]{length: 0}
[object Arguments]{length: 0}
arguments
*/

上面这个例子表明arguments是函数对象的一个属性,在函数内部可以直接通过arguments[i]来访问实参。还说明了this绝对不是指向函数本身。

最后举一个求平方和的例子。

function sum(){
var args=Array.prototype.slice.apply(arguments);
return args.reduce(function(prev,next){return prev+next*next},0);
}
sum(1,2,4,6,8)//121

参考文章:深入浅出 妙用Javascript中apply、call、bind

理解javascript里的ABC--apply bind call的更多相关文章

  1. JavaScript学习(2)call&apply&bind&eval用法

    javascript学习(2)call&apply&bind&eval用法 在javascript中存在这样几种特别有用的函数,能方便我们实现各种奇技淫巧.其中,call.bi ...

  2. Learning JavaScript with MDN (call, apply, bind)

    Learning JavaScript with MDN (call, apply, bind) call, apply, bind Object.prototype.toString() 检测 js ...

  3. 深入浅出:了解JavaScript中的call,apply,bind的差别

     在 javascript之 this 关键字详解文章中,谈及了如下内容,做一个简单的回顾:         1.this对象的涵义就是指向当前对象中的属性和方法.       2.this指向的可变 ...

  4. 别真以为JavaScript中func.call/apply/bind是万能的!

    自从学会call/apply/bind这三个方法后我就各种场合各种使用各种得心应手至今还没踩过什么坑,怎么用?说直白点就是我自己的对象没有某个方法但别人有,我就可以通过call/apply/bind去 ...

  5. javascript中的call(),apply(),bind()方法的区别

    之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再 ...

  6. 深入理解javascript中的Function.prototye.bind

    函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...

  7. 理解javascript中的Function.prototype.bind

    在初学Javascript时,我们也许不需要担心函数绑定的问题,但是当我们需要在另一个函数中保持上下文对象this时,就会遇到相应的问题了,我见过很多人处理这种问题都是先将this赋值给一个变量(比如 ...

  8. 理解 JavaScript 中的 Function.prototype.bind

    函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...

  9. 理解JavaScript里this关键字

    1.全局代码中的this:始终指向window 2.函数代码中的this: }; var bar = { x: , test: function () { alert(this === bar); a ...

随机推荐

  1. 在公有云AZURE上部署私有云AZUREPACK以及WEBSITE CLOUD(三)

    (三) 搭建Windows Azure Pack环境 1安装SQL SERVER 2012 服务器 为简单起见,本例直接使用了Azure提供的具有SQLServer的Win2012 Server镜像来 ...

  2. bzoj1036--树链剖分

    模板题... #include<iostream> #include<cstdio> #include<cstring> using namespace std; ...

  3. Spring MVC中的ModelMap作用及用法

    ModelMap的作用: ModelMap对象主要用于传递控制方法传递数据到结果页面.类似于request的setAttribute方法的作用. 所以我们要想在jsp页面获取数据,只要将数据放到Mod ...

  4. jQuery拖动剪裁图片作为头像

    图片上传是许多网站的一个常用的功能,有时需要对上传的图片做初步的选择裁剪,比如上传头像.下面就是一个使用HTML5+jQuery实现的图片上传裁剪特效,可以对选择要上传的图片做缩小.放大.拖动和裁剪, ...

  5. iOS学习15之OC集合

    1.数组类 1> 回顾C语言数组 数组是一个有序的集合, 来存储相同数据类型的元素. 通过下标访问数组中的元素,下标从 0 开始. 2> 数组 数组是一个有序的集合,OC中的数组只能存储对 ...

  6. h5上传图片及预览

    第一次做图片上传,记录一些问题. 1,图片的base64编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址.而网页上的每一个图片,都是需要消耗一个http请求下载而来的,使用base ...

  7. css之浮动

    标准文档流 将窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素,即为文档流.每个非浮动块级元素都独占一行, 浮动元素则按规定浮在行的一端. 若当前行容不下, 则另起新行再浮动. 标准流的微 ...

  8. 在Windows中玩转Docker Toolbox

    最近在研究虚拟化,容器和大数据,所以从Docker入手,下面介绍一下在Windows下怎么玩转Docker. Docker本身在Windows下有两个软件,一个就是Docker,另一个是Docker ...

  9. 创建agsXMPP 自定义packet types

    在网上看了好多文章基本都是转载 没有能成功运行的,又没有别的资料,很是费解,无奈之下只好潜心研究,最终总结了几个要点给大家分享下,以免再次多浪费时间 agsXMPP是什么就不多描述了,重点说下我在创建 ...

  10. CentOS安装Apache-2.4.10+安全配置

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. #准备工作# 在安装Nginx之前,请确保已经使用yum安装了各基础组件,并且配置了www用户和用户组,具体见<CentOS ...