扩展JavaScript功能的正确方法(译文)


Posted in Javascript onApril 12, 2012

早上看到《JavaScript 每周导读》【第三期】一文,里面发现一篇文章(Extending JavaScript ? The Right Way),觉得还不错,翻译过来跟大家共享,本文并不是逐字逐句进行翻译,尽量说得通俗易懂。

原文地址:Extending JavaScript ? The Right Way

以下是译文

JavaScript已经内置了很多强大的方法,但有时你需要的某个功能在内置的方法中没有,我们怎么来优雅地扩展JavaScript功能呢。

例如我们想增加一个capitalize()方法来实现首字母大写,通常我们这样写:

if(!String.prototype.capitalize) 
{ 
String.prototype.capitalize = function() 
{ 
return this.slice(0,1).toUpperCase() + this.slice(1).toLowerCase(); 
} 
}

上面的代码可以正常使用,但如果在某个地方有下面的代码:

var strings = "yay"; 
for(i in strings) console.log(i + ":" + strings[i]);

我们得到的结果是这样的:
0: y
1: a
2: y
capitalize: function () { return this.slice(0, 1).toUpperCase() + this.slice(1).toLowerCase(); }

这显然不是我们想要的结果,输出了我们增加的方法的原因是我们增加的方法的enumerable属性默认为true。

我们可以通过简单地把枚举属性(enumerable)设置为false避免这个问题,使用defineProperty方法进行功能的扩展:

if(!String.prototype.capitalize) 
{ 
Object.defineProperty(String.prototype, 'capitalize', 
{ 
value: function() 
{ 
return this.slice(0,1).toUpperCase() + this.slice(1).toLowerCase(); 
}, 
enumerable: false 
}); 
}

现在我们再运行这段代码:

var strings = "yay"; 
for(i in strings) console.log(i + ":" + strings[i]);

我们得到的结果是:
0: y
1: a
2: y

要注意的是,用循环没有输出的并不代表不存在,我们可以通过下面的代码查看到定义:

var strings = "yay"; 
console.log(strings.capitalize)

会输出:

function () { return this.slice(0, 1).toUpperCase() + this.slice(1).toLowerCase(); }

用这种方式扩展JavaScript功能比较灵活,我们可以用这种方式来定义我们自己的对象,并设置一些默认值。

以下是另外几个扩展方法,你可以在自己的项目中使用:

String.pxToInt()

把"200px"这样的字符串转换为数字 200 :

if(!String.prototype.pxToInt) 
{ 
Object.defineProperty(String.prototype, 'pxToInt', 
{ 
value: function() 
{ 
return parseInt(this.split('px')[0]); 
}, 
enumerable: false 
}); 
}

String.isHex()

判断一个字符串是否是16进制表示的,如"#CCC" 或 "#CACACA"

if(!String.prototype.isHex) 
{ 
Object.defineProperty(String.prototype, 'isHex', 
{ 
value: function() 
{ 
return this.substring(0,1) == '#' && 
(this.length == 4 || this.length == 7) && 
/^[0-9a-fA-F]+$/.test(this.slice(1)); 
}, 
enumerable: false 
}); 
}

String.reverse()

字符串反转:

if(!String.prototype.reverse) 
{ 
Object.defineProperty(String.prototype, 'reverse', 
{ 
value: function() 
{ 
return this.split( '' ).reverse().join( '' ); 
}, 
enumerable: false 
}); 
}

String.wordCount()

统计单词数量,用空格分开

if(!String.prototype.wordCount) 
{ 
Object.defineProperty(String.prototype, 'wordCount', 
{ 
value: function() 
{ 
return this.split(' ').length; 
}, 
enumerable: false 
}); 
}

String.htmlEntities()

html标签如<和>编码为特殊字符

if(!String.prototype.htmlEntities) 
{ 
Object.defineProperty(String.prototype, 'htmlEntities', 
{ 
value: function() 
{ 
return String(this).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); 
}, 
enumerable: false 
}); 
}

String.stripTags()

去掉HTML标签:

if(!String.prototype.stripTags) 
{ 
Object.defineProperty(String.prototype, 'stripTags', 
{ 
value: function() 
{ 
return this.replace(/<\/?[^>]+>/gi, ''); 
}, 
enumerable: false 
}); 
}

String.trim()

去掉首尾空格:

if(!String.prototype.trim) 
{ 
Object.defineProperty(String.prototype, 'trim', 
{ 
value: function() 
{ 
return this.replace(/^\s*/, "").replace(/\s*$/, ""); 
}, 
enumerable: false 
}); 
}

String.stripNonAlpha()

去掉非字母字符:

if(!String.prototype.stripNonAlpha) 
{ 
Object.defineProperty(String.prototype, 'stripNonAlpha', 
{ 
value: function() 
{ 
return this.replace(/[^A-Za-z ]+/g, ""); 
}, 
enumerable: false 
}); 
}

