call,apply,bind

在JavaScript中,callapplybindFunction对象自带的三个方法,都是为了改变函数体内部 this 的指向。

           apply 、 call 、bind 三者第一个参数都是 this 要指向的对象,也就是想指定的上下文;

           apply 、 call 、bind 三者都可以利用后续参数传参;

bind 是返回对应 函数,便于稍后调用;apply 、call 则是立即调用 。

——————————————————————————————————————————————————————————————————————————-

例子:

1.

   function fruits() {}

       fruits.prototype = {
color: 'red',
say: function() {
console.log('My color is' + this.color);
}
} var apple = new fruits;
apple.say(); // 此时方法里面的this 指的是fruits
// 结果: My color is red
 

但是如果我们有一个对象 banana= {color : 'yellow'} ,我们不想重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:

banana = {
color: 'yellow'
}
apple.say.call(banana); //此时的this的指向已经同过call()方法改变了,指向的是banana,this.color就是banana.color='yellow';
//结果是My color is yellow
apple.say.apply(banana);//同理,此时的this的指向已经同过apply()方法改变了,指向的是banana,this.color就是banana.color ='yellow';
//My color is yellow
// 如果传入的是 null: apple.say.apply(null); // null是window下的,此时,this 就指向了window ,但是window下并没有clolr这个属性,因此this.clolr就是window.color=undefined;
//My color is undefined

2.对于 apply、call 二者而言,作用完全一样,只是接受 参数 的方式不太一样。call 是把参数按顺序传递进去,而 apply 则是把参数放在数组 里。

var array1 = [12,'foo',{name:'Joe'},-2458];
var array2 = ['Doe' , 555 , 100];
Array.prototype.push.call(array1, array2);
// 这里用 call 第二个参数不会把 array2 当成一个数组,而是一个元素
//等价于array1.push(‘‘'Doe' , 555 , 100’’);
//array1.length=5; Array.prototype.push.apply(array1, array2); // 这里用 apply 第二个参数是一个数组 // 等价于: array1.push('Doe' , 555 , 100);
//array1.length=7;

3.类(伪)数组使用数组方法

var divElements = document.getElementsByTagName('div'); //虽然 divElements 有length属性,但是他是一个伪数组,不能使用数组里面的方法
Array.isArray(divElements);// false var domNodes = Array.prototype.slice.call(document.getElementsByTagName('div'));
// 将数组对象Array里的this指向伪数组document.getElementsByTagName('div'),
//slice() 方法可从已有的数组中返回选定的元素,不传参数是,返回整个数组
Array.isArray(domNodes);// true

4. 验证一个对象的类型可以用:

Object.prototype.toString.call(obj) 

5.bind() 方法,MDN 的解释是:bind() 方法会创建一个 新函数,称为绑定函数,当调用这个绑定函数时,

绑定函数会以创建它时传入 bind() 方法的第一个参数 作为 this,传入 bind() 方法的 第二个以及以后的参

数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
bar(); // undefined
var func = bar.bind(foo); //此时this已经指向了foo,但是用bind()方法并不会立即执行,而是创建一个新函数,如果要直接调用的话 可以 bar.bind(foo)()

func(); //

6.在 Javascript 中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
var sed = {
x:4
}
var func = bar.bind(foo).bind(sed);
func(); // var fiv = {
x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //

7.apply、call、bind 三者相比较,之间又有什么异同呢?何时使用 apply、call,何时使用 bind 呢。简单的一个例子:

var obj = {
x: 81,
}; var foo = {
getX: function() {
return this.x;
}
}
console.log(foo.getX.bind(obj)()); //
console.log(foo.getX.call(obj)); //
console.log(foo.getX.apply(obj)); //

参考:

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

