关于原生js中bind函数的实现

今天继续研究了bind函数的实现,也知道了shim和polyfill的说法,现在总结一下,

 1 if (!Function.prototype.bind) {
 2   Function.prototype.bind = function (oThis) {
 3     if (typeof this !== "function") {
 4       // closest thing possible to the ECMAScript 5 internal IsCallable function
 5       throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
 6     }
 7
 8     var aArgs = Array.prototype.slice.call(arguments, 1),
 9         fToBind = this,
10         fNOP = function () {},
11         fBound = function () {
12           return fToBind.apply(this instanceof fNOP && oThis
13                                  ? this
14                                  : oThis || window,
15                                aArgs.concat(Array.prototype.slice.call(arguments)));
16         };
17
18     fNOP.prototype = this.prototype;
19     fBound.prototype = new fNOP();
20
21     return fBound;
22   };
23 }

这是官方文档上的实现,我分二个方面来谈我要说的东西,

第一个是参数,agruments的使用

 var aArgs = Array.prototype.slice.call(arguments, 1),

这里是将bind函数的参数数组取出来,第一个参数不要(就是不要oThis)也就是要被绑定方法的那个对象,第二个是

aArgs.concat(Array.prototype.slice.call(arguments)));

这里是用了数组的方法,把参数插在参数数组后面,要注意,这个函数是要被return 出去然后执行的,他的参数数组是return出去的那个fBound函数的参数数组,所以上下两个参数数组是不一样的,有点像柯里化。

第二个是上下文,在其中上下文的变化比较难理解,bind函数主要就是为了绑定上下文来使用的

 fToBind = this

这里是保存了对象的上下文,紧接着下面的apply方法让要被绑定的那个对象可以使用该上下文

 fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

这里是以fNOP为中介把this.prototype这个原对象的属性给fBound,确保fBound是在定义的时候的那个上下文里面执行。本来

bound.prototype = self.prototype

就可以将原属性集成过来了,但是这样两个对象属性都指向同一个地方,修改 bound.prototype 将会造成self.prototype 也发生改变,这样并不是我们的本意。所以通过一个空函数 nop 做中转,能有效的防止这种情况的发生。

时间: 2024-08-03 16:48:24

关于原生js中bind函数的实现的相关文章

原生JS实现bind()函数

一.bind()函数的两个特性: 1.bind和curring,函数科里化 function add(a, b, c) { var i = a+b+c; console.log(i); return i; } var func = add.bind(undefined, 100);//给add()传了第一个参数a func(1, 2);//103,继续传入b和c var func2 = func.bind(undefined, 200);//给func2传入第一个参数,也就是b,此前func已有

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

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

原生 JS 中对象相关 API 合集

https://juejin.im/entry/58f8a705a0bb9f0065a4cb20 原文链接:https://microzz.com/2017/04/20/jsobject/ 原生 JavaScript 中对象相关 API 合集 - 对象篇.现在 jQuery 已经没有那么有优势了,原生 JS 赶紧学起来... -- 由microzz分享 Microzz [email protected] 主页 文章 标签 GitHub 关于我 掘金专栏 SegmentFault Vue音乐播放器

原生JS封装_new函数,实现new关键字的功能

一.前言 众所周知:没有对象怎么办?那就new一个! 那么在JS中,当我们new一个对象的时候,这个new关键字内部都干了什么呢?现在我们就来剖析一下原生JS中new关键字内部的工作原理. 二.原始的new 首先,我们先new一个对象看看: 1 //创建Person构造函数,参数为name,age 2 function Person(name,age){ 3 this.name = name; 4 this.age = age; 5 } 6 //实例化对象小明 7 xm = new Person

js中一些函数(一)【丫头, 今天去哪儿了呢,好些没有】

Math.Rondom()   ==>  0 到 1 之间的小数 Math.floor(x)  ==>  小于或者等于 x 的整数(即转换成整数后是不能比 x 大的整数) setInterval(hanshu,1000)  ==>  意思为调用下面的 hanshu(), 间隔时间为 1000 ms(毫秒) js中一些函数(一)[丫头, 今天去哪儿了呢,好些没有],码迷,mamicode.com

让js中的函数只有一次有效调用的三种常用方法

如何让js中的函数只被有效执行一次,请看下面的三种常用方法. 1. <script> window.onload = function () { function once(fn) { var result; return function() { if(fn) { result = fn.apply(this, arguments); fn = null; } return result; }; } var callOnce = once(function() { console.log('

JS中的函数、Bom、DOM及JS事件

本期博主给大家带来JS的函数.Bom.DOM操作,以及JS各种常用的数据类型的相关知识,同时,这也是JavaScript极其重要的部分,博主将详细介绍各种属性的用法和方法. 一.JS中的函数 [函数的声明及调用] 1.函数声明的格式: function 函数名(参数1,参数2,参数3,--){//函数体 return 结果; } >>>函数的调用格式: 直接调用:函数调用的格式:函数名(参数一的值,参数二的值,--): 事件调用:事件名=函数名( ); 2.函数声明的几点强调: ①函数名

js中声明函数的区别

在JS中有两种定义函数的方式, 1是var aaa=function(){...} 2是function aaa(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. function方式定义函数可以先调用,后声明.请看代码: var声明时,只有变量声明提前了,变量的初始化代码仍在原位置.然而,使用函数声明的话,函数名称和函数体都会提前.两种声明得到的函数都不可删除 //aaa();这样调用就会出错                var aaa = funct

js中没有函数重载,怎样实现函数重载的功能?

js中没有函数重载,javasript中使用可选参数:arguments实现相同的功能.. 函数在定义的时候可不定义参数: <script type="text/javascript" > function say() { for (var i = 0; i < arguments.length; i++) { alert(arguments[i].toString()); } } </script> 调用:<input type="but