• 主页
  • 归档
  • 分类
  • 照片墙
所有文章 友情链接 关于我

  • 主页
  • 归档
  • 分类
  • 照片墙
  1. 1. 嗅探
  2. 2. 更严谨的做法

实现bind方法

2017-10-14 00:35:19
总字数 602
预计阅读时间 2 分钟

bind方法来自于Function.prototype
这个方法会创建一个新函数 , 当这个函数被调用时 , 第一个参数将会作为它运行时的this , 之后的参数会作为实际调用时传递的实参前作为实参

语法

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

应用示例 :

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
name : "Sookie",
show : function() {
console.log(this.name);
console.log(arguments);
}
}
var _show = obj.show.bind(obj,"aa","bb");
_show("cc");
/*output:
Sookie
{ '0': 'aa', '1': 'bb', '2': 'cc' }
*/

如果要实现一个bind方法 , 需要用到柯里化

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.bind = function(context) {
var me = this;//调用bind的函数对象
var args = Array.prototype.slice.call(arguments, 1);//传入的固定实参
return function () {
//实际调用时传入的参数
var innerArgs = Array.prototype.slice.call(arguments);
//合并两个参数数组
var finalArgs = args.concat(innerArgs);
//调用该函数
return me.apply(context, finalArgs);
}
}

这里解释一下 , arguments并不是数组对象 , 而是类数组

  • 具有 : 指向对象元素的数字索引 , 以及length属性
  • 不具有 : push , slice等数组对象的方法

数组对象的__proto__是Array
而arguments的 __proto__是Object

如果要把一个arguments转化为一个数组对象 , 可以使用如下方式

var args = Array.prototype.slice.call(arguments);

嗅探

在运行时如果对标准库当中的内容有修改
( 可能是出于兼容性的需要 , 比如旧版本的标准库当中无此函数 )

1
2
3
Function.prototype.bind = Function.prototype.bind || function(context) {
//...
}

这属于一个加分项
由于标准库当中的函数多是经过了深度优化的
一般要比我们自己写的函数效率更高 更健壮
所以如果标准库中存在 , 其实没有必要用我们自己写的方法去替换
这里就是进行嗅探

这是一个典型的 Monkey patch(猴子补丁)
主要有以下几个用处

  • 在运行时替换方法 属性等
  • 在不修改第三方代码的情况下增加原来不支持的功能
  • 在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加

更严谨的做法

由于需要调用bind方法的一定是一个函数 , 所以有必要在bind的内部做一个校验

1
2
3
if(typeof this !== "function") {
throw new TypeError("what is trying to be bound is not callable");
}
  • JavaScript
  • prototype
  • JavaScript

扫一扫,分享到微信

Maven(3)-从入门到重新入门
变量的定义提升 
© 2024 夏夜梦星辰
鲁ICP备19028444号
Power By Hexo
  • 所有文章
  • 友情链接
  • 关于我
{{searchItem.query}}
标签: 分类:
  • maven
  • 持续集成
  • JMS
  • 线程
  • JavaScript
  • ECMAScript6
  • 单元测试
  • Promise
  • Web Worker
  • 函数
  • prototype
  • 模块化
  • 正则表达式
  • 数据库
  • MongoDB
  • 索引
  • 集群
  • 全文检索
  • flutter
  • dart
  • git
  • 版本控制
  • linux
  • shell
  • docker
  • nginx
  • jenkins
  • opencv
  • vim
  • react
  • react native
  • 前端
  • css
  • HTML5
  • Hexo
  • sass
  • Three.js
  • TypeScript
  • Vue
  • 组件化
  • base64
  • webpack
  • nodejs
  • gulp
  • TensorFlow
  • 机器学习
  • 算法
  • 动态规划
  • 数据结构
  • Java
  • JavaScript
  • MongoDB
  • flutter
  • Git
  • linux
  • react
  • 前端杂烩
  • 男生女生
  • 算法
  • 十年饮冰,难凉热血
  • †少女癌†
  • 猫与向日葵
  • coderfun
  • JENKINS
  • API管理后台
愿你最终能接纳每一面每一种的自己
独自活着便是团圆