Object.sizeof()

统计对象的大小,如{one: “and”, two: “and”}为2

if(!Object.prototype.sizeof) 
{ 
Object.defineProperty(Object.prototype, 'sizeof', 
{ 
value: function() 
{ 
var counter = 0; 
for(index in this) counter++; 
return counter; 
}, 
enumerable: false 
}); 
}

这种方式扩展JS原生对象的功能还是挺不错的,但除非必要(项目中用的很多),不建议直接在原生对象上扩展功能,会造成全局变量污染。

另外,文中的pxToInt()方法是没什么必要的,JS中的parseInt()可以直接完成这样的功能:parsetInt("200px")===200

htmlEntities方法貌似有问题,下面另提供一个:

if(!String.prototype.htmlEntities) 
{ 
Object.defineProperty(String.prototype, 'htmlEntities', 
{ 
value: function() 
{ 
var div = document.createElement("div"); 
if(div.textContent){ 
div.textContent=this; 
} 
else{ 
div.innerText=this; 
} 
return div.innerHTML; 
}, 
enumerable: false 
}); 
}
Javascript 相关文章推荐
jquery中插件实现自动添加用户的具体代码
Nov 15 Javascript
JS实现从表格中动态删除指定行的方法
Mar 31 Javascript
基于javascript实现图片切换效果
Apr 17 Javascript
Bootstrap滚动监听(Scrollspy)插件详解
Apr 26 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
Jan 13 Javascript
js实现简单的二级联动效果
Mar 09 Javascript
移动设备手势事件库Touch.js使用详解
Aug 18 Javascript
React+Webpack快速上手指南(小结)
Aug 15 Javascript
JavaScript之数组扁平化详解
Jun 03 Javascript
微信小程序wxml列表渲染原理解析
Nov 27 Javascript
使用Node.js实现base64和png文件相互转换的方法
Mar 11 Javascript
微信小程序实现单个或多个倒计时功能
Nov 01 Javascript
idTabs基于JQuery的根据URL参数选择Tab插件
Apr 11 #Javascript
JQuery学习笔录 简单的JQuery
Apr 09 #Javascript
广泛收集的jQuery拖放插件集合
Apr 09 #Javascript
深入分析js中的constructor和prototype
Apr 07 #Javascript
浅谈javascript中的作用域
Apr 07 #Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
Apr 07 #Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
Apr 07 #Javascript
You might like
php在程序中将网页生成word文档并提供下载的代码
2012/10/09 PHP
非常实用的php弹出错误警告函数扩展性强
2014/01/17 PHP
PHP 5.3新增魔术方法__invoke概述
2014/07/23 PHP
php发送邮件的问题详解
2015/06/22 PHP
php随机获取金山词霸每日一句的方法
2015/07/09 PHP
使用新的消息弹出框blackbirdjs
2008/10/16 Javascript
javascript StringBuilder类实现
2008/12/22 Javascript
不一样的文字闪烁 轮番闪烁
2009/11/11 Javascript
input输入框的自动匹配(原生代码)
2013/03/19 Javascript
jquery如何判断某元素是否具备指定的样式
2013/11/05 Javascript
可选择和输入的下拉列表框示例
2013/11/05 Javascript
JavaScript实现数组随机排序的方法
2015/06/26 Javascript
Node.js  REPL (交互式解释器)实例详解
2017/08/06 Javascript
Angular实现的table表格排序功能完整示例
2017/12/22 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
2018/09/07 jQuery
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
React实现轮播效果
2020/08/25 Javascript
[11:33]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第二场
2018/04/06 DOTA
Python中用于转换字母为小写的lower()方法使用简介
2015/05/19 Python
ubuntu环境下python虚拟环境的安装过程
2018/01/07 Python
解决Atom安装Hydrogen无法运行python3的问题
2019/08/28 Python
Python基于Twilio及腾讯云实现国际国内短信接口
2020/06/18 Python
Python+OpenCV图像处理——图像二值化的实现
2020/10/24 Python
CSS3 实现弹幕的示例代码
2017/08/07 HTML / CSS
CSS3制作3D立方体loading特效
2020/11/09 HTML / CSS
澳大利亚排名第一的在线酒类商店:MyBottleShop
2018/04/26 全球购物
雅诗兰黛加拿大官网:Estee Lauder加拿大
2019/07/31 全球购物
全球领先的全景影像品牌:Insta360
2019/08/21 全球购物
两则小学生的自我评价分享
2013/11/14 职场文书
矿泉水广告词
2014/03/20 职场文书
关于国庆节的演讲稿
2014/09/05 职场文书
2014年技术工作总结范文
2014/11/20 职场文书
2015年度员工自我评价范文
2015/03/11 职场文书
公诉意见书范文
2015/06/05 职场文书
一篇文章带你复习java知识点
2021/06/28 Java/Android
Spring事务管理下synchronized锁失效问题的解决方法
2022/03/31 Java/Android