【问题标题】:Why do you access Symbol.iterator via brackets?为什么要通过方括号访问 Symbol.iterator?
【发布时间】:2018-12-31 12:32:07
【问题描述】:

如果我创建了一个数组,例如 var array=[1,2,3,4]; 来返回一个迭代器,我会这样做 var iterator = array[Symbol.iterator](); 我不明白你为什么要通过括号访问 Symbol.iterator 属性?为什么不只是array.Symbol.iterator

【问题讨论】:

    标签: javascript arrays iterator symbols


    【解决方案1】:

    在名为Symbol 的数组上没有属性(除非您在其中放置一个)。相反,您正在查找其键是 Symbol.iterator 指向的符号原语的值。 Symbol.iterator 返回一个符号,您使用该符号作为查找键。这有点像用变量查找属性:

    let a = [1, 2, 3]
    a.someProp = "hello"
    
    let key = "someProp"
    
    // this doesn't work for the same reason s.Symbol.iterator doesn't:
    // a.key
    
    // but this does:
    console.log(a[key])
    
    // So with a Symbol:
    
    let k = Symbol.iterator
    console.log(typeof k)
    // k is now a reference to the symbol that is the key
    // you can use that to returns the iterator function
    console.log(a[k])    // <-- that returns your iterator function
    console.log([...a[k]()])
    
    // equivalent to:
    console.log([...a[Symbol.iterator]()])

    【讨论】:

      【解决方案2】:

      因为这就是可迭代协议的工作方式。见MDN

      可迭代协议允许 JavaScript 对象定义或自定义它们的迭代行为,例如在 for..of 构造中循环的值。一些内置类型是具有默认迭代行为的内置可迭代对象,例如 Array 或 Map,而其他类型(例如 Object)则不是。

      为了可迭代,对象必须实现@@iterator 方法,这意味着对象(或其原型链上的对象之一)必须具有带有@@iterator 键的属性,该键可通过常量 Symbol 获得.iterator:

      解释器需要一种方法来确定一个 generic 对象是否是可迭代的。虽然可以指定每个可迭代对象都有一个字符串 iterator 属性,当调用该属性时,该属性会返回该对象的迭代器,这对于可能碰巧具有 @987654323 的(预迭代器)对象可能是一个问题@property 但不符合实际的规范迭代器协议。

      要求通过(唯一的、特定于迭代器的)Symbol 访问迭代器属性可确保不会发生此类有问题的冲突。

      (附带说明:array.Symbol.iterator 将要求 Symbol 成为 array 的属性,这没有多大意义 - Symbol 是一个全局对象

      【讨论】:

        【解决方案3】:

        array.Symbol.iterator 表示“访问array 变量的Symbol 成员,然后访问该值的iterator 成员”但是这将返回错误Uncaught TypeError: Cannot read property 'iterator' of undefined,因为该数组没有名为Symbol 所以它返回 undefined 并且 undefined 没有 iterator 成员。

        JS 中的点. 运算符是左关联的,因此它是从左到右计算的。您需要使用方括号来明确您想要什么,您想要的是访问Symboliterator,然后使用该值访问array 变量的成员。

        使用数学类比,array.Symbol.iteratorarray[Symbol.iterator] 之间的区别就像 6 / 0 + 2(未定义,不能除以 0)和 6 / (0 + 2)(= 3,有效操作!)之间的区别。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-18
          • 2015-07-23
          • 1970-01-01
          • 2022-11-10
          • 2014-08-09
          • 2013-06-16
          • 2019-10-27
          • 1970-01-01
          相关资源
          最近更新 更多