美文网首页
bind详解

bind详解

作者: 骑骑小飞猪 | 来源:发表于2017-08-30 18:09 被阅读0次

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
语法 : fun.bind(thisArg[, arg1[, arg2[, ...]]])
参数含义
this.Arg
当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用[new 操作符],调用绑定函数时,该参数无效。
arg1, arg2, ...
当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法
返回值:返回由指定的this值和初始化参数改造的原函数拷贝

1.bind() 最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的 this 值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,希望方法中的 this 是原来的对象。(比如在回调中传入这个方法。)如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则能很漂亮地解决这个问题:

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.偏函数(Partial Functions)
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,在默认情况下,this 关键字会指向 [window](或全局)对象。当使用类的方法时,需要 this 引用类的实例,你可能需要显式地把 this绑定到回调函数以便继续使用实例。

function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  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();  // 一秒钟后, 调用'declare'方法

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

你知道不需要做特别的处理就可以用new操作符创建一个绑定函数。必然地,你需要知道不需要做特别处理就可以创建一个可以被直接调用的绑定函数,即使你更希望绑定函数是用new操作符来调用。

// 这个例子可以直接在你的 javascript 控制台运行
// ...接着上面的代码继续(译注:

// 仍然能作为一个普通函数来调用
// (即使通常来说这个不是被期望发生的)
YAxisPoint(13);
emptyObj.x + ',' + emptyObj.y;   //  '0,13'

5.如果你希望一个绑定函数只支持使用new操作符或者只能直接调用它,那么模板函数必须强制执行那限制。
快捷调用,在你想要为一个需要特定的 this 值的函数创建一个捷径(shortcut)的时候,bind()方法也很好用。你可以用 [Array.prototype.slice] 来将一个类似于数组的对象(array-like object)转换成一个真正的数组,就拿它来举例子吧。你可以创建这样一个捷径:

var slice = Array.prototype.slice;
// ...
slice.apply(arguments);

用 bind() 可以使这个过程变得简单。在下面这段代码里面,slice是 [Function.prototype]的 [call()] 方法的绑定函数,并且将 [Array.prototype] 的 [slice()] 方法作为 this的值。这意味着我们压根儿用不着上面那个 apply() 调用了。

// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
// ...
slice(arguments);

原文地址(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

相关文章

  • MachO动态库绑定过程详解

    动态库绑定过程详解 首先动态库绑定分为lazy bind 和no_lazy_bind,lazy bind 主要用于...

  • bind详解

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

  • bind Polyfill 详解javascript bind

    前端面试经常会遇到的一个面试题:手写bind方法 这篇文章就ECMAScript中bind Polyfill来详解...

  • call() , apply() 与 bind() 实例详解

    call() , apply() 与 bind() 详解 我们知道可以用call(), apply() 和 bin...

  • call apply

    js基础知识---call,apply,bind的用法 call,apply详解 javascript中,call...

  • bind函数详解

    object.getNameFunc()返回一个匿名函数,在全局环境调用该函数,this指向的全局对象 解决这一问...

  • this call apply bind【整理】

    详解JS中的this、apply、call、bind(经典面试题) https://m.jb51.net/arti...

  • Python 学习笔记 056

    本节预告 控件事件相关详解 label.bind("", func) 26.鼠标移动事件 " 鼠标滑...

  • JavaScript中call()、apply()、bind()

    call()、apply()、bind() 都是用来改变this指向的。 关于this 详解,可以看我另一篇文章J...

  • bind9 named.conf 详解

    bind9 named.conf 详解 acl:定义IP地址表的名字,用于访问控制等 语法: controls:宣...

网友评论

      本文标题:bind详解

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