为什么
最近我开始阅读.js源码,并将.js源码解读纳入我的2016年计划中。
阅读一些著名框架库的源码就像和大师交谈一样。 你会学到很多东西。 为什么? 主要是因为它短小精悍(约1.5k行),封装了100多个有用的方法,耦合度低,非常适合逐个方法的阅读,适合像原贴者这样的初学者。 从中你不仅可以学到一些使用void 0代替以避免被重写等技巧,还可以学到变量类型判断、函数节流&函数去抖等常用方法,还可以学到很多浏览器兼容的hacks 。 ,还可以了解到作者的整体设计思路和API设计原则(向后兼容)。
后期笔者会写一系列的文章与大家分享在源码阅读中学到的知识。
欢迎观看~(如果有兴趣,欢迎star&观看~)您的关注是作者继续写下去的动力。
为…在
今天想和大家聊聊for...in在浏览器中的兼容性问题。
对于...in大家应该都很熟悉了。 循环仅遍历可枚举属性。 像 Array 这样的对象以及使用内置构造函数创建的对象继承了 . 和 。 ,例如 () 方法或 . 该循环将迭代对象的所有可枚举属性以及从其构造函数继承的属性(包括覆盖的内置属性)。
让我们举一个简单的例子:
= {姓名:'',年龄:30};
为了(){
.log(k,obj[k]);
//输出
// 姓名
// 30 岁
等等,你告诉我for...in这东西有浏览器兼容性吗? ! 我以前从来没有注意到过,我想我在工作中也没有遇到过这样的兼容性问题! 确实,要……产生问题,必须满足两个条件。 一种是在IE中
让我们举一个简单的例子:
= {: ''};
为了(){
警报(k);
好的,我们收到了预期的“”警报,但在 IE 8 中什么也没有弹出。
我们回顾一下 for...in 的作用,循环遍历可枚举属性,那么显然 IE 8 会“默认”为非可枚举属性(虽然已经被重写)。 那么如何判断是否是在IE 8这样的环境下呢? 里面有一个函数就是用来做这个判断的:
//IE中的按键
代码一目了然,方法也用起来。
那么哪些属性在 IE 中被覆盖后不能与 for...in 一起使用
//IE
好吧,我应该错过一个。
让我们看看它是如何完成的。
(对象,键){
= .;
= 对象。;
// proto 是否继承?
= (_.() & .) || ;
// 是一个案例。
//``属性需要特殊处理
// 如果 obj 有 `` 这个键
// 并且key不在keys数组中
// 存储在数组中
= '';
if(_.has(obj,prop) & !_.(keys,prop))keys.push(prop);
//数组中的键
尽管( - ){
道具=[];
// obj 中的 prop 肯定应该返回 true,对吧? 有没有必要?
// obj[prop] !== proto[prop] 判断key是否来自原型链
if(prop inobj & obj[prop] !== proto[prop] && !_.(keys,prop)){
键.push(prop);
proto 变量存储原型。 通过 obj.. 可以获取对象的原型,但是如果重写的话,显然这样就获取不到了,所以替换为 . 比如我们重写的话,只需要比较是否是 obj. 与 proto 具有相同的引用。 个人认为源码中obj判断中的prop是多余的。 不是肯定会返回true吗? 如果有理解错误的地方,还请指出。
对于重写的情况,用 来判断。
对于上述属性被重写的情况,确实可以在IE中获取它们的属性
对于要覆盖的此类属性, ? 的判断原贴者认为也是有可能的。 该方法用于判断对象的key是否是其自身的属性,即是否来自原型链。 如果它被覆盖,它应该返回 true,否则返回 false。
重写后的可以通过obj[prop] !== proto[prop]来判断吗? 笔者认为这是可能的。 如果没有被重写,则 obj. === obj... 返回 true。 如果重写的话,obj. === .. 返回 false。
对于这一点,笔者也很疑惑,但是很明显,属性和其他属性有着明显的区别。 从代码理解的角度来说,比较容易接受。 若与原贴理解有出入,请指出!
最后总结一下,在 IE 中 for...in
最后给出这部分源码的位置。 有兴趣的同学可以看看#L904-L946
专栏作者简介()
韩子驰:一个
提示支持作者写出更多好文章,谢谢!
【今日微信公众号推荐↓】