• sprinty
    2019-12-27
    强行找到一种方法, 但和本节所讲没啥关系:

    Object.defineProperty(global, 'x', {
        get: function() {
            return Math.random();
        }
    })

    x === x // false
    展开

    作者回复: 赞!

    的确,这是除NaN之外我认为最可行的一个答案。事实上,这也是我在课程中提升“动态语言特性”这个方向的原因:一部分动态特性是基于OOP来实现的,这正是JavaScript的混合语言特性的应用。

    不过这个例子其实可以变成更简单。例如:

    ```
    Object.defineProperty(global, 'x', { get: Symbol })

    // 或
    Object.defineProperty(global, 'x', { get: Math.random })
    ```

    AND, @晓小东 给出的Symbol()方案对这个getter方法是一个很好的补充,很好地利用了“symbol总是唯一”的特性。

    
     4
  • 晓小东
    2019-12-28
    难道是这个吗, 如果作为标识符var x 确实没想出。
    >> Symbol() === Symbol() // false

    作者回复: 参见 @sprinty 的答案。呵呵,我自己也不知道有没有更多的可能了。

    
     2
  • Geek_185c7d
    2020-01-19
    请问老师,为什么{} + {} 在浏览器中打印的是 "[object Object][object Object]"

    作者回复: 浏览器把引擎包了一层,你执行的不是真正的引擎环境。

    在node中用如下命令行试试:
    ```
    > node -p -e '{} + {}'
    NaN

    > node -p -e '{} + []'
    0
    ```

    
    
  • 晓小东
    2019-12-27
    老师我测很多代码得出一个总结:
    参与 + 或 - 运算 + - 只认那五种值类型数据,
    从包装对象实例(String, Number, Boolean, Symbol),和数组Object 对象调用valueOf可以看出
    只要valueOf 返回五种值类型数据, 就不会toString()方法, 反之如果还是对象类型,即使是包装对象实例,还是会调用toString方法
    总结是: 在toPrimitive()中要获取五种值类型数据包括undefined 和 null, 大部分情况下引擎都是按数据值类型进行预测: 如下:
    {}; + []
    String(1) + [];
    1 - [];
    都是valueOf -> toString 过程

    最终在toPrimitivie() 中 根据 + 或者 - 以及运算符两侧值类型 调用相应String 或者Number 进行转换 求值
    所以最终的结果只有三种 字符串、数值、和 NaN

    直接toString就是在模板字符串中(目前发现这一种除了Date)
    `${x}`

    测试代码如下
    代码链接 https://repl.it/@XiaoDHuang/MadEuphoricTabs

    let valueOf = Array.prototype.valueOf
    let toString = Array.prototype.toString;

    Array.prototype.valueOf = function() {
        console.log(this.flag + " valueOf")
        return valueOf.call(this);
    }

    Array.prototype.toString = function() {
        console.log(this.flag + ' toString');
        return toString.call(this);
    }

    var x = [];

    x.flag = '{}; + []';
    {}; + x;

    x.flag = 'String(1) + []';
    console.log(1 + x);

    x.flag = '1 - []';
    console.log(1 - x);

    x.flag = '`${x}`'
    console.log(`${x}`);
    展开

    作者回复: 是的呀。

    > 总结是: 在toPrimitive()中要获取五种值类型数据包括undefined 和 null, ...
    ------

    在上一小节里不是讲过了么?原文是:
    > > 一种关于“原始值”的简单解释是:所有 5 种能放入私有槽(亦即是说它们有相应的包装类)的值(Values),都是原始值;并且,再加上两个特殊值 undefined 和 null,那么就是所谓原始值(Primitive values)的完整集合了。

    > 只要valueOf 返回五种值类型数据, 就不会toString()方法, 反之如果还是对象类型,即使是包装对象实例,还是会调用toString方法...
    ----
    这在这一讲的“步骤4”中也讲到了。原文是:
    > > 这需要利用到对象的valueOf()和toString()方法:当预期是“number”时,valueOf()方法优先调用;否则就以toString()为优先。并且,重要的是,上面的预期只决定了上述的优先级,而当调用优先方法仍然得不到非对象值时,还会顺序调用另一方法。

    最后,关于Date()类型中顺序相反的问题,本讲里也是解释了的哟哟哟哟~ ^^.

    
    
  • Astrogladiator-埃蒂...
    2019-12-27
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

    看了下mdn,还真是只有NaN这么一种情况。

    If Type(x) is different from Type(y), return false.
    If Type(x) is Number or BigInt, then
    Return ! Type(x)::equal(x, y).
    Return ! SameValueNonNumeric(x, y).

    Assert: Type(x) is not Number or BigInt.
    Assert: Type(x) is the same as Type(y).
    If Type(x) is Undefined, return true.
    If Type(x) is Null, return true.
    If Type(x) is String, then
    If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
    If Type(x) is Boolean, then
    If x and y are both true or both false, return true; otherwise, return false.
    If Type(x) is Symbol, then
    If x and y are both the same Symbol value, return true; otherwise, return false.
    If x and y are the same Object value, return true. Otherwise, return false.

    按照https://tc39.es/ecma262/#sec-samevaluenonnumeric的说明测试了下也没有找到其他的可能

    好奇这个答案是什么
    展开

    作者回复: 绝对是还有的。至少一个。^^.

     1
    
  • 晓小东
    2019-12-27
    老师这个“其中的 boolean 是通过查表来进行的“ 这个查表该如何理解???

    作者回复: Here:

    https://tc39.es/ecma262/#sec-toboolean

    
    
  • 潇潇雨歇
    2019-12-27
    想不出啦……NaN不是唯一的吗

    作者回复: 参见 @sprinty 的答案哟。总算有人给出来这个标准答案了。呵呵~

     6
    
我们在线,来聊聊吧