浅析 JavaScript 中的 Function.prototype.bind() 方法
Function.prototype.bind()方法
bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数的值。
例如,在 f() 函数上调用 bind() 方法并传入参数 obj ,即 f.bind(obj) ,这将返回一个新函数, 新函数会把原始的函数 f() 当做 obj 的方法来调用,就像 obj.f() 似的,当然这时 f() 函数中的 this 对象指向的是 obj 。
简单使用情形一
var o={
f: function () {
var self=this;
var fff=function() {
console.log(self.value); //此时 this 指向的是全局作用域 global/window,因此需要使用 self 指向对象o
};
fff();
},
value: "Hello World!"
};
o.f(); // Hello World!
上例是我们常用了 保持 this 上下文的方法,把 this 赋值给了中间变量 self,这样在内部嵌套的函数中能够使用 self 访问到对象o,否则仍使用 this.value,内部嵌套函数的this此时指向的是全局作用域,最后的输出将会是 undefined,代码如下:
var o={
f: function () {
var self=this;
var fff=function() {
console.log(this.value);
};
fff();
},
value: "Hello World!"
};
o.f(); // undefined
但是,如果我们使用 bind()函数,将fff函数的绑定在对象o中,即将fff()函数内部的 this 对象绑定为对象 o,那么可以遇见此时 this.value 是存在的。代码如下:
var o={
f: function () {
var self=this;
var fff=function() {
console.log(this.value); // bind(this) 中 this 指向的是o,这里也可直接写成 bind(o)
}.bind(this);
fff();
},
value: "Hello World!"
};
o.f(); // Hello World!
更普遍的使用情形
再看一个例子:
function f(y,z){
return this.x+y+z;
}
var m=f.bind({x:1},2);
console.log(m(3)); // 6
最后将输出 6
这是因为 bind()方法会把传入它的第一个实参绑定给f函数体内的 this,从第二个实参起,将依此传递给原始函数,因此 {x:1}传递给this ,2传递给形参y,m(3) 调用时的3 传递给形参z。
其实这个例子 f() 函数能够处理部分参数,分步计算 ( bind() 时处理了参数x,和参数y,调用 m(3)时处理了参数z )的过程其实是一个典型的Curry过程(Currying)。
bind()背后的简单原理
那么bind函数背后做了什么呢? 我们可以用以下代码来模拟:
Function.prototype.testBind = function (scope) {
var fn = this; // this 指向的是调用testBind方法的一个函数
return function () {
return fn.apply(scope, arguments);
}
};
下面是测试的例子:
var foo = {x: "Foo "};
var bar = function (str) {
console.log(this.x+(arguments.length===0?'':str));
};
bar(); // undefined
var testBindBar = bar.testBind(foo); // 绑定 foo
testBindBar("Bar!"); // Foo Bar!
当调用 testBind() 后,我们创建了一个新的函数,通过调用 apply 将 this 设置成 foo, OK,现在应该比较清晰了,但实际 bind() 的实现远比上面的复杂,如上面提到的 curry化过程等,上面只是主要原理便于学习理解 bind() 函数。
参考资料:
Javascript权威指南
浅析 JavaScript 中的 Function.prototype.bind() 方法的更多相关文章
- JavaScript 中的 Function.prototype.bind() 方法
转载自:https://www.cnblogs.com/zztt/p/4122352.html Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个 ...
- 理解javascript中的Function.prototype.bind
在初学Javascript时,我们也许不需要担心函数绑定的问题,但是当我们需要在另一个函数中保持上下文对象this时,就会遇到相应的问题了,我见过很多人处理这种问题都是先将this赋值给一个变量(比如 ...
- 理解 JavaScript 中的 Function.prototype.bind
函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...
- prototype.js中Function.prototype.bind方法浅解
prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...
- 深入理解javascript中的Function.prototye.bind
函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其 ...
- Javascript中this作用域以及bind方法的重写
这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将bind方法用ES3重写,使用bind这个方法,导致一时半会懵了,只记得bind可以改变this的作用域. 作为查漏 ...
- JavaScript 函数绑定 Function.prototype.bind
ECMAScript Edition5 IE9+支持原生,作用为将一个对象的方法绑定到另一个对象上执行. Function.prototype.bind = Function.prototype.bi ...
- javascript中的call(),apply(),bind()方法的区别
之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再 ...
- 浅析 JavaScript 中的 函数 currying 柯里化
原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...
随机推荐
- 【详记MySql问题大全集】一、安装MySql
最近公司要从SqlServer转到MySql,期间在安装环境和数据迁移的过程中,遇到了一些不大不小问题,比如怎么重置密码.怎么设置大小写敏感等等. 这些问题都比较细比较杂,这边解决完可能过几天就忘了, ...
- [Swift]两种线程休眠的方式
一.线程休眠方式1 [Swift]与[C#]的比较: //C#:需要添加using System.Threading; //线程休眠3000毫秒,即3秒 Thread.Sleep(); //Swift ...
- JavaScript 快速入门
JavaScript是jquery的基础, JavaScript是一种描述性语言 JavaScript的组成 :ECMAScript,BOM,DOM. JavaScript的基本结构 <scri ...
- 一文搞懂 Linux network namespace
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 本文通过 IP ...
- Java 虚拟机对锁优化所做的努力
作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...
- dbvisual 9 使用自定义jdk版本运行
dbvisual 9 不支持jdk1.8 ,当系统默认的jdk是1.8且不方便修改时,可以自行指定运行dbvisual9.2 的jdk版本 打开dbvisgui.bat 将set JAVA_EXEC= ...
- JAVA基础-输入输出流
一,File类:文件的创建和删除 1.File(String pathname):pathname是指路径名称.用法 File file = new File("d:/1.txt " ...
- JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript之间转换
现在构建任何类型的软件项目最流行的方法这是使用类.在这篇文章中,探讨用 JavaScript 实现类的不同方法,以及如何构建类的结构.首先从深入研究原型工作原理,并分析在流行库中模拟基于类的继承的方法 ...
- (转)Apache从2.2换至2.4httpd.conf的调整笔记(windows环境)
原文:https://www.cnblogs.com/tjws/articles/3469075.html#top 整理一下Windows环境Apache 2.2 改成 Apache 2.4.1后 h ...
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...