lessfish / underscore-analysis

【NO LONGER UPDATE】underscore-1.8.3.js 源码解读 & 系列文章(完)
MIT License
3.96k stars 642 forks source link

打扰一下,有一个问题想咨询你一下 #31

Closed FoxDaxian closed 5 years ago

FoxDaxian commented 7 years ago
_.isFunction = function(obj) {
            // 这最后的逻辑或跟一个false,有必要吗?
            return typeof obj == 'function' || false;
        };

underscore 中的 这个地方最后一个 false 是必要的吗?如果是有什么意义么? 你有时间的话,希望你能解答一下,谢谢!!

lessfish commented 7 years ago

@a13821190779

是有历史原因的,具体可以参考以下几个链接

FoxDaxian commented 7 years ago

@hanzichi 看了你提供的连接,好像因为ie8和11下 typeof dom 节点 有时候会返回 'function' 但是如果返回'fcuntion'的话那么这个 || false 也就无用了啊? 我理解的对吗?

FoxDaxian commented 7 years ago

并且我开虚拟机测试了一下ie8,并没有重现这个问题啊,我的代码如下:

                var obj = {}

        var type = typeof obj

        console.log(type === 'function');
        console.log(type === 'object');

        console.log('----------');

        console.log((typeof obj) === 'function')
        console.log((typeof obj) === 'object')
aswind7 commented 7 years ago

同问。 @hanzichi 看了你提供的连接,好像因为ie8和11下 typeof dom 节点 有时候会返回 'function' 但是如果返回'fcuntion'的话那么这个 || false 也就无用了啊? 我理解的对吗?

aswind7 commented 7 years ago

为何加个 || false 就能改变结果= = 不明白

mqyqingfeng commented 6 years ago

我也看了这个问题,确实是个很诡异的 bug。

问题的起源虽然是 IE8 下 typeof dom 节点会返回 'function',但是讨论着讨论着问题就变了。

有一个人写了这样的一个测试代码,这里贴上代码:

  function isFunction(value) {
    return typeof value == 'function';
  }

  var fnc = function() {};
  var obj = { 'a': 'b' };
  var num = 1;
  var xml = window.ActiveXObject ? new ActiveXObject('Msxml2.DOMDocument.3.0') : {};

  console.log('before JIT isFunction(fnc). Expected: true;  Got:', isFunction(fnc));
  console.log('before JIT isFunction(obj). Expected: false; Got:', isFunction(obj));
  console.log('before JIT isFunction(num). Expected: false; Got:', isFunction(num));
  console.log('before JIT isFunction(xml). Expected: false; Got:', isFunction(xml));

  var count = 200;
  while (count--) {
    isFunction(fnc);
  }
  console.log('typeof xml', typeof xml);

  console.log('after JIT isFunction(fnc). Expected: true;  Got:', isFunction(fnc));
  console.log('after JIT isFunction(obj). Expected: false; Got:', isFunction(obj));
  console.log('after JIT isFunction(num). Expected: false; Got:', isFunction(num));
  console.log('after JIT isFunction(xml). Expected: false; Got:', isFunction(xml));

在 IE11 下的 non-edge document modes 下,最后一个

after JIT isFunction(xml).   Expected: false; Got: true

这个人说是一个 IE11 下的 JIT bug,既然是编译上的 bug,解释的方式也无法按照常理理解了,为了让最后一个打印结果也变成 false, 只用在代码后面加上个|| false

后来这个人也验证了 IE11 下的 IE8 compat 模式的 DOM element 也有这个问题

var div = document.createElement('div');

// JIT the function
var count = 200;
while (count--) {
    _.isFunction(fn);
}

equal(_.isFunction(div), false);

如果不加上 || false 的话,这里的结果会是 true,加上的话,就会避免这个 JIT bug。

最后,没有验证过哈~ 我理解的是这样~

aswind7 commented 6 years ago

@mqyqingfeng 666 大神!

delayk commented 6 years ago

@mqyqingfeng 还是没看明白加不加 || false对于最后的结果为什么会有影响? 我看jashkenas/underscore#1621danschumann 描述typeof obj的结果保存到变量里的情况下是正确的,加 || false是隐式的实现了这一点吗?

mqyqingfeng commented 6 years ago

@delayk 有人认为这是一个代码编译上的问题,加上 || false 是避免这个编译 bug,而不是通过执行这段代码从而获得正确的结果……不过提出这个问题的人也没有去验证他的这个 bug 是否可以通过这种方式解决……