41条对违反抽象原则行为的讨论之后,下面聊一聊终极违例。由于对象共享原型,因此每一个对象都可以增加、删除或修改原型的属性。这个有争议的实践通常称为猴子补丁。

猴子补丁示例

猴子补丁的吸引力在于其强大。数组缺少一个有用的方法吗?你自己就可以增加它。

Array.prototype.split=function(i){
return [this.slice(0,i),this.slice(i)];
}

很完美,现在可以在任意的数组上调用这个方法了。但当多个库以不兼容的方式给同一个原型打猴子补丁时,另外的库使用同一个方法名给Array.prototype打猴子补丁。

Array.prototype.split=function(){
var i=Math.floor(this.length);
return [this.slice(0,i),this.slice(i)];
}

问题

现在,任一对数组split方法的使用都大约有50%的机会被破坏,这取决于它们期望这两个方法哪一个被调用。
至少,任一修改其享原型的程序库都应当清晰地记录其修改。这至少能给使用者在关于不同库之间潜在的冲突提供足够的警告。但是,两个以冲突的方式给原型打猴子补丁的程序库不能在同一个程序中使用。

替代的方法

一种替代的方法是,如果库仅仅是将给原型打猴子补丁作为一种便利,那么可以将这些修改置于一个函数中,用户可以选择调用或忽略。

function addArrayMethods(){
Array.prototype.split=funciton(i){
return [this.slice(0,i),this.slice(i)]
}
}

这种方法只有在程序库提供了addArrayMethods函数时才能工作,而实际上并不依赖于Array.prototype.split函数。

ployfill

尽管猴子补丁很危险,但有一种告别可靠而且有价值的使用场景:ployfill。js程序和库经常部署在多个平台,这些平台实现了多少个标准API可能是有区别的。缺失的方法的行为是广泛支持的标准所定义的,而且许多程序和库可能依赖这些方法。由于它们的行为是标准化的,因此实现这些方法并不会造成与库之间不兼容性的类似的风险。事实上,多个库都可以给同一个标准方法提供实现(假设是被正确实现),因为它们都实现了相同的标准API。
你可以通过使用带有测试条件的守护猴子补丁来安全地弥补这些平台的差距。

if(typeof Array.prototype.map!=="function"){
Array.prototype.map=function(f,thisArg){
var res=[];
for(var i=0,n=this.length;i < n;i++){
res[i]=f.call(thisArg,this[i],i);
}
return res;
}
}

提示

  • 避免使用轻率的猴子补丁

  • 记录程序库所执行的所有猴子补丁

  • 考虑通过将修改置于一个导出函数中,使猴子补丁成为可选的

  • 使用猴子补丁为缺失的标准API提供polyfills

[Effective JavaScript 笔记]第42条:避免使用轻率的猴子补丁的更多相关文章

  1. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  2. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  3. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  4. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  5. [Effective JavaScript 笔记]第50条:迭代方法优于循环

    "懒"程序员才是好程序员.复制和粘贴样板代码,一但代码有错误,或代码功能修改,那么程序在修改的时候,程序员需要找到所有相同功能的代码一处处进行修改.这会使人重复发明轮子,而且在别人 ...

  6. [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑

    构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...

  7. [Effective JavaScript 笔记]第64条:对异步循环使用递归

    假设需要有这样一个函数,接收一个URL的数组并尝试依次下载每个文件直到有一个文件被成功下载.如果API是同步的,使用循环很简单实现. function downloadOneSync(urls){ f ...

  8. [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合

    对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...

  9. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

随机推荐

  1. Android调用系统相册和拍照的Demo

    最近我在群里看到有好几个人在交流说现在网上的一些Android调用系统相册和拍照的demo都有bug,有问题,没有一个完整的.确实是,我记得一个月前,我一同学也遇到了这样的问题,在低版本的系统中没问题 ...

  2. 第十一课:js操作选择器的通用函数

    1.判断文档是否是XML文档 var isXML = function(elem){ var documentElement = elem && (elem.ownerDocument ...

  3. JS面向对象概述

    这部分内容还是比较难理解的,像借用构造函数这种方法,实际工作中还是很常见的,不过对于后面的寄生理解还有点困难,只能慢慢学习了. 思维导图

  4. Moqui学习Day1

    运行时目录以及Moqui的xml配置文件 Moqui框架部署运行主要有三个核心部分: 可执行的war包文件 运行时目录 Moqui配置文件XML格式 不管怎么使用这个可执行的war文件,你必须拥有一个 ...

  5. CreateCompatibleDC与BitBlt 学习

    CreateCompatibleDC与BitBlt CreateCompatibleDC 创建一个与指定设备一致的内存设备描述表. HDC CreateCompatibleDC(HDC hdc //设 ...

  6. iOS不得姐项目--推荐关注模块(一个控制器控制两个tableView),数据重复请求的问题,分页数据的加载,上拉下拉刷新(MJRefresh)

    一.推荐关注模块(一个控制器控制两个tableView) -- 数据的显示 刚开始加载数据值得注意的有以下几点 导航控制器会自动调整scrollView的contentInset,最好是取消系统的设置 ...

  7. Yii2结合webuploader实现图片上传

    js中 uploader = WebUploader.create({ // 自动上传. auto : true, // swf文件路径 swf : 'webuploader/Uploader.swf ...

  8. Myeclipse报PermGen space异常的问题

    最好用的方法: 1)在myeclipse中windos——>preference——>Myeclipse——>servers——>Tomcat——>JDK(Optiona ...

  9. 配置hibernate

    http://blog.csdn.net/hanjiancanxue_liu/article/details/9966423

  10. Vijos1459 车展 (数学)

    描述 遥控车是在是太漂亮了,韵韵的好朋友都想来参观,所以游乐园决定举办m次车展.车库里共有n辆车,从左到右依次编号为1,2,…,n,每辆车都有一个展台.刚开始每个展台都有一个唯一的高度h[i].主管已 ...