浅析 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传递给形参ym(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() 函数。

原文地址:https://www.cnblogs.com/Gbeniot/p/10384480.html

时间: 2024-11-09 00:38:59

浅析 JavaScript 中的 Function.prototype.bind() 方法的相关文章

理解 JavaScript 中的 Function.prototype.bind

函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其实就是 Function.prototype.bind(),只是你有可能仍然没有意识到这点. 第一次遇到这个问题的时候,你可能倾向于将this设置到一个变量上,这样你可以在改变了上下文之后继续引用到它.很多人选择使用 self, _this 或者 context 作为变量名称(也有人使用 that)

深入理解javascript中的Function.prototye.bind

函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其实就是 Function.prototype.bind(),只是你有可能仍然没有意识到这点. 第一次遇到这个问题的时候,你可能倾向于将this设置到一个变量上,这样你可以在改变了上下文之后继续引用到它.很多人选择使用 self, _this 或者 context 作为变量名称(也有人使用 that)

javascript中的call(),apply(),bind()方法的区别

之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再进行补充. 1. 改变this的指向 var obj = { name : '张三', age : 17, myFun : function () { console.log(this.name + ' ' + this.age); } } var obj2 = { name : '李四', age

浅析 JavaScript 中的 函数 currying 柯里化

原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果.因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程. 柯里化一个求和函数 按照分步求值,我们看一个

Function.prototype.bind接口浅析

本文大部分内容翻译自 MDN内容, 翻译内容经过自己的理解. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind Function.prototype.bind Syntax fun.bind(thisArg[, arg1[, arg2[, ...]]]) Parameters thisArg The value to be passed as the thi

《javascript设计模式与开放实践》学习(一)Function.prototype.bind

使用Function.prototype.bind来包装func函数 1.简化版的bind Function.prototype.bind=function (context) { var self=this; //保存原函数 return function () { return self.apply(context,arguments); } }; var obj={name:'seven'}; var func=function(){ alert(this.name); }.bind(ob

JavaScript中的Array.prototype.slice.call()方法学习

JavaScript中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). 但有一个例外,IE下的节点集合它不能转换(因为IE下的dom对象是以com对象的形式实现,js对象和com对象不能进行转换) 首先,我们来看看JavaScript中的slice用法, 在JavaScript中Array是一个类,slice是此类中的一个方法,slice的中文意思是 '截取' 一个是String.

浅析function.prototype.bind

作用: 对于一个给定的函数,创造一个绑定对象的新函数,这个函数和之前的函数功能一样,this值是它的第一个参数,其它参数,作为新的函数的给定参数. bind最直接的作用就是改变this的指向: // 定义函数 var checkNumericRange = function (value) { if (typeof value !== 'number') return false; else return value >= this.minimum && value <= th

深入浅出:了解JavaScript中的call,apply,bind的差别

在 javascript之 this 关键字详解文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,this指向全局:当在某个对象中使用this时,this指向该对象:当把某个对象的方法赋值给      另外一个对象时,this会指向后一个对象. 3.this的使用场合有:在全局环境中使用:在构造函数中使用,在对象的方法中使用. 4.this的使用注意点,最重要的一点就是要避免多层嵌套使用this对象.