扩展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 相关文章推荐
JavaScript this 深入理解
Jul 30 Javascript
jQuery中dequeue()方法用法实例
Dec 29 Javascript
js调用百度地图及调用百度地图的搜索功能
Sep 07 Javascript
基于javascript代码实现通过点击图片显示原图片
Nov 29 Javascript
JS中JSON对象和String之间的互转及处理技巧
Apr 06 Javascript
第九篇Bootstrap导航菜单创建步骤详解
Jun 21 Javascript
详解vue2路由vue-router配置(懒加载)
Apr 08 Javascript
Vue+Vux项目实践完整代码
Nov 30 Javascript
微信小程序显示倒计时功能示例【测试可用】
Dec 03 Javascript
JS实现百度搜索框关键字推荐
Feb 17 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
Apr 09 Javascript
动态规划之使用备忘录来改进Javascript函数
Apr 07 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
Linux下PHP加速器APC的安装与配置笔记
2014/10/24 PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
2016/03/01 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
2010年最佳jQuery插件整理
2010/12/06 Javascript
javascript标签在页面中的位置探讨
2013/04/11 Javascript
JavaScript动态插入script的基本思路及实现函数
2013/11/11 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
jQuery对于显示和隐藏等常用状态的判断方法
2014/12/13 Javascript
Javascript的表单验证-初识正则表达式
2016/03/18 Javascript
js时间控件只显示年月
2017/01/08 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
微信小程序实现的动态设置导航栏标题功能示例
2019/01/31 Javascript
vue与django集成打包的实现方法
2019/11/11 Javascript
JavaScript基于用户照片姓名生成海报
2020/05/29 Javascript
python通过smpt发送邮件的方法
2015/04/30 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
2016/05/17 Python
Python学习之用pygal画世界地图实例
2017/12/07 Python
python 实现在txt指定行追加文本的方法
2018/04/29 Python
python检索特定内容的文本文件实例
2018/06/05 Python
python3实现SMTP发送邮件详细教程
2018/06/19 Python
python爬虫 爬取58同城上所有城市的租房信息详解
2019/07/30 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
2020/07/14 Python
python线程里哪种模块比较适合
2020/08/02 Python
浅析python 字典嵌套
2020/09/29 Python
python批量生成身份证号到Excel的两种方法实例
2021/01/14 Python
python快速安装OpenCV的步骤记录
2021/02/22 Python
德国富尔达运动鞋店:43einhalb
2020/12/25 全球购物
社区七一党员活动方案
2014/01/25 职场文书
2014法院四风问题对照检查材料思想汇报
2014/10/04 职场文书
运动会三级跳加油稿
2015/07/21 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
python解析照片拍摄时间进行图片整理
2022/07/23 Python