当前位置: 首页 > news >正文

模拟实现兼容低版本IE浏览器的原生bind()函数功能

模拟实现兼容低版本IE浏览器的原生bind()函数功能:
代码如下:
if (!Function.prototype.bind){
   Function.prototype.bind= function (oThis){
     if ( typeof this !== 'function' ){
       throw new TypeError( '调用者不是当前函数对象' );
     }
  
     var aArgs = Array.prototype.slice.call(arguments, 1),
         fToBind = this ,
         fNOP = function () {},
         fBound = function () {
           return fToBind.apply( this instanceof fNOP && oThis ? this : oThis||window,          
           aArgs.concat(Array.prototype.slice.call(arguments)));
         };
  
         fNOP.prototype = this .prototype;
         fBound.prototype = new fNOP();
  
     return fBound;
   };
}
上面的代码实现了兼容效果,下面介绍一下它的实现过程。
一.代码注释:
1.if(!Function.prototype.bind),判断当前浏览器是否支持bind()函数。
2.Function.prototype.bind=function(oThis){},如果不支持的话,就添加一个bind函数,参数自然是this要指向的对象。
3.if (typeof this !== 'function'){
  throw new TypeError('调用者不是当前函数对象');
},因为使用call或者apply等方式的存在,可以将调用者转换成其他对象,比如func.bind.call(obj),就是为了防止此情况的出现。
4.var aArgs = Array.prototype.slice.call(arguments, 1),获取为bind函数传递的从第二个开始以后的参数。
5.fToBind = this,将当前函数对象的this引用赋值给变量fToBind 。
6.fNOP = function() {},使用表达式方式创建一个函数,它的用法在后面介绍。
7.fBound = function() {  
  return fToBind.apply(this instanceof fNOP && oThis ? this : oThis||window , 
  aArgs.concat(Array.prototype.slice.call(arguments)));
},fBound函数就是要返回的函数。return fToBind.apply()前面加上return是因为fToBind函数可能会有返回值。
this instanceof fNOP && oThis ? this : oThis||window,this instanceof fNOP可以判断是否用作构造函数,至于&&与运算符后面的oThis 是否需要值得商榷,如果按照MDN的源码的话,当用作构造函数不传递oThis参数的时候,那么会用window对象调用fToBind函数,如果此位置 没有oThis,那么无论是否bind()函数传递oThis参数,函数fBound用作构造函数的时候,都能够使用this调用fToBind()函 数。
aArgs.concat(Array.prototype.slice.call(arguments)),两个数组进行连接,最终结果就是要传递给fToBind()函数的参数。
8.fNOP.prototype = this.prototype,此句感觉完全没有必要,可能是为了增加原型链的密度。
9.fBound.prototype = new fNOP(),将fBound的原型对象设置为fNOP()的实例对象,这样的话如果fBound 用作构造函数的话,this instanceof fNOP返回值为true。
10.return fBound,返回此函数。

转载于:https://www.cnblogs.com/momox/p/5090689.html

相关文章:

  • oracle中exp,imp(导入,导出)的使用详解
  • 【原创】erlang 模块之 rpc
  • Extreme交换机基本配置-账号软件升级密码配置
  • 使用mysqldump导入导出含BOLB数据的表
  • root logger默认的level是logging.WARNING
  • Prime Path
  • vim配色方案colorscheme设置
  • JAVA图形界面(GUI)之菜单
  • the difference among ios deivces
  • 随笔 2016-1-4
  • VC中的数据类型转换BSTR、char*和CString
  • contentprovider的学习实例总结
  • 终于找到IE10 Browser Mode为IE10 compat View的真相
  • 如何提高perl处理大文件的效率
  • CxImage的几种应用举例
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 08.Android之View事件问题
  • android图片蒙层
  • angular2 简述
  • Angular数据绑定机制
  • CentOS7 安装JDK
  • co.js - 让异步代码同步化
  • Cumulo 的 ClojureScript 模块已经成型
  • GitUp, 你不可错过的秀外慧中的git工具
  • leetcode386. Lexicographical Numbers
  • Objective-C 中关联引用的概念
  • PHP CLI应用的调试原理
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • windows下mongoDB的环境配置
  • 分布式事物理论与实践
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 开源SQL-on-Hadoop系统一览
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 如何选择开源的机器学习框架?
  • 我是如何设计 Upload 上传组件的
  • 小而合理的前端理论:rscss和rsjs
  • 用 Swift 编写面向协议的视图
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • Python 之网络式编程
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • (06)金属布线——为半导体注入生命的连接
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (二)JAVA使用POI操作excel
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (原創) 物件導向與老子思想 (OO)
  • .“空心村”成因分析及解决对策122344
  • .NET Core 成都线下面基会拉开序幕