如何禁止JavaScript对象重写

这篇文章主要介绍了关于如何禁止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等, 或者你的开发团队非常大,本文介绍的这些方法将非常有用。

立即学习“Java免费学习笔记(深入)”;

不要重写他人的对象

不要重写他人的对象,这是JavaScript的黄金法则。比如,当你重写了一个方法,则很可能这会影响依赖于该方法的库,这会让其他开发者非常困惑。

// 示例代码1window.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(),这会导致非常严重的后果。

如果你只是为对象添加新的方法,这也会导致问题。

// 示例代码2Math.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()可以查看某个对象是否可以增加方法或者属性。

// 示例代码3var 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);  // undefinedsong.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 extensibledelete song.artist; // Uncaught TypeError: Cannot delete property 'artist' of #

登录后复制

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 # song.getLongTitle = function() // Uncaught TypeError: Cannot assign to read only property 'getLongTitle' of object '#'{    return "foobar";};

登录后复制

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

IE 9+

Firefox 4+

Safari 5.1+

Chrome 7+

Opera 12+

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

相关推荐:

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

JavaScript创建对象的四种方式

以上就是如何禁止JavaScript对象重写的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2746848.html

(0)
上一篇 2025年3月8日 04:13:47
下一篇 2025年3月8日 04:13:55

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • ES6 Class 继承与 super的介绍

    这篇文章主要介绍了关于es6 class 继承与 super的介绍,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 Class 继承与 super class 可以 extends 自另一个 class。这是一个不错的语法,技…

    2025年3月8日 编程技术
    200
  • jQuery-Ajax请求Json数据并加载在前端页面

    这篇文章主要介绍了关于jquery-ajax请求json数据并加载在前端页面,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 Ajax技术应用广泛,这种异步加载技术,无需刷新网页即可更新网站内容,全局或者局部均可,所以大家应该…

    编程技术 2025年3月8日
    200
  • js 异步for循环的介绍

    这篇文章主要介绍了关于js 异步for循环的介绍,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 假设一名厨师,需要做3道菜,声明一个菜数组,菜对象是菜名和做菜需要的时间 let dishes=[{name:”fish”,ti…

    编程技术 2025年3月8日
    200
  • jQuery源码之Callbacks的学习

    这篇文章主要介绍了关于jquery源码之callbacks的学习,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 jQuery源码学习之Callbacks jQuery的ajax、deferred通过回调实现异步,其实现核心是…

    编程技术 2025年3月8日
    200
  • 关于react项目静态类型检查方案

    这篇文章主要介绍了关于react项目静态类型检查方案,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 为什么需要引入类型检查 JS作为一个弱类型语言,具有很大的灵活性,但是它的优点也是它的缺点,它很容易让我们忽视一些隐晦的逻辑…

    2025年3月8日
    200
  • ES6 Promise中then与catch的返回值的实例

    这篇文章主要介绍了关于es6 promise中then与catch的返回值的实例,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 一.catch为then的语法糖 故then方法与catch方法均会返回一个Promise对象(…

    2025年3月8日 编程技术
    200
  • Vue脚手架的简单使用

    这篇文章主要介绍了关于vue脚手架的简单使用,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 提前申明 注意:自己对vue脚手架的理解和认识,很多东西和理解都是形象上的手法,并不专业和官方 webpack 一种项目构建工具,可…

    2025年3月8日
    200
  • Vue iview-admin框架二级菜单改为三级菜单的方法

    这篇文章主要介绍了关于vue iview-admin框架二级菜单改为三级菜单的方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 最近在用 iview-admin的Vue后台模板,从git上下载后发现左侧导航栏最多支持到二级…

    2025年3月8日 编程技术
    200
  • 通过Vue属性$route的params传参

    这篇文章主要介绍了关于通过vue属性$route的params传参,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 vue传值 与 vue传参是两块东西 概念图 原理 vue传参的原理主要在于 Vue.$route.param…

    2025年3月8日
    200
  • vscode搭建Typescript+React+Dva的开发环境

    这篇文章主要介绍了关于vscode搭建typescript+react+dva的开发环境,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 [ 作为2018年前端最应该学的技术 ], Typescript 确实惹火, 这两天崩崩…

    2025年3月8日 编程技术
    200

发表回复

登录后才能评论