[譯]擴充JavaScript功能的正確方法《JavaScript 每周導讀》【第三期】

來源:互聯網
上載者:User

  早上看到《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: y1: a2: ycapitalize: 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: y1: a2: 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    });}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.