澳门在线威尼斯官方 > 威尼斯澳门在线 > bind详细分析,你可能需要了解的知识点以及使用

原标题:bind详细分析,你可能需要了解的知识点以及使用

浏览次数:103 时间:2019-10-06

关于 bind 你或者需求了然的知识点以及选用情况

2016/08/18 · JavaScript · bind

正文笔者: 伯乐在线 - 韩子迟 。未经小编许可,制止转发!
招待参与伯乐在线 专辑撰稿人。

不看不清楚,一看吓一跳,已经整整三个月没有更新 underscore 源码解读种类文章了。前边我们早已到位了 Object ,Array,Collection 上的增加方法的源码解析,本文早先来解读 Function 上的扩大方法。

总体的 underscore 源码解读类别文章请移步 ,以为还阔以的话,给个 star 鼓劲下楼主呗 ^_^

那篇文章首要介绍了Javascript Function.prototype.bind详细剖析的相关质地,供给的情人能够参照下

bind 简介

Ok,今日要讲的就是 bind。关于 bind,能够先活动楼主在此之前写的稿子 ECMAScript 5(ES5) 中 bind 方法简要介绍备忘,有个主导的概念。

bind() 方法会创设四个新函数,当以此新函数被调用时,它的 this 值是传递给 bind() 的率先个参数, 它的参数是 bind() 的其他参数和其本来的参数。

语法是那般样子的:

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

1
fun.bind(thisArg[, arg1[, arg2[, ...]]])
  • thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用 new 操作符调用绑定函数时,该参数无效。
  • arg1, arg2, … (可选)当绑定函数被调用时,这个参数加上绑定函数本身的参数会根据顺序作为原函数运营时的参数。

  Function.prototype.bind分析

参数

bind 的第三个参数会作为原函数运维时的 this 指向,相当少说;而第贰个起来的参数是可选的,当绑定函数被调用时,这么些参数加上绑定函数自身的参数会依据顺序作为原函数运转时的参数。怎么知道?

function fn(a, b, c) { return a + b + c; } var _fn = fn.bind(null, 10); var ans = _fn(20, 30); // 60

1
2
3
4
5
6
function fn(a, b, c) {
  return a + b + c;
}
 
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30); // 60

fn 函数要求四个参数,_fn 函数将 10 作为暗中认可的率先个参数,所以只必要传入四个参数就能够,要是您非常的大心传入了八个参数,放心,也只会取前三个。

function fn(a, b, c) { return a + b + c; } var _fn = fn.bind(null, 10); var ans = _fn(20, 30, 40); // 60

1
2
3
4
5
6
function fn(a, b, c) {
  return a + b + c;
}
 
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30, 40); // 60

那有吗用吧?假使有个别函数,前多少个参数已经 “内定” 了,我们便能够用 bind 再次回到三个新的函数。也正是说,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]

1
2
3
4
5
6
7
8
9
10
11
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]

bind()方法会创造三个新的函数,成为绑定函数。当调用那个绑定函数时,绑定函数会以创办它时传出的第贰个参数作为this,传入bind()方法的第三个以及以后的参数加上绑定函数运转时自己的参数依据顺序作为原函数的参数来调取原函数。

new

利用 bind 重返的结果依然个 function,是个 function 就足以被 new 运算符调用,那么结果吧?标准中说的很理解了,当使用 new 操作符调用绑定函数时,bind 的率先个参数无效。

function Person(name, age) { this.name = name; this.age = age; } var _Person = Person.bind({}); var p = new _Person('hanzichi', 30); // Person {name: "hanzichi", age: 30}

1
2
3
4
5
6
7
function Person(name, age) {
  this.name = name;
  this.age = age;
}
 
var _Person = Person.bind({});
var p = new _Person('hanzichi', 30); // Person {name: "hanzichi", age: 30}

相似大家不会去这么用,不过一旦要写个 bind 的 polyfill(),照旧需求想念用 new 调用的意况。

大家也得以设置默许值(参照他事他说加以考察上一小节),原先提供的那个参数如故会被放到到构造函数调用的先头。

function Person(name, age) { this.name = name; this.age = age; } var _Person = Person.bind(null, 'hanzichi'); var p = new _Person(30); // Person {name: "hanzichi", age: 30}

1
2
3
4
5
6
7
function Person(name, age) {
  this.name = name;
  this.age = age;
}
 
var _Person = Person.bind(null, 'hanzichi');
var p = new _Person(30); // Person {name: "hanzichi", age: 30}

      实际使用中大家平时会境遇这么的标题:

配合 setTimeout

哪天便于错过 this 指向?恩,setTimeout 是二个意况,很轻松把 this 指向 window,当然,setInterval 也是一样。当使用对象的不二诀窍时,须求 this 引用对象,你或然须要显式地把 this 绑定到回调函数以便继续运用对象。

