推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
zrp1994

JavaScript 里面使用 instanceof 来判断变量是否为 function,这种用法有什么问题么?看到用的不多。。。

  •  
  •   zrp1994 · Aug 21, 2015 · 6338 views
    This topic created in 4095 days ago, the information mentioned may be changed or developed.

    顺便查了下 instanceof 的原理。暂时没发现这样判断有什么问题……

    23 replies  •  2015-08-22 22:40:50 +08:00
    immjun
    immjun
    Aug 21, 2015
    1
    typeof
    exoticknight
    exoticknight
    Aug 21, 2015
    2
    我用 typeof
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    3
    @immjun
    @exoticknight
    我知道有 typeof ,但是为什么大家不用 instanceof 呢? typeof 跨浏览器很多问题的
    learnshare
    learnshare
    Aug 21, 2015
    4
    可以看看 underscore 或 lodash 的实现方式
    mcfog
    mcfog
    Aug 21, 2015❤️2
    5
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    6
    @mcfog 好吧……强行改变隐型原型……这个算一条
    mcfog
    mcfog
    Aug 21, 2015
    7
    还有个反向的例子



    浏览器里不高兴找哪里有 util.inherits 了就用了 node
    wssgcg1213
    wssgcg1213
    Aug 21, 2015
    8
    跨 context 比如 iframe
    YuJianrong
    YuJianrong
    Aug 21, 2015
    9
    @zrp1994 typeof 跨浏览器有什么问题?

    另外改__proto__不算一条,这个根本不应该改,该出错了就错了呗。

    虽然我觉得两个都可以,不过语义上显然 typeof 更合理,虽然 function 确实也是对象,但 instanceof 语义上应该是确定普通对象的类型,而不是像这样用在确定 function 上,毕竟 function 已经被“虚拟”成一种高于对象的类型了(所以 typeof func === "function"),实在没办法的类型比如 Date 才应该用 instanceof 或者 Object.prototype.toString.call
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    10
    @mcfog 我去看下 util.inherits
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    11
    @YuJianrong 你再 IE 8 及以下试下 alert (window.open )
    spance
    spance
    Aug 21, 2015
    12
    instanceof 判断左是不是右的一个实例,或者左是不是从右继承来的,判断依据是 左.__proto__===右.prototype
    typeof 检查变量的类型,等同于强类型语言的变量类型自举。
    明显,这 2 个语义是完全不同的。

    是一个 function 的实例,它未必是一个 function 类型。
    是一个 function 类型,它一定(默认)是从 Function 继承的。


    @mcfog 你的例子, MyFunction 是一个 constructor , b 是 MyFunction 的一个实例,这个 constructor 只是构造了一个普通的 object 就是 b 但它不是一个 function 类型,但却是从 MyFunction 分娩来的,所以 instanceof 一定是真。
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    13
    @mcfog
    @spance
    是不是可以这么理解?
    MyFunction.prototype = Function;
    b = new MyFunction
    因为这时:
    b.__proto__.__proto__ === MyFunction.prototype === Function
    所以导致 instanceof 无法真实反映 b 的类型?
    spance
    spance
    Aug 21, 2015
    14
    @zrp1994 instanceof 反应的结果哪里有问题?(如果没有修改__proto__等私有属性的话)

    b is a instance of MyFunction
    MyFunction extends from Function
    Function extends from Object

    所以, b instanceof MyFunction====true
    b instanceof Function====true
    b instanceof Object====true
    但是, b is not a Function
    spance
    spance
    Aug 21, 2015
    15
    @zrp1994 sorry,b instanceof Function====false 因为 b.__proto__ ==== {} object
    而 Function.prototype=Function
    instanceof 判断依据是 左.__proto__===右.prototype 并且不断向上递推直到左的.__proto__是 null
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    16
    @spance 明白了
    一般的函数字面量表示的函数它们已经是 Function 的实例了,他们的直接 prototype 指向的不是 Function ,在此基础上构造出的新实例的__proto__指向的也不是 Function ,所以 instanceof 不是 Function

    然而按照上面的修改,改变了 MyFunction 的 prototype 指向, instanceof 从功能上讲是准确的

    其实我的意思是 b 在这个时候从意义上讲更应该是一个 object ,而且 typeof b 也是“ object ”,我觉着这个时候用 instanceof 判断 b 的“类型”就不准确了
    YuJianrong
    YuJianrong
    Aug 21, 2015
    17
    @zrp1994 没 IE8 及以下,不能直接说一下吗……

    完全看不懂后面你们在说啥了……

    MyFunction.prototype = Function;

    这个基本没有意义不大会有人这样做吧?毕竟 function 是特殊对象……
    spance
    spance
    Aug 21, 2015
    18
    @zrp1994 是的,实际上对 instanceof 的判断就是要从左.__proto__===右.prototype 来是准确的。
    因为如果继承是用父构造方法 apply 的方式,此时 instance.__proto__是自己的构造方法的(这是被 new 设值的),不会等于父构造方法,也就是说 instance 除了 instaceof 自己构造方法是 true 就剩下 Object 是 true 了,中间继承链上的父、爷等不会 true.
    如果是用 prototype 方式继承的,那么父、爷的 prototype 被继承时人为修改了,在左.__proto__===右.prototype 的判断中是相等的,那么就会有不光是自己构造方法的 isinstanceof==true 还会有中间链上的 isinstanceof==true 了,此时 instanceof 的效果就类似于普通面向对象语言的 isinstanceof 的语义了。
    zrp1994
    zrp1994
    OP
    Aug 21, 2015
    19
    @YuJianrong 低版本 IE 中 native functions 的 typeof 的结果不是“ function ”而是“ object ”
    YuJianrong
    YuJianrong
    Aug 21, 2015
    20
    原来如此。不过 native function 本来就不大会用上 typeof 吧。
    LancerComet
    LancerComet
    Aug 21, 2015
    22
    好像 Object.prototype.toString.call () 很少有人使用
    an168bang521
    an168bang521
    Aug 22, 2015
    23
    Object.prototype.toString.call ()是最完美的判断方法, instanceof 如果原型中修改了,就不准了; typeof 再检测 Object 的时候,正则,数组,日期,等所有的都是返回 Object ,不精确;
    上面的方法也可以用 Object 的实例来代替,比如[].toString.call ()
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   918 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 20:16 · PVG 04:16 · LAX 12:16 · JFK 15:16
    ♥ Do have faith in what you're doing.