ECMAScript 5(ES5)中bind方法简介备忘

一直以来对和this有关的东西模糊不清,譬如call、apply等等。这次看到一个和bind有关的笔试题,故记此文以备忘。

  bind和call以及apply一样,都是可以改变上下文的this指向的。不同的是,call和apply一样,直接引用在方法上,而bind绑定this后返回一个方法,但内部核心还是apply。

  直接看例子:


1

2

3

4

5

6

7

8

9

10

11

12

var obj = {

  a: 1,

  b: 2,

  getCount: function(c, d) {

    return this.a + this.b + c + d;

  }

};

window.a = window.b = 0;

console.log(obj.getCount(3, 4));  // 10

var func = obj.getCount;

console.log(func(3, 4));  // 7

  为何会这样?因为func在上下文中的this是window!bind的存在正是为了改变this指向获取想要的值:


1

2

3

4

5

6

7

8

9

10

11

var obj = {

  a: 1,

  b: 2,

  getCount: function(c, d) {

    return this.a + this.b + c + d;

  }

};

window.a = window.b = 0;

var func = obj.getCount.bind(obj);

console.log(func(3, 4));  // 10

  bind是function的一个函数扩展方法,bind以后代码重新绑定了func内部的this指向(obj),但是不兼容ie6~8,兼容代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

var obj = {

  a: 1,

  b: 2,

  getCount: function(c, d) {

    return this.a + this.b + c + d;

  }

};

Function.prototype.bind = Function.prototype.bind || function(context) {

  var that = this;

  return function() {

    // console.log(arguments); // console [3,4] if ie<6-8>

    return that.apply(context, arguments);

  }

}

window.a = window.b = 0;

var func = obj.getCount.bind(obj);

console.log(func(3, 4));  // 10

  其实在我看来bind的核心是返回一个未执行的方法,如果直接使用apply或者call:


1

2

var ans = obj.getCount.apply(obj, [3, 4]);

console.log(ans); // 10

  无法使用简写的func函数构造,所以用bind传递this指向,再返回一个未执行的方法,实现方式相当巧妙。

时间: 2024-10-05 14:30:24

ECMAScript 5(ES5)中bind方法简介备忘的相关文章

【转载】JS中bind方法与函数柯里化

原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情况戳这里ECMAScript 5 compatibility table),权威指南上提到在ES3中利用apply模拟该方法的实现(JS权威指南中函数那章), 但无法真实还原该方法, 这也是真bind方法中的有趣特性. (原文这边理解有问题, 这段话的意思如果结合犀牛书上下文的意思, 再结合犀牛书中

...扩展运算符妙用 - ES5中push方法的参数不能是数组

含义 扩展运算符( spread )是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5 [...document.querySelectorAll('div')] // [<div>, <div>, <div>] 该运算符主要用于函数调用. array.push(...ite

Javascript中bind()方法的使用与实现

我们先来看一道题目 1 2 3 4 var write = document.write;  write("hello");  //1.以上代码有什么问题 //2.正确操作是怎样的 不能正确执行,因为write函数丢掉了上下文,此时this的指向global或window对象,导致执行时提示非法调用异常,所以我们需要改变this的指向 正确的方案就是使用 bind/call/apply来改变this指向 bind方法 1 2 var write = document.write; wr

JavaScript里call,apply,bind方法简介

JavaScript里call,apply,bind方法不太容易理解,其实背后的思想并不算非常复杂,希望本文能帮你更好地了解这3个很像,而且看似很神秘的方法. 非要用一个关键字来点明它们的背后思想的精髓的话,关键字就是:this 因为通常程序员对C++比较熟,先借用C++,简单说一下this. 类的成员函数里,都可以用this来访问当前类的成员,但问题是成员函数的参数并没有this这个参数,比如: Animal a; a.eat(); a.eat("meat"); Animal的对象调

shell中${##%%}代表啥,备忘

#!/bin/bash A=aigo.goto.aigo.goto echo ${A#*go} echo ${A##*go} echo ${A%.*} echo ${A%%go*} 执行结果 .goto.aigo.goto to aigo.goto.aigo ai 备忘如下: #*字串 --从左向右将变量A中最先出现的"字串"(最靠左)以及其左边的一切都去掉(因为有个*) ##*字串 --从左向右将变量A中最后出现的"字串"(最靠右)以及其左边的一切都去掉 %字串*

通用mapper的增删改查方法 留存 备忘

Mybatis通用Mapper介绍与使用 前言 使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQL.而且,当数据库表结构改动时,对应的所有SQL以及实体类都需要更改.这工作量和效率的影响或许就是区别增删改查程序员和真正程序员的屏障.这时,通用Mapper便应运而生-- 什么是通用Mapper 通用Mapper就是为了解决单表增删改查,基于Mybatis的插件.开发人员不需要编写SQL,不需要在DA

C++中 _itoa_s方法简介

_itoa_s 函数原型如下: 1 _itoa_s 2 ( 3 int value, 4 char *buffer, 5 size_t sizeInCharacters, //存放结果的字符数组长度 6 int radix //进制 7 ); 使用如下: 1 const int g_MaxNumberLength = 10 ;//数的最大位数 2 void intochar(int* numbers , int lenght) 3 { 4 char** strNum = new char*[le

开发过程遇到的问题和解决方法(备忘)

2015-3-19 1.当项目框架为.Net Framework4.0的时候,使用EF6.0会出问题. 解决方法:将引用的EF相关dll改成EF5.0的DLL. 2.EF使用Model First方式建立数据库时,发布网站至IIS或者服务器上时,微软会采取sql登录验证而采取Windows(即连接字符串为Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=true; 时会出问题) 解决方法:将EF的

C#中符号的作用备忘

~ 按位求补符: ! 非逻辑运算符: % 求余运算符: ^ 异或位运算符: & 且位运算符: |  或位运算符: * 既可以用作乘法符号,还可以表示为指针: + 表示数学运算符相加: = 用来表示赋值操作: \  用于转义符的开始,如\n表示换行: ”  包裹字符串: ’  包裹单个字符: < 逻辑运算符小: > 逻辑运算符大: , 用于分隔参数: . 用于表示对象成员选择器或小数点: / 表示除以的数学运算符: # 用于条件编译或划分代码块. #if #else 控制预编译的代码:如