前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊 Array 中的一个小坑 [每日前端夜话(0x07)]

聊聊 Array 中的一个小坑 [每日前端夜话(0x07)]

作者头像
疯狂的技术宅
发布2019-03-27 11:31:14
4180
发布2019-03-27 11:31:14
举报
文章被收录于专栏:京程一灯京程一灯

原文标题:Arrays, symbols, and realms

原文:https://jakearchibald.com/2017/arrays-symbols-realms/

翻译:疯狂的技术宅

每日前端夜话,陪你聊前端。每天晚上18:00准时推送

Array 类型检测

假设obj是一个数组,我们想要实现一些功能。比如JSON.stringify就是一个例子,它以不同的方式把数组输出到其他对象。

我们可以这样做:

但是对于数组的子类来说这是错误的:

所以如果你想检查子类的类型,那么应该用instanceof

但是当引入多个realm时,事情将会变得更加复杂:

Multiple realms

realm包含self引用的JavaScript全局对象。 因此,可以说在worker中运行的代码与在页面中运行的代码处于不同的realm。 在iframe之间也是如此,但同源iframe也共享一个ECMAScript'代理',这意味着对象可以穿越 realm

接着看代码:

这两个都是false,因为:

iframe有自己的数组构造函数,它与父页面中的构造函数不同。

Array.isArray

Array.isArray将为数组返回true,即使它们是在另一个realm中创建的。 对于任何realm的Array的子类,它也会返回true。 这就是JSON.stringify内部的处理方法。

但是,这并不意味着arr有 array 方法。 有些甚至所有方法都已设置为undefined,或者数组可能已将其整个原型删除:

不管怎样,如果要杜绝上述问题,可以通过Array原型调用Array的方法:

Symbols 与 realms

再看看这个:

上面的logs 1, 2, 3 很不引人注目,但 for-of 循环通过调用arr[Symbol.iterator]来工作,这在某种程度上可以跨越realm。 这是如何做:

虽然每个realm都有自己的Symbol实例,但Symbol.iterator在各个realm都是相同的。

Symbols同时也是JavaScript中最独特和最独特的东西。

The most unique 多唯一性

传递给Symbol函数的字符串只是一个描述。 即使在同一realm内,这些Symbol也是独一无二的。

The least unique 最小唯一性

Symbol.for(str)创建一个与传递它的字符串唯一的symbol。 有趣的是它在各个realms都是一样的:

这就是Symbol.iterator大致的工作原理。

创建自己的 'is' 函数

如果我们想要创建我们自己的“is”函数并跨越realm会怎么样? 好吧,Symbol允许我们这样做:

即使实例来自另一个realm,即使它是一个子类,即使它的原型已被删除,也是可以的。

唯一的问题是,你需要确认自己的symbol名称在所有代码中都是唯一的。 如果其他人创建了他们自己的Symbol.for('whatever-type-symbol')并使用它来表示别的东西,那么isWhatever肯定返回false。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京程一灯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Array 类型检测
    • Multiple realms
    • Array.isArray
    • Symbols 与 realms
    • The most unique 多唯一性
    • The least unique 最小唯一性
    • 创建自己的 'is' 函数
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档