for in 语句用来列举对象的属性(成员),如下

1
2
3
4
5
6
7
var obj = { name:"jack",
      getName:function(){return this.name}
};
//输出name,getName   
for(var atr in obj) {
    alert(atr);
}

注意了吗,没有输出obj的toString,valueOf等内置属性(或称内置成员,隐藏属性和预定义属性)。即for in用来列举对象的显示成员(自定义成员)。

如果重写了内置属性呢,下面就重写obj的toString

1
2
3
4
5
6
7
var obj = {name:"jack",
      getName:function(){return this.name},
      toString:function(){return "I'm jack."}
}
for(var atr in obj) {
    alert(atr);
}

会输出什么呢?
1、IE6/7/8 下和没有重写toString一样,仍然只输出name,getName
2、IE9/Firefox/Chrome/Opera/Safari下则输出name,getName,toString

如果给内置原型添加属性/方法,那么for in时也是可遍历的

1
2
3
4
5
6
7
8
9
Object.prototype.clone = function() {}
var obj = {
    name: 'jack',
    age: 33
}
// name, age, clone
for (var in obj) {
    alert(n)
}

给Object.prototype添加了方法clone,for in时所有浏览器都显示了clone。

这或许还没什么,因为一般不建议去扩展内置构造器的原型,这也是Prototype.js走向没落的原因之一。jQuery和Underscore没有扩展自原型,前者在jQuery对象上做文章,后者索性将所有方法都挂在下划线上。

但有时我们为了兼容ES5或后续版本,会在不支持ES5的浏览器上(IE6/7/8)去扩展内置构造器的原型,这时for in在各浏览器中就不同了。如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (!Function.prototype.bind) {
    Function.prototype.bind = function(scope) {
        var fn = this
        return function () {
            fn.apply(scope, arguments)
        }
    }
}
function greet(name) { 
    alert(this.greet + ', ' + name)
}
for (var in greet) {
    alert(n)
}

IE6/7/8输出了bind,其它浏览器则无。因为现代浏览器中bind是原生支持的,for in不到,IE6/7/8则是给Function.prototype添加了bind。

总结下:在跨浏览器的设计中,我们不能依赖于for in来获取对象的成员名称,一般使用hasOwnProperty来判断下。

JavaScript for in的缺陷的更多相关文章

  1. JavaScript的坑,缺陷

    JavaScript的缺陷 1.在做判断的时候用=======而不是== 2.浮点预算有精度问题 通过差值去把这个精度锁定到一个范围 Math. Abs(A-B)<0.0001** 3.null ...

  2. React Native:使用 JavaScript 构建原生应用

    [转载] 本篇为联合翻译,译者:寸志,范洪春,kmokidd,姜天意 数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生 ...

  3. 深入浅出 React Native:使用 JavaScript 构建原生应用

    深入浅出 React Native:使用 JavaScript 构建原生应用 链接:https://zhuanlan.zhihu.com/p/19996445 原文:Introducing React ...

  4. 关于Javascript的内存泄漏问题的整理稿

    写了好长时间javascript小功能模块,从来没有关注过内存泄漏问题.记得以前写C++程序的时候,内存泄漏是个严重的问题,我想是时候关注一下了.网上找了篇文章,Mark一下.原文地址:http:// ...

  5. React Native:使用 JavaScript 构建原生应用 详细剖析

    数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生的 iOS 应用——就在今天,Beta 版的仓库释出了! 基于 Pho ...

  6. JavaScript 归纳

    MDN 本文以 NodeJS 为交互解释器实验 尽量遵循 ES6 标准 javascript 重点 1.javascript 是单线程,通过 EventLoop 实现模拟异步,其中包括宏任务,微任务 ...

  7. 从零开始学 Web 之 JavaScript(一)JavaScript概述

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  8. 知识点【JavaScript模块化】

    JavaScript模块化历程 JavaScript发展变迁大概是一下几个步骤: 工具(浏览器兼容) 组件(功能模块) 框架(功能模块组织) 应用(业务模块组织) 但是经过了长长的后天努力过程Java ...

  9. Javascript 创建对象的三种方法及比较【转载+整理】

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain 本文内容 引 ...

随机推荐

  1. Sphinx学习笔记2

    因为网站搜索的需要,启动了一个搜索引擎项目,其实也算不上完整的搜索引擎,需求很简单,如下:     1)搜索产品名.类别名.品牌名.副标题.关键字等字段     2)数据量目前为13000左右,未来可 ...

  2. PXE搭建

    前提最好是防火墙规则-F,关闭,selinux 是disable 这个在以后更新linux系统的时候还可以在这个基础上再次增加可以一体化安装的系统. 1.用yum来安装所需要的软件包,先来搭建yum光 ...

  3. ROS初探:(一)ROS架构

    一.ROS架构 ROS架构上分为三个层级: 计算图级(Computation Graph level):体现进程与系统的关系,描述系统怎么运行. 文件系统级(Filesystem level):组织构 ...

  4. iis部署php项目

    今天跟着学习了如何在IIS下部署php项目,操作很简单,记录一下步骤! 1.启动iis服务器 最后点击确定就完成了 2.打开iis 点击进入即可 3.创建网站 进入添加网站. 添加注意事项如图所示! ...

  5. Prism for WPF再探(基于Prism事件的模块间通信)

    上篇博文链接 Prism for WPF初探(构建简单的模块化开发框架) 一.简单介绍: 在上一篇博文中初步搭建了Prism框架的各个模块,但那只是搭建了一个空壳,里面的内容基本是空的,在这一篇我将实 ...

  6. Jmeter+Ant+Jenkins接口自动化测试(一)_环境部署

    前言: 2017年最后一个月份,今天抽出时间把之前的一些记录分享出来,也为今年画上个简单的句号吧,无论好与坏,无论成功与失败,简单的记忆,不要留下点点空白. 特别提示: 知识是用来分享的,但是也要尊重 ...

  7. vue 和 react 学习 异同点

    vue 和 react 学习 异同点 本文不做两个框架比较,只对比了两个框架的语法对比,不代表任何观点,盗版必究,本人唯一qq:421217189 欢迎大家一起来学习探讨,壮我大前端(本文markdo ...

  8. java 分解质因数

    算法目的:对一个正整数分解质因数 一.算法分析: 1.建立整数列表,保存求到的因数. 2.声明整数i=2,用以递增取模:整数m,用于临时保存n 3.建立while循环,i小于等于整数m时,判断m%i, ...

  9. Python爬虫——爬豆瓣登录页面

    直接上代码 import urllib.request import http.cookiejar from lxml import etree # from spiderImg import get ...

  10. 求字符数组逆序数(poj1007)

    int InversionNumber(char* s,int len) { int ans=0;  //s逆序数 int A,C,G;  //各个字母出现次数,T是最大的,无需计算T出现次数 A=C ...