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. pip cannot confirm SSL certificate: SSL module is not available

    centos6.8编译安装python2.7之后,使用pip报错:pip cannot confirm SSL certificate: SSL module is not available 解决方 ...

  2. 修改thinkpad 小红点(TrackPoint速度)

    from: http://www.jianshu.com/p/b9677e9e56ec Thinkpad大概是对Linux支持最好的笔记本了,Ubuntu大概是对硬件支持最好的Linux发行版了.Ub ...

  3. Mysql 知识(2)

    1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一 ...

  4. Apache kafka v1.0.0 部署文档

    简介: Apache Kafka 是一个 Scala 语言编写的可扩展.分布式.高性能的容错消息发布.订阅系统. 官网地址:http://kafka.apache.org 中文教程:http://ww ...

  5. salt常用模块及API

    saltstack提供了非常丰富的功能模块,涉及操作系统的基础功能,常用工具支持等,更多模块信息见官网模块介绍:https://docs.saltstack.com/en/latest/ref/mod ...

  6. dubbo2.5.3升级到dobbo2.8.4(dubbox) jar

    需要注意的地方: 1.pom文件中 dubbo的版本由2.5.3变为2.8.4,maven依赖如下:     <dependency>         <groupId>com ...

  7. 登录时显示403 Access Denied

    用户名及密码设置如下: 在tomcat安装目录\conf\tomcat-users.xml中的<tomcat-users>标签内设置: <role rolename="ma ...

  8. 好用的模板引擎NVelocity

    CastleNVelocity-1.1.1,使用方法: 把dll放到项目中,添加引用,修改配置的文件夹以及数据模型,最后在逻辑代码中调用即可. 封装到CommonHelper.cs using Sys ...

  9. Unable to get the default Bean Validation factory

    前几天看了一下教程 ,自己试着配置了一下web下的hibernate,悲剧的时,出错了提示下面: 信息: Hibernate Validator bean-validator-3.0-JBoss-4. ...

  10. 苹果 重置APPID密保问题及更新开发者协议

    [链接]重置AppleID密保问题 https://www.jianshu.com/p/37e7f2852eda [链接]苹果开发者计划许可协议更新:持续更新 https://www.jianshu. ...