var canvas = { render: function() { this.update(); this.draw(); }, update: function() { // ... }, draw: function() { // ... } }; window.setInterval(canvas.render, 1000 / 60);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var canvas = {
  render: function() {
    this.update();
    this.draw();
  },
 
  update: function() {
    // ...
  },
 
  draw: function() {
    // ...
  }
};
 
window.setInterval(canvas.render, 1000 / 60);

用 canvas 写特效恐怕做游戏时平时会超出类似的主题素材。上边的代码是有题指标,render 方法中的 this 其实被针对了 window!大家得以用 bind,显式地把 this 绑定到回调函数以便继续使用该指标。

window.setInterval(canvas.render.bind(canvas), 1000);

1
window.setInterval(canvas.render.bind(canvas), 1000);

附近的事态还或者有 dom 的事件监听,一比非常的大心或者 this 就被指向了 dom 元素。能够参照他事他说加以考察下以前做 bigrender 时写的那部分代码 。

var name = "pig";

tip

bind 仍是能够做一些好玩的事务。

普普通通来说,将多少个类数组转为数组,大家会用 slice(ie9- 不协助)。参谋

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

1
2
3
4
var slice = Array.prototype.slice;
 
// slice.apply(arguments);
// slice(arguments, 1);

bind 能让调用变的更是简明。

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

1
2
3
4
5
6
7
8
// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
 
// ...
 
slice(arguments);
// slice(arguments, 1);

再举个八九不离十的例子,比方说大家要增进事件到四个节点,for 循环当然未有其余难点,我们还是能够 “剽窃” forEach 方法:

Array.prototype.forEach.call(document.querySelectorAll('input[type="button"]'), function(el){ el.addEventListener('click', fn); });

1
2
3
Array.prototype.forEach.call(document.querySelectorAll('input[type="button"]'), function(el){
  el.addEventListener('click', fn);
});

更上一层楼,大家得以用 bind 将函数封装的更加好:

var unboundForEach = Array.prototype.forEach , forEach = Function.prototype.call.bind(unboundForEach); forEach(document.querySelectorAll('input[type="button"]'), function (el) { el.addEventListener('click', fn); });

1
2
3
4
5
6
var unboundForEach = Array.prototype.forEach
  , forEach = Function.prototype.call.bind(unboundForEach);
 
forEach(document.querySelectorAll('input[type="button"]'), function (el) {
  el.addEventListener('click', fn);
});

同等看似的,大家得以将 x.y(z) 形成 y(x,z) 的款型:

var obj = { num: 10, getCount: function() { return this.num; } }; var unboundBind = Function.prototype.bind , bind = Function.prototype.call.bind(unboundBind); var getCount = bind(obj.getCount, obj); console.log(getCount()); // 10

1
2
3
4
5
6
7
8
9
10
11
12
var obj = {
  num: 10,
  getCount: function() {
    return this.num;
  }
};
 
var unboundBind = Function.prototype.bind
  , bind = Function.prototype.call.bind(unboundBind);
 
var getCount = bind(obj.getCount, obj);
console.log(getCount());  // 10

再举个栗子。每隔一秒在调节台打字与印刷 1-5,看起来是道考查闭包的精粹题目。

for(var i = 1; i <= 5; i++) { !function(i) { setTimeout(function() { console.log(i); }, i * 1000); }(i); }

1
2
3
4
5
6
7
for(var i = 1; i <= 5; i++) {
  !function(i) {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  }(i);
}

ES6 下能用 let

for(let i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); }

1
2
3
4
5
for(let i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}

也能够用 bind,眨眼之间间逼格提高:

for(var i = 1; i <= 5; i++) { setTimeout(console.log.bind(console, i), i * 1000); }

1
2
3
for(var i = 1; i <= 5; i++) {
  setTimeout(console.log.bind(console, i), i * 1000);
}

function Person(name){

Read more

关于 bind 的牵线就到此处,下一篇小说将整合 underscore 来讲讲什么兑现多个bind 的 polyfill。

  • Function.prototype.bind()
  • ECMAScript 5(ES5) 中 bind 方法简要介绍备忘
  • Javascript 中的 Bind ,Call 以及 Apply
  • Javascript 中 bind() 方法的利用与落实

打赏帮助自个儿写出更加多好作品,多谢!

打赏笔者

  this.name = name;

打赏援救作者写出更加多好小说,多谢!

图片 1

1 赞 7 收藏 评论

  this.getName = function(){

至于小编:韩子迟

图片 2

a JavaScript beginner 个人主页 · 笔者的稿子 · 9 ·    

图片 3

    setTimeout(function(){

      console.log("Hello,my name is "+this.name);

    },100);

  }

}

var weiqi = new Person("卫旗");

weiqi.getName(); 

//Hello,my name is pig

      这一年输出this.name是pig,原因是this的指向是在运营函数时规定的,并不是在概念函数时规定的,再因为setTimeout是在大局意况下只想,所以this就针对了window。

      在此以前消除那个标题标主意平日是缓存this,举例:

var name = "pig";

function Person(name){

  this.name = name;

  this.getName = function(){

    //在此间缓存一个this

    var self = this;

    setTimeout(function(){

      //在这里是有缓存this的self

      console.log("Hello,my name is "+self.name);

    },100);

  }

}

var weiqi = new Person("卫旗");

weiqi.getName();

//Hello,my name is 卫旗

      那样就消除了那些标题,特别方便,因为它使得setTimeout函数中得以访谈Person的上下文。

      以后有贰个越来越好的消除办法,能够选拔bind()函数,上边的例子能够被更新为:

var name = "pig";

function Person(name){

  this.name = name;

  this.getName = function(){

    setTimeout(function(){

      console.log("Hello,my name is "+this.name);

    }.bind(this),100);

    //注意上面这一行,加多了bind(this)

  }

}

var weiqi = new Person("卫旗");

weiqi.getName();

//Hello,my name is 卫旗

      bind()最简便易行的用法是成立多少个函数,使得这一个函数无论什么样调用都独具同样的this值。JavaScript菜鸟平日犯的多个漏洞非常多就是将二个方式从叁个目的中拿出来,然后再调用,希望方法中的this是原先的指标(譬喻在回调函数中流传这些方法)。要是不做非常管理的话,平常会遗弃原本的对象。从原来的函数和原本的指标创制一个绑定函数,则足以绝对美丽的缓慢解决那几个难点:

//定义全局变量x

var x = "window";

本文由澳门在线威尼斯官方发布于威尼斯澳门在线,转载请注明出处:bind详细分析,你可能需要了解的知识点以及使用

关键词:

上一篇:js框架入门,如何通过

下一篇:没有了