方法描述

bind()方法创建一个新函数,当被调用时,将其this关键字设置为提供的值。

语法说明

fn.bind(thisArg,arg1,arg2,..)

参数说明

thisArg:当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new操作符调用绑定函数时,该参数无效。

arg1,arg2,…:当绑定函数被调用时,这些参数将传递给被绑定的方法。

应用场景

1、创建绑定方法

this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
}; module.getX(); // 返回 81 var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域 // 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

2、偏函数

bind()的另一个简单用法就是使一个函数拥有预设的初始参数。这些参数会作为bind()的第二个参数跟在this后面,之后它们会插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。

function list() {
return Array.prototype.slice.call(arguments);
} var list1 = list(1, 2, 3); // [1, 2, 3] // Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37); var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

3、配合setTimeout

在默认情况下,使用window.setTimeout()时,this关键字会指向window(或全局)对象。当使用类的方法时,需要this引用类的实例,需要显式地把this绑定到回调函数以便继续使用实例。

4、作为构造函数使用的绑定函数

绑定函数适用于用new操作符去构造一个由目标函数创建的新的实例。当一个绑定函数是用来构建一个值的,原来提供的 this 就会被忽略。然而, 原先提供的那些参数仍然会被前置到构造函数调用的前面。

function Point(x, y) {
this.x = x;
this.y = y;
} Point.prototype.toString = function() {
return this.x + ',' + this.y;
}; var p = new Point(1, 2);
p.toString(); // '1,2' var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);
// 以下这行代码在 polyfill 不支持,
// 在原生的bind方法运行没问题:
//(译注:polyfill的bind方法如果加上把bind的第一个参数,即新绑定的this执行Object()来包装为对象,Object(null)则是{},那么也可以支持)
var YAxisPoint = Point.bind(null, 0/*x*/); var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5' axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true

Polyfill

bind()函数在 ECMA-262 第五版才被加入;它可能无法在所有浏览器上运行。你可以部份地在脚本开头加入以下代码,就能使它运作,让不支持的浏览器也能使用 bind() 功能。

if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
} var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
// this instanceof fNOP === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fNOP
? this
: oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
}; // 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP(); return fBound;
};
}

【前端基础系列】理解bind方法使用与实现的更多相关文章

  1. 【前端基础系列】slice方法将类数组转换数组实现原理

    问题描述 在日常编码中会遇到将类数组对象转换为数组的问题,其中常用到的一种方式使用Array.prototype.slice()方法. 类数组对象 所谓的类数组对象,JavaScript对它们定义为: ...

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

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

  3. 【前端基础系列】理解GET与POST请求区别

    语义区别 GET请求用于获取数据 POST请求用于提交数据 缓存 GET请求能被缓存,以相同的URL再去GET请求会返回304 POST请求不能缓存 数据长度 HTTP协议从未规定过GET/POST请 ...

  4. js作用域与执行环境(前端基础系列)

    一.作用域(what?) 官方解释是:"一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域." 单从文字理解比较难懂,举个栗子: ...

  5. javascript 命名空间与运用(前端基础系列)

    所谓代码,当你随便命名一个变量:var name = "ukerxi"; 就是一句代码:但当你的代码写出来后,对于后续维护及阅读的人,就可以看出代码是否,易读,易理解:优雅的代码总 ...

  6. navigator.userAgent浏览器检测(前端基础系列)

    对于前端来说,浏览器检测已经不陌生了,在做一些页面是,需要针对不同的浏览器进行处理不同的逻辑,最简单的就是区分pc和移动端的浏览器,或是android 和ios下的浏览器. 一.浏览器检测的由来?  ...

  7. “use strict” 严格模式使用(前端基础系列)

    ECMAscript5添加一种严格模式的运行模式("use strict"),让你的js语句在更加严格的环境下进行运行: 一.主要作用: 消除版本javascript中一些不合理及 ...

  8. 前端基础系列——CSS规范(文章内容为转载)

    原作者信息 作者:词晖 链接:http://www.zhihu.com/question/19586885/answer/48933504 来源:知乎 著作权归原作者所有,转载请联系原作者获得授权. ...

  9. C#基础系列 - 抽象类及其方法的学习

    在C#中使用关键字 abstract 来定义抽象类和抽象方法. 不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例. "一个包含一个或多个纯虚函数的类 ...

随机推荐

  1. JS的Ajax和同源策略

    JS实现的ajax AJAX核心(XMLHttpRequest) 其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象.所有的异步交互都是使用XMLHttpSer ...

  2. genPanel.py

    #!/usr/bin/python # -*- coding: UTF-8 -*- import os import sys import re import shutil import glob ' ...

  3. 利用表格分页显示数据的js组件datatable的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. nginx中Geoip_module模块的使用

    nginx中Geoip_module模块的使用 .安装模块,nginx也是通过yum安装 yum install nginx-module-geoip -y # 可以看到模块的链接库文件 [root@ ...

  5. 快速解决PHP调用Word组件DCOM权限的问题

    1. 首先必须要在电脑上安装 Office 2. windows+r : 输入 dcomcnfg.exe 打开组件服务,然后双击 组件服务 ==> 双击 计算机 ==> 双击 我的电脑 = ...

  6. 用于主题检测的临时日志(c5ac07a5-5dab-45d9-8dc2-a3b27be6e507 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

    这是一个未删除的临时日志.请手动删除它.(5051e554-d10d-4e48-b2ca-37c38a30153a - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

  7. python学习第39天

    # 数据操作 # 增 # 删 # 改 # 查 # 单表查询 # 多表查询

  8. Linux多台主机间配置SSH免密登陆

    1.安装ssh.  sudo apt-get install ssh. 安装完成后会在~目录(当前用户主目录,即这里的/home/xuhui)下产生一个隐藏文件夹.ssh(ls -a 可以查看隐藏文件 ...

  9. GZip、deflate和sdch压缩(网摘整理)

    GZip和deflate: gzip是一种数据格式,默认且目前仅使用deflate算法压缩data部分:deflate是一种压缩算法,是huffman编码的一种加强. deflate与gzip解压的代 ...

  10. python按照字典排序

    d = {'a':1,'b':4,'c':2} 方法一: sorted(d.items(),key = lambda x:x[1],reverse = True) 方法二: import operat ...