首頁 > web前端 > js教程 > 主體

如何禁止JavaScript物件重寫

不言
發布: 2018-07-09 10:41:37
原創
1442 人瀏覽過

這篇文章主要介紹了關於如何禁止JavaScript物件重寫,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

譯者按: 使用Object.preventExtensions()、Object.seal()和Object.freeze(),可以禁止重寫JavaScript物件。

  • 譯者:Fundebug

  • #原文:Preventing modification of JavaScript objects

#由於JavaScript的靈活性,我們可以輕易地重寫(override)一些於其他人定義的物件(object)。換句話說,任何人都可以重寫我們所定義的物件。這是一個非常強大的特性,許多開發者都有興趣試試,來拓展或修改某些物件的行為。例如,DOM方法document.getElementById()都可以重寫。一般來講,我們應該避免這樣做,因為這會導致程式碼很難維護,並且會留下一些難於發現的BUG。 ECMAScript 5引入了一些方法,讓開發者可以限制物件重寫。如果你在開發一些工具庫例如jQuery, fundebug等, 或是你的開發團隊非常大,本文介紹的這些方法將會非常有用。

不要重寫他人的物件

不要重寫他人的對象,這是JavaScript的黃金法則。例如,當你重寫了一個方法,則很可能這會影響依賴該方法的函式庫,這會讓其他開發者非常困惑。

// 示例代码1
window.originalAlert = window.alert;  
window.alert = function(msg) {  
    if (typeof msg === "string") {
        return console.log(msg);
    }
    return window.originalAlert(msg);
};

alert('ooh so awesome'); // 参数为字符串时,打印到控制台 
alert(3.14); // 参数为其他类型时,弹出对话框
登入後複製

範例程式碼1中,我修改了windows.alert:參數為字串時,列印到控制台;參數為其他類型時,彈出對話框。這樣的修改顯然會影響其他使用alert方法的開發者。如果你修改的是DOM物件例如getElementById(),這會導致非常嚴重的後果。

如果你只是為物件添加新的方法,這也會導致問題。

// 示例代码2
Math.cube = function(n) {  
    return Math.pow(n, 3);
};
console.log(Math.cube(2)); // 8
登入後複製

這樣做最大的問題是有可能在未來導致命名衝突。雖然Math物件目前並沒有cube方法,下一個版本的JavaScript標準也許會增加cube方法(當然可能性不大),這就意味著我們會把原生cube方法給替代了。有一個真實的案例,Prototype函式庫定義了document.getElementsByClassName()方法,而這個方法後來被加入了JavaScript標準。

不幸的是,我們無法阻止其他開發者重寫我們定義的對象,這時我們就需要本文介紹的這些方法了:

#首先,我們不妨透過一個表格對比一下Object.preventExtensions()、Object.seal()和Object.freeze():

#禁止增加屬性 #刪除屬性 禁止修改屬性
Object.preventExtensions()
Object.seal()
##Object.freeze()
######

Object.preventExtensions()

使用Object.preventExtensions(),可以禁止给对象添加新的方法或者属性。注意,修改或者删除对象已经存在的方法或者属性是没有问题的。使用Object.isExtensible()可以查看某个对象是否可以增加方法或者属性。

// 示例代码3
var song = {  
    title: 'Hope Leaves',
    artist: 'Opeth'
};


console.log(Object.isExtensible(song)); //true  
Object.preventExtensions(song);  
console.log(Object.isExtensible(song)); //false  


song.album = 'Damnation';
console.log(song.album);  // undefined


song.play = function() {  
    console.log('ahh soo awesome');
};
song.play(); // TypeError: song.play is not a function
登入後複製

示例代码3可知,执行Object.preventExtensions()之后,为song对象新增album以及play方法都失败了!

但是,当我们为song新增属性或者方法时,并没有报错。当我们使用了"use strict"采用严格模式时,情况就不一样了:

// 示例代码4
"use strict";

var song = {  
    title: 'Hope Leaves',
    artist: 'Opeth'
};

Object.preventExtensions(song);  

song.album = 'Damnation'; // Uncaught TypeError: Cannot add property album, object is not extensible
登入後複製

在严格模式下,给已经Object.preventExtensions的对象新增属性时,会立即报错。广告:如果你希望实时监控应用中类似的错误,欢迎免费试用Fundebug

Object.seal()

使用Object.seal(),可以禁止给对象添加属性或者方法(这一点与Object.preventExtension()的作用一致),同时禁止删除对象已经存在的属性或者方法。

// 示例代码5
"use strict"
var song = {
    title: 'Hope Leaves',
    artist: 'Opeth'
};

Object.seal(song);
console.log(Object.isExtensible(song)); //false  
console.log(Object.isSealed(song)); //true  

song.album = 'Damnation'; // Uncaught TypeError: Cannot add property album, object is not extensible
delete song.artist; // Uncaught TypeError: Cannot delete property 'artist' of #<Object>
登入後複製

Object.freeze()

使用Object.freeze(),可以禁止为对象增加属性或者方法(这一点与Object.preventExtension()的作用一致),同时禁止删除对象已经存在的属性或者方法(这一点与Object.seal()的作用一致),另外还禁止修改已经存在的属性或者方法。

// 示例代码6
"use strict"
var song = {
    title: 'Hope Leaves',
    artist: 'Opeth',
    getLongTitle: function()
    {
        return this.artist + " - " + this.title;
    }
};

Object.freeze(song);

console.log(Object.isExtensible(song)); // false  
console.log(Object.isSealed(song)); // true  
console.log(Object.isFrozen(song)); // true  

song.album = 'Damnation'; // Uncaught TypeError: Cannot add property album, object is not extensible  
delete song.artist; // Uncaught TypeError: Cannot delete property 'artist' of #<Object> 
song.getLongTitle = function() // Uncaught TypeError: Cannot assign to read only property 'getLongTitle' of object '#<Object>'
{
    return "foobar";
};
登入後複製

主流浏览器的最新版本都支持这些方法:

  • IE 9+

  • Firefox 4+

  • Safari 5.1+

  • Chrome 7+

  • Opera 12+

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何解决JS高程中的垃圾回收机制与常见内存泄露的问题

JavaScript创建对象的四种方式

以上是如何禁止JavaScript物件重寫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!