[译]扩展JavaScript功能的正确方法

简介:

  早上看到《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
    });
}

PS

  这种方式扩展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
    });
}



本文转自Artwl博客园博客,原文链接:http://www.cnblogs.com/artwl/,如需转载请自行联系原作者

相关文章
|
1月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
1月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
127 52
|
4天前
|
JavaScript 容器
带方向感知功能的js图片遮罩层插件
带方向感知功能的js图片遮罩层插件
|
22天前
|
机器学习/深度学习 JavaScript Cloud Native
Node.js作为一种快速、可扩展的服务器端运行时环境
Node.js作为一种快速、可扩展的服务器端运行时环境
34 8
|
28天前
|
JavaScript 前端开发 容器
jQuery多功能滑块插件r-slider.js
r-slider.js是一款jQuery多功能滑块插件。使用该插件,可以制作出滑块、开关按钮、进度条、向导步骤等多种效果。
33 5
|
4天前
|
前端开发 JavaScript 应用服务中间件
Nginx 支持 JavaScript:前所未有的扩展
Nginx 是全球领先的高性能 Web 服务器,以其高效的反向代理和负载均衡功能著称。近期,Nginx 正式支持 JavaScript(通过 NJS 模块),基于 V8 引擎,允许在配置中嵌入 JS 代码,极大提升了灵活性和扩展性。开发者可以使用 JavaScript 实现动态请求处理、自定义认证、复杂响应处理、中间件编写及流量控制等功能,显著降低开发和维护难度,同时保持高性能。NJS 模块的引入为 Nginx 带来了前所未有的扩展能力,适应快速变化的业务需求。
15 0
|
1月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
45 5
|
29天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
37 2
|
1月前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
27 1
|
1月前
|
JavaScript 前端开发
.js方法参数argument
【10月更文挑战第26天】`arguments` 对象为JavaScript函数提供了一种灵活处理参数的方式,能够满足各种不同的参数传递和处理需求,在实际开发中具有广泛的应用价值。
44 7