之前的几条都不断地重复着for...in循环,它便利好用,但又容易被原型污染。for...in循环最常见的用法是枚举字典中的元素。这里就是从侧面提出不要在共享的Object.prototype中增加可枚举的属性。
这就导致,我们在开发的时候,不能在Object.prototype中添加有用的方法。如,我们想增加一个产生对象属性名数组的allKeys方法将会怎么样?

Object.prototype.allKeys=function(){
var res=[];
for(var key in this){
res.push(key);
}
return res;
}

上面的方法污染了它自身。

({a:1,b:2,c:3}).allKeys();//['allKeys','a','b','c']

可以用之前说的方法改进allKeys方法忽略掉Object.prototype中的属性。

独立为函数

把要添加的方法独立为一个函数。

function allKeys(obj){
var res=[];
for(var key in this){
res.push(key);
}
return res;
}

这样就可以使用,而又可以不污染到原型。for...in循环也不会出错。

设置为不可枚举

如果想在Object.prototype中增加属性,ES5提供了Object.defineProperty方法,可以定义一个对象的属性并指定该属性的元数据。通过设置其可枚举性为false使其在for...in循环中不可见。

Object.defineProperty(Object.prototype,'allKeys',{
value:function(){
var res=[];
for(var key in this){
res.push(key);
}
return res;
},
writable:true,
enumerable:false,
configurable:true
});

调用一下可得

({a:1,b:2,c:3}).allKeys();//['a','b','c']

上面的代码不会污染其他所有Object实例的所有for...in循环。事实上,当你需要增加一个不应该在for...in循环中出现的属性时,Object.defineProperty方法可以用来定义属性。

提示

  • 避免在Object.prototype中增加属性

  • 考虑编写一个函数代替Object.prototype方法

  • 如果你确定需要在Object.prototype中增加属性,使用ES5中的Object.defineProperty方法将它们定义为不可枚举的属性

[Effective JavaScript 笔记]第47条:绝不要在Object.prototype中增加可枚举的属性的更多相关文章

  1. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数

    示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...

  2. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  3. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  4. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  5. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  6. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

  7. [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合

    对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...

  8. [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作

    第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...

  9. [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法

    不好的实践 函数或方法的接收者(即绑定到特殊关键字this的值)是由调用者的语法决定的.方法调用语法将方法被查找的对象绑定到this变量,(可参阅之前文章<理解函数调用.方法调用及构造函数调用之 ...

随机推荐

  1. Ubuntu 上创建常用磁盘阵列

    RAID(Redundant Array of Independent Disk 独立冗余磁盘阵列)技术是加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的昂贵磁盘,同时希望磁盘失 ...

  2. Object C学习笔记19-枚举

    一. 枚举类型 枚举类型是一个基本类型,不能再分为为任何其他的类型.在一般的编程语言中都有枚举(enum)这种数据结构类型.枚举类型主要用于将一个变量限定在特定的范围内.比如一周有七天,那么一周的值就 ...

  3. SSRS开发的经验记录

    虽然工作经验相当的长,但是之前在SSRS上还没有象今天这样的经验.这只是工作经验的一点记录. 1. 定义DataSet 定义DataSet的时后,可以采用Text的方式.用Text的方式可以用一段比较 ...

  4. 深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法

    当我们用javascript写ajax程序写得很“开心”的时候,突然有人告诉你有一种东西叫jquery,它会告诉你不直接和HttpRequest是多么的快乐,同时你再也不需要再烦恼纠结的ajax乱码问 ...

  5. [工具]推荐一款查看dll依赖工具

    引言 很久没写一篇像样的博客了,最近一个月一直忙于项目,也没时间去总结了,回到家,也就是看看书,没怎么总结.不过还是挺兴奋的,每天过得还算充实.这里也算是对五月份的一个总结吧. 为什么要查看dll 因 ...

  6. linq入门系列导航

    写在前面 为什么突然想起来学学linq呢?还是源于在跟一个同事聊天的时候,说到他们正在弄得一个项目,在里面用到了linq to sql.突然想到距上次使用linq to sql是三年前的事情了.下班回 ...

  7. Javascript基础系列之(五)关键字和保留字 (keyword)

    关键字不可以作为变量名或者函数名 break case catch continue default delete do else finally for function if in instanc ...

  8. Linux下安装项目管理工具Redmine

    http://www.redmine.org.cn/download Linux下安装项目管理工具Redmine1.Ruby安装Ruby on Rails网站推荐使用1.8.7版. 点击(此处)折叠或 ...

  9. 基于Bootstrap的jQuery开关按钮插件

        按钮 下载 使用方法 首先要在页面中引入依赖文件: jquery.Bootstrap.Bootstrap Switch CSS和Bootstrap Switch JS.这里用的是bootstr ...

  10. yii2URL美化

    yii2的url 域名/index.php?r=site%2Findex 实际为 域名/index.php?r=site/index 可以美化下 可以在main.php中配置 'components' ...