Safari的这种行为是否违反ECMAScript规范? [英] Does this Safari behavior break the ECMAScript specification?

查看:76
本文介绍了Safari的这种行为是否违反ECMAScript规范?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在OSX的Safari 13.0.4中打印1.

The following code prints 1 in Safari 13.0.4 on OSX.

let set = new Set

for(let x = 0; x < 2; x++) {
    function f() {}
    set.add(f)
}

console.log(set.size) // 1 in Safari non-strict mode

也:

let set = new Set

for(let x = 0; x < 2; x++) {
    function f() {}
    f.test = x
    set.add(f)
}

console.log(set.size); // 1 in Safari
for(let x of set) console.log(x.test) // 1 in Safari non-strict mode

并且:

let set = new Set;

for(let x = 0; x < 2; x++) {
    var v = (function () {})
    set.add(v);
}

console.log(set.size); // 2 in Safari non-strict mode

此行为是否与第13.7.4.8节兼容?(请参见下文)?

Is this behavior compatible with section 13.7.4.8 (see below) of the specification?

请注意:Node 13.9.0,Chrome 80.0.3987.122和Brave 1.3.118打印2.

Note that: Node 13.9.0, Chrome 80.0.3987.122, and Brave 1.3.118 print 2.

规范的13.7.4.8:

(似乎与4.b相关)

The abstract operation ForBodyEvaluation with arguments test, 
increment, stmt, perIterationBindings, and labelSet is 
performed as follows:

1. Let V = undefined.

2. Let status be CreatePerIterationEnvironment(perIterationBindings).

3. ReturnIfAbrupt(status).

4. Repeat

  a. If test is not [empty], then

    i. Let testRef be the result of evaluating test.

    ii. Let testValue be GetValue(testRef).

    iii. ReturnIfAbrupt(testValue).

    iv. If ToBoolean(testValue) is false, return NormalCompletion(V).

  b. Let result be the result of evaluating stmt.

  c. If LoopContinues(result, labelSet) is false, return d.
     Completion(UpdateEmpty(result, V)).

  d. If result.[[value]] is not empty, let V = result.[[value]].

  e. Let status be CreatePerIterationEnvironment(perIterationBindings).

  f. ReturnIfAbrupt(status).

  g. If increment is not [empty], then

    i. Let incRef be the result of evaluating increment.

    ii. Let incValue be GetValue(incRef).

    iii. ReturnIfAbrupt(incValue).

推荐答案

是的,这是Safari [1] 中的错误.但是,您已经注意到,它仅在全局(或eval)范围中发生,并且仅在草率模式下发生.

Yes, this is a bug in Safari[1]. However, as you noticed, it only occurs in global (or eval) scope and only in sloppy mode.

通常,这些绝对应该是不同的函数实例,而不是悬挂在块之外.但是,作为浏览器的Safari确实实现了规范附件B3.3中的块级功能声明Web旧版兼容性语义(请参见

In general, these should definitely be distinct function instances, not getting hoisted outside of the block. However, Safari - being a browser - does implement the Block-Level Function Declarations Web Legacy Compatibility Semantics from Annex B3.3 of the specification (see here for details). In ES6 and ES7, these did apply only to block statements inside functions though. Only since ES8, they are also specified for declaration instantiations in global and eval scopes.

似乎Safari尚未从ES8采纳该更改,并保留了自己的版本(不兼容)

It seems that Safari did not adopt that change from ES8 yet, and has kept their own (noncompliant) pre-ES6 semantics for block-scoped declarations in the global scope, where they hoist the declaration completely.

1:可能#201695 #179698 . "我们不支持在全局范围内.我们确实在函数内部支持它,并且我相信eval.我们仍然需要在全局范围内实现它."

1: Probably #201695 or #179698. "We don't support this in global scope. We do support it inside functions and I believe eval. We still need to implement it for the global scope."

这篇关于Safari的这种行为是否违反ECMAScript规范?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