Javascript中的Bind 、Call和Apply
看以下代码:
var bind = Function.prototype.call.bind(Function.prototype.bind);
第一眼看上去,我能猜出它究竟是用来做什么的。它把x.y(z)转化成了y(x,z)。
编写良好的代码会比较容易被读懂。在读完Functional Javascript和 JavaScript Allongé (两本都是相当好的书)这两本书之后,再加上在Javascript函数式编程方面有些经验,弄懂上面这段代码的意思毫无压力。但是应该怎么向没有函数式编程经验的人解释呢(正如大多数人关心的那样)?
//设立一个简单地对象作为“上下文”
var context = { foo: "bar" }; //一个在this上下文中指向foo变量的函数
function returnFoo () {
return this.foo;
} // 变量在作用域中不存在,因此显示undefined
returnFoo(); // => undefined // 如果我们把它绑定在context上下文中
var bound = returnFoo.bind(context); // 现在的作用域中有这个变量了
bound(); // => "bar" //
// 这就是Function.prototype.bind的作用.
//由于returnFoo也是函数,因此它继承了function的原型
//
// 如果你觉得享受,接着往下读,下面更精彩
// // 有许多方法将函数绑定在一个上下文中
// Call和Apply让你能在上下文中调用函数
returnFoo.call(context); // => bar
returnFoo.apply(context); // => bar // 将函数添加到对象中
context.returnFoo = returnFoo;
context.returnFoo(); // => bar //
// 现在我们来玩一点诡异的东西
// // Array.prototype 中有一个叫做slice的方法
// 对一个数组调用slice,可以返回一个从start index到end index的数组
[1,2,3].slice(0,1); // => [1] // 因此我们把Array.slice赋值给一个本地变量slice
var slice = Array.prototype.slice; //现在的slice是"自由的",由于Array.prototype中的slice一般指定了上下文
//或者默认为this,此时slice将不起作用
slice(0, 1); // => TypeError: can't convert undefined to object
slice([1,2,3], 0, 1); // => TypeError: ... // 但是如果我们使用call或者apply,slice又将在一个上下文中执行
slice.call([1,2,3], 0, 1); // => [1] // Apply和Call差不多,只是参数要放在一个数组中
slice.apply([1,2,3], [0,1]); // => [1] // 使用call没错了,那么能不呢使用bind呢?
// 没错,我们来把"call"绑定在slice上
slice = Function.prototype.call.bind(Array.prototype.slice); // 现在slice可以把第一个参数作为上下文了
slice([1,2,3], 0, 1); // => [1] //
// 很酷,对吧。现在再来完成一件事
// // 现在我们对bind本身做一件刚才对silce做的事
var bind = Function.prototype.call.bind(Function.prototype.bind); // 在这里总结一下,好好想想
// 发生了什么事? 我们改变了call,
// 返回一个接收一个函数和一个上下文作为ic桉树的函数
//并且返回了一个完全绑定的函数 // 回到最初的例子
var context = { foo: "bar" };
function returnFoo () {
return this.foo;
} // 现在来使用神奇的"bind"函数
var amazing = bind(returnFoo, context);
amazing(); // => bar
原文:http://www.html-js.com/article/1553
英文原文:https://variadic.me/posts/2013-10-22-bind-call-and-apply-in-javascript.html
参考文章: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Javascript中的Bind 、Call和Apply的更多相关文章
- JavaScript中的bind,call和apply函数的用法和区别
一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式, ...
- 把玩Javascript中的bind
前言 今天闲着无聊随便逛了逛MDN,忽而看到一个方法Function.prototype.bind(),突然发现除了使用这个方法之外都没有仔细琢磨过这个方法.于是乎,找到了kill time的事情-写 ...
- Javascript中的bind详解
前言 用过React的同学都知道,经常会使用bind来绑定this. import React, { Component } from 'react'; class TodoItem extends ...
- JavaScript中的bind方法及其常见应用
一.bind()方法的实现 在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用.就拿最常见的console.log("info…")来说,避免书写 ...
- 理解JavaScript中的arguments,callee,caller,apply
arguments 该对象代表正在执行的函数和调用它的函数的参数. [function.]arguments[n] 参数function :选项.当前正在执行的 Function 对象的名字. n : ...
- Javascript中的bind()函数
今天看到公司大神的一段代码: function ReplaceProcessor() { this._dom = { btnReplace: $('#ro_btnReplace'), btnCompl ...
- [转] 理解 JavaScript 中的 Array.prototype.slice.apply(arguments)
假如你是一个 JavaScript 开发者,你可能见到过 Array.prototype.slice.apply(arguments) 这样的用法,然后你会问,这么写是什么意思呢? 这个语法其实不难理 ...
- JavaScript中callee与caller,apply与call解析
1. arguments.callee 1.1 解释 返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文. 1,.2 说明 callee 属性的初始值就是正被执行的 ...
- javascript中函数的call,apply及bind方法
call 方法调用一个对象的一个方法,以另一个对象替换当前对象.call([thisObj[,arg1[, arg2[, [,.argN]]]]])参数thisObj可选项.将被用作当前对象的对象. ...
随机推荐
- c++常用的一些库函数、常量和头文件
1.常用数学函数 头文件 #include <math> 或者 #include <math.h> 函数原型 功能 返回值 int abs(int x) 求整数x的绝对值 ...
- C#使用ConditionalAttribute特性来实现代码调试
转自:http://www.csharpwin.com/csharpspace/10729r8541.shtml #if/#endif条件编译常用来由同一份源代码生成不同的结果文件,最常见的有debu ...
- Form_Form Builder开发基于视图页面和自动代码生成包(案例)
2014-01-06 Created By BaoXinjian
- c#复习整理
一.基本语法 1.数据类型 整数类型:int.long 浮点类型:float.double.decimal 布尔类型:bool 字符串类型:string 2.类型转换 int a; double b ...
- JAVA用户数据输入
数据输入 首先需要导入扫描仪 然后声明扫描仪 输出输入提示 接收用户数据的数据 输出用户数据的数据 实例: import java.util.Scanner; //导入扫描仪 public class ...
- Guava 10-散列
概述 Java内建的散列码[hash code]概念被限制为32位,并且没有分离散列算法和它们所作用的数据,因此很难用备选算法进行替换.此外,使用Java内建方法实现的散列码通常是劣质的,部分是因为它 ...
- Java多线程之线程中断
该例子说明,Sleep可以被中断,但是I/O和synchronized不能被中断. package Thread.Interrupting; import java.io.IOException; i ...
- Restful API的设计与实践
Restful这个名称应该很多人都不陌生,但是我发现不少人对Restful存在或多或少的理解偏差,其中不泛比较厉害的程序员,所以有必要为Restful来“正名”. Restful是一种软件架构风格,设 ...
- 织梦后台更新,报错DedeCMS Error:Tag disabled:"php" more...
网站采用织梦v5.7版本,在做过一次后台补丁更新后,再对网站“生成”操作的时候,无厘头出现报错“ 网站后台--系统--系统基本参数---其他选项 ---模板引擎禁用标签:php ,把php删掉 保存 ...
- ramBufferSizeMB
索引算法确定 的情况下,影响Lucene索引速度的因素 MaxBufferedDocs这个参数默认是disabled的,因为Lucene中还用另外一个参数(RAMBufferSizeMB)控制这个bu ...