美文网首页JavaScript学习笔记
bind()使用场景及原理

bind()使用场景及原理

作者: 小二子SAMA | 来源:发表于2018-04-02 22:17 被阅读0次

bind()的语法是:

    fun.bind(thisArg[, arg1[, arg2[, ... ]]]);

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

arg1, arg2... :当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

返回值:返回由指定的this值和初始化参数改造的原函数拷贝。

bind()使用场景:

1)作为绑定函数使用,并且设置函数的this值。


````

var name = "The Window";

var object = {

    name : "My Object",

    getNameFunc : function() {

        return function(){

            return this.name;

        }

    }

}

console.log(object.getNameFunc()());//>The Window

````

getNameFunc()返回一个匿名函数,object.getNameFunc()()立即调用它返回的函数,匿名函数的执行环境具有全局性,因此其this对象通常指向window。

为解决上面方法,我们可以把外部作用域中的this对象保存在闭包函数能够访问到的变量里:


````

var name = "The Window";

var object = {

    name : "My Object",

    getNameFunc : function() {

        var _this = this;

        return function(){

            return _this.name;

        }

    }

}

console.log(object.getNameFunc()());//>My Object

````

当然也可以bind()方法:


````

var name = "The Window";

var object = {

    name : "My Object",

    getNameFunc : function() {

        return function(){

            return this.name;

        }.bind(this)

    }

}

console.log(object.getNameFunc()());//>My Object

````

上面通过bind()方法实现的绑定,效果等价于如下:


````

var name = "The Window";

var object = {

name : "My Object",

getNameFunc : function() {

return function(){

return this.name;

}.apply(this)

}

}

console.log(object.getNameFunc());//>My Object

````

2) 偏函数,使一个函数拥有预设的初始值,也称柯里化(currying)


````

var sum = function(x, y) {return x + y;};

var succ = sum.bind(null, 1);//创建一个类似sum的新函数,this值设为null,指向全局变量

//第一个参数绑定到1,新的函数期望只传入一个实参

succ(2);//>3

````

3)配合setTimeout()使用


````

function LateBloomer() {

  this.petalCount = Math.ceil(Math.random() * 12) + 1;

}

// Declare bloom after a delay of 1 second

LateBloomer.prototype.bloom = function() {

//如果不使用bind()绑定作用域,作用域为winidow

  window.setTimeout(this.declare.bind(this), 1000);

};

LateBloomer.prototype.declare = function() {

  console.log('I am a beautiful flower with ' +

    this.petalCount + ' petals!');

};

var flower = new LateBloomer();

flower.bloom();  

````

4) 作为构造函数的绑定函数,即通过new关键字调用bind()产生的绑定函数,bind()中俄第一个参数(指定this值的参数)不起作用,后续参数正常使用。


````

function Person(_age, _address) {

this.age = _age;

this.address = _address;

console.log(this.name);//undefined

console.log(this.age);//23

}

var north = {

name : "north"

}

var northBind = Person.bind(north, 24);

var northObj = new northBind();

````

name并不是north对象含有的名字,可见第一个参数并没有起作用。

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() {

          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 = new fNOP();

    return fBound;

  };

}

````

看这段代码需要注意的的几个点:

1. bind()返回值是改造参数后的原函数的拷贝,所以调用bind()的必须是函数;

2. 如果返回的函数是一个构造函数,那么this不改变,即不会被传入的第一反应参数重写。

3. fBound函数中对arguments的操作,其实是对bind()函数返回的绑定函数的参数的操作,aArgs和arguments的合并实现了参数预设功能。

4. bind()函数返回的绑定函数与最开始的原函数具有相同的原型

bind()和apply()、call()的区别:

bind()返回一个绑定函数,apply()、call()是立即调用原函数。

备注:可能还是没有完全理解bind吧。。。

参考:

Function.prototype.bind()

相关文章

  • bind()使用场景及原理

    bind()的语法是: fun.bind(thisArg[, arg1[, arg2[, ... ]]]); ...

  • iOS面试进阶篇(五)

    目录 block原理及使用多线程方式OC内存管理机制代理,通知的区别及使用场景宏const,const,exter...

  • Websocket原理及使用场景

    WebSocket的使用场景 社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天...

  • 探究call、bind、apply知识点

    call、bind、apply知识点 一、食用方式 apply call bind 二、使用场景 基本理念:借用方...

  • 2019-02-20 JMeter分布式测试

    一:分布式使用场景及原理 使用场景:由于Jmeter是JAVA应用,对于CPU和内存的消耗比较大,所以,当需要模拟...

  • bind的使用场景

    bind的使用场景 文章JavaScript容易混淆的地方提到了bind最简单的应用是用于绑定方法的运行时作用域。...

  • Vue 指令的使用(一)常用指令

    一、 v-bind 变量绑定 1.使用场景: 动态绑定属性的值 2.使用方法: 属性前添加v-bind:即可 v...

  • bind的运用和bind的实现

    1.bind和call,apply一样都是改变this指向的 原理是使用bind方法,会将函数绑定到指定的对象上,...

  • Websocket原理及使用场景[转载]

    WebSocket的使用场景 社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天...

  • iOS Runtime原理及使用场景

    一,Runtime 是什么? Objective-C是一门面向对象的动态语言,该语言采用“消息结构”,其运...

网友评论

    本文标题:bind()使用场景及原理

    本文链接:https://www.haomeiwen.com/subject/mirncftx.html