一直以来对和this有关的东西模糊不清,譬如call、apply等等。这次看到一个和bind有关的笔试题,故记此文以备忘。

  bind和call以及apply一样,都是可以改变上下文的this指向的。不同的是,call和apply一样,直接引用在方法上,而bind绑定this后返回一个方法,但内部核心还是apply。

  直接看例子:

var obj = {
  a: 1,
  b: 2,
  getCount: function(c, d) {
    return this.a + this.b + c + d;
  }
};

window.a = window.b = 0;
console.log(obj.getCount(3, 4));  // 10
var func = obj.getCount;
console.log(func(3, 4));  // 7

  为何会这样?因为func在上下文中的this是window!bind的存在正是为了改变this指向获取想要的值:

var obj = {
  a: 1,
  b: 2,
  getCount: function(c, d) {
    return this.a + this.b + c + d;
  }
};

window.a = window.b = 0;
var func = obj.getCount.bind(obj);
console.log(func(3, 4));  // 10

  bind是function的一个函数扩展方法,bind以后代码重新绑定了func内部的this指向(obj),但是不兼容ie6~8,兼容代码如下:

var obj = {
  a: 1,
  b: 2,
  getCount: function(c, d) {
    return this.a + this.b + c + d;
  }
};

Function.prototype.bind = Function.prototype.bind || function(context) {
  var that = this;
  return function() {
    // console.log(arguments); // console [3,4] if ie<6-8>
    return that.apply(context, arguments);

  }
}
window.a = window.b = 0;
var func = obj.getCount.bind(obj);
console.log(func(3, 4));  // 10

  其实在我看来bind的核心是返回一个未执行的方法,如果直接使用apply或者call:

var ans = obj.getCount.apply(obj, [3, 4]);
console.log(ans); // 10

  无法使用简写的func函数构造,所以用bind传递this指向,再返回一个未执行的方法,实现方式相当巧妙。

  

2015-6-10补充:

  昨天看到一个bind在代码中的装逼实现。如何用setTimeout连续打印0~9?

  以前试过的朋友肯定知道,直接打印是不行的,会打印出一样的数字,这时候就要用闭包了,闭包的话有两种方式,简单实现一种如下:

for(var i = 0; i < 10; i++) {
  ~function(i) {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  }(i);
}

  但是居然用bind也能实现:

for(var i = 0; i < 10; i++) {
  setTimeout(console.log.bind(console, i), i * 1000);
}

  这样为何也能实现,我也是百思不得其解,只能说不明觉厉。

  bind是和apply、call一样,是Function的扩展方法,所以应用场景是func.bind(),而传的参数形式和call一样,第一个参数是this指向,之后的参数是func的实参,fun.bind(thisArg[, arg1[, arg2[, ...]]])。

  参考资料:bind

ECMAScript 5(ES5)中bind方法简介备忘的更多相关文章

  1. simplify the life ECMAScript 5(ES5)中bind方法简介

    一直以来对和this有关的东西模糊不清,譬如call.apply等等.这次看到一个和bind有关的笔试题,故记此文以备忘. bind和call以及apply一样,都是可以改变上下文的this指向的.不 ...

  2. 【转载】JS中bind方法与函数柯里化

    原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...

  3. SQL Server修改标识列方法(备忘)

    原文:SQL Server修改标识列方法(备忘) SQL Server修改标识列方法 ----允许对系统表进行更新 exec sp_configure 'allow updates',1 reconf ...

  4. js学习进阶中-bind()方法

    有次面试遇到的,也是没说清楚具体的作用,感觉自己现在还是没有深刻的理解! bind():绑定事件类型和处理函数到DOM element(父元素上) live():绑定事件到根节点上,(document ...

  5. Javascript中bind()方法的使用与实现

    对于bind,我愣了下,这个方法常用在jquery中,用于为被选元素添加一个或多个事件处理程序. 查了下手册,发现bind的作用和apply,call类似都是改变函数的execute context, ...

  6. 理解js中bind方法的使用

    提到bind方法,估计大家还会想到call方法.apply方法:它们都是Function对象内建的方法,它们的第一个参数都是用来更改调用方法中this的指向.需要注意的是bind 是返回新的函数,以便 ...

  7. ES6中。类与继承的方法,以及与ES5中的方法的对比

    // 在ES5中,通常使用构造函数方法去实现类与继承 // 创建父类 function Father(name, age){ this.name = name; this.age = age; } F ...

  8. 通用mapper的增删改查方法 留存 备忘

    Mybatis通用Mapper介绍与使用   前言 使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQ ...

  9. jq中 load()方法 简介

    load()方法会在元素的onload事件中绑定一个处理函数.如果处理函数绑定给window对象,则会在所有内容(包括窗口,框架,对象和图像等)加载完毕后触发,如果处理函数绑定在元素上,则会在元素的内 ...

随机推荐

  1. jQueryMobile示例页面代码

    这是一个jQueryMobile示例页面 示例效果:http://hovertree.com/texiao/jquerymobile/ 可以在手机或者触屏浏览器查看效果. 以下是HTML代码: < ...

  2. 谷歌浏览器下载地址 chrome最新版本 百度云地址

    每次下载更新谷歌浏览器是一件很蛋疼的事情.百度搜索"谷歌浏览器下载地址",居然有很多骗子网站,相信有很多不知所以的人中招了.收集了一些chrome的安装包,放在了百度云里面(打不开 ...

  3. iOS 如何获取屏幕大小

    UIScreen *currentScreen = [UIScreen mainScreen]; NSLog(@"applicationFrame.size.height = %f" ...

  4. 关于举办 2015年 Autodesk 助力云应用项目开发活动通知

    各位尊敬的Autodesk 合作伙伴,大家好! 相信您在过去的一年里应该对Autodesk最新的云服务技术有所了解,您是不是曾经闪现过一些很好的想法,却由于不确定是否真实可行,或担心没有技术支持来帮助 ...

  5. 用SourceTree合并工程冲突,工程打不开时的操作

    1.右键工程 --> 显示包内容 2.打开project.pbxproj文件 3.command + F :搜索“<<<<<” 或“>>>> ...

  6. IOS开发基础知识--碎片2

    六:获得另一个控件器,并实现跳转 UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboa ...

  7. Android--split()分割字符串特殊用法

    split()分割字符串 1.不同环境下的区分 Java:分割字符串不能写成split("$")//$为要分割的字符Android:分割字符串需要加上中括号split(" ...

  8. 【转载】ReactiveX 的理念和特点

    原作者地址:http://www.open-open.com/lib/view/open1440166491833.html ReactiveX是Reactive Extensions的缩写,一般简写 ...

  9. Invoke--转载

    在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界 ...

  10. winform(三)——更换主窗体例子

    做一个登录窗口,登录成功时关闭form1,展示from2界面 1.主界面Login namespace WindowsFormsApplication1 { public partial class ...