This article mainly introduces how to prohibit JavaScript object rewriting, which has certain reference value. Now I share it with everyone. Friends in need can refer to it
Translator’s note: Use Object.preventExtensions(), Object.seal() and Object.freeze() to prohibit rewriting JavaScript objects.
Translator: Fundebug
Original text: Preventing modification of JavaScript objects
Due to the Flexibility, we can easily override some objects defined by others. In other words, anyone can override the objects we define. This is a very powerful feature that many developers are interested in trying to extend or modify the behavior of certain objects. For example, the DOM method document.getElementById() can be overridden. Generally speaking, we should avoid doing this because it will make the code difficult to maintain and leave some bugs that are difficult to find. ECMAScript 5 introduces methods that allow developers to restrict object rewriting. If you are developing some tool libraries such as jQuery, fundebug, etc., or your development team is very large, the methods introduced in this article will be very useful.
Don’t override other people’s objects. This is the golden rule of JavaScript. For example, when you override a method, it's likely that this will affect libraries that depend on that method, which can be very confusing to other developers.
// 示例代码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); // 参数为其他类型时,弹出对话框
In Sample Code 1, I modified windows.alert: when the parameter is a string, it is printed to the console; when the parameter is other types, a dialog box pops up. Such modifications will obviously affect other developers using the alert method. If you modify a DOM object such as getElementById(), this will lead to very serious consequences.
This can also cause problems if you just add new methods to the object.
// 示例代码2 Math.cube = function(n) { return Math.pow(n, 3); }; console.log(Math.cube(2)); // 8
The biggest problem with this is that it may cause naming conflicts in the future. Although the Math object currently does not have a cube method, the next version of the JavaScript standard may add a cube method (of course it is unlikely), which means that we will replace the native cube method. In a real case, the Prototype library defined the document.getElementsByClassName() method, which was later added to the JavaScript standard.
Unfortunately, we cannot prevent other developers from rewriting the objects we define. Then we need the methods introduced in this article:
First, we might as well compare through a table Object.preventExtensions(), Object.seal() and Object.freeze():
Method | Prohibited from adding attributes | Prohibited Delete attributes | Prohibit modification of attributes |
---|---|---|---|
Object.preventExtensions() | Yes | No | No |
Object.seal() | Yes | Yes | No |
Object.freeze() | is | is | is |
使用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.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.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中文网!
相关推荐:
The above is the detailed content of How to disable JavaScript object rewriting. For more information, please follow other related articles on the PHP Chinese website!