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

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
桃源资源网 Design By www.nqtax.com

评论“扩展JavaScript功能的正确方法(译文)”

暂无“扩展JavaScript功能的正确方法(译文)”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。