学习前端的菜鸡对JS的call,apply,bind的通俗易懂理解的更多相关文章

  1. 学习前端的菜鸡对JS 的classList理解

    classList 在早期的时候要添加,删除类 需要用className去获取,然后通过正则表达式去判断这个类是否存在. 代码上去会有点麻烦,现在有了classList 就方便了很多. ——————— ...

  2. JS 的 call apply bind 方法

    js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[,   [,.argN]]]] ...

  3. js: this,call,apply,bind 总结

    对js中的一些基本的很重要的概念做一些总结,对进一步学习js很重. 一.this JavaScript 中的 this 总是指向一个对象,而具体指向那个对象是在运行时基于函数的执行环境动态绑定的,而非 ...

  4. js call apply bind简单的理解

    相同点:JS中call与apply方法可以改变某个函数执行的上下文环境,也就是可以改变函数内this的指向.区别:call与apply方法的参数中,第一个参数都是指定的上下文环境或者指定的对象,而ca ...

  5. 前端基础:call,apply,bind的的理解

    背景 前两天在做小程序的需求的时候用到bind的时候才想起自己对这三的东西的了解比较浅薄,这个时候用的时候就有点怕.时候还是要好好学习下,理解下怎么玩. 正文 先说call 和 apply吧:ECMA ...

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

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

  7. 原生JS实现call,apply,bind函数

    1. 前言 使用原生JS实现call和apply函数,充分了解其内部原理.call和apply都是为了解决改变this的指向.作用都相同,只是传参的方式不同.除了第一个参数外,call可以接受一个参数 ...

  8. js笔记——call,apply,bind使用笔记

    call和apply obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1, arg2, ...]); 两者作用一致,都是把obj( ...

  9. JS之call/apply/bind

    测试代码: var a = 1; var obj = { a = 2; } function test(a){ alert(a); alert(this.a); } 1.test(3); 结果:3,1 ...

随机推荐

  1. jdk升级到9,eclipse打不开

    jdk从1.8到1.9之后删除了不少之前Deprecated的类. eclipse 版本oxygen和neon对应jdk1.8 eclipse 版本luna和mars对应jdk1.7,1.6 在打开e ...

  2. React Native指南汇集了各类react-native学习资源、开源App和组件

    来自:https://github.com/ele828/react-native-guide React Native指南汇集了各类react-native学习资源.开源App和组件 React-N ...

  3. iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角)--(转)

    图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网络下载图片并进行缓存.可对图片进行缩放等操作. 下 ...

  4. mongodb基础学习4-游标

    今天来讲讲游标的操作,可以先获取一组文档,再对每一个文档进行操作. 因为mongodb底层是js引擎,所有可以像操作js一样操作mongodb,比如插入数据 游标的使用:声明游标,判断是否有下一条数据 ...

  5. sql server 2000能否得到一个表的最后更新日期?

    如果是SQL 2005 或 2008.运行下面的代码.就可以看到从上次启动SQL 服务以来,某个表的使用情况,包括select/update/delete/insert. SELECT * FROM ...

  6. 注册COM

    可以用代码在程序中实现COM的注册. 举例如下: (假设需要注册的文件为test.ocx)uses OLEctl,....varOCXHand: THandle;RegFunc: TDllRegist ...

  7. Hibernate 的Ehache学习

    Hibernate默认二级缓存是不启动的,启动二级缓存(以EHCache为例)需要以下步骤: 1.添加相关的包: Ehcache.jar和commons-logging.jar,如果hibernate ...

  8. GBDT 将子树结果当成lr输出

    http://scikit-learn.org/stable/auto_examples/ensemble/plot_feature_transformation.html#example-ensem ...

  9. Hadoop slaves 没有nodeManager

    1../start-yarn.sh 后从服务器没有nodemanager 进程,并且这里没有报错 在从服务器上的日志上见: 从服务器查看日志: 查看2.8.4官方文档: https://hadoop. ...

  10. testlink问题--linux环境下

    搭建testlink 时出现问题,相关解决办法: 1.Maximum Session Idle Time before Timeout 修改php.ini文件,修改成session.gc_maxlif ...