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

2015-08-21 10:23:53 +08:00
 zrp1994

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

5396 次点击
所在节点    JavaScript
23 条回复
immjun
2015-08-21 10:26:50 +08:00
typeof
exoticknight
2015-08-21 10:27:22 +08:00
我用 typeof
zrp1994
2015-08-21 10:29:18 +08:00
@immjun
@exoticknight
我知道有 typeof ,但是为什么大家不用 instanceof 呢? typeof 跨浏览器很多问题的
learnshare
2015-08-21 10:34:26 +08:00
可以看看 underscore 或 lodash 的实现方式
mcfog
2015-08-21 10:36:17 +08:00
zrp1994
2015-08-21 10:40:43 +08:00
@mcfog 好吧……强行改变隐型原型……这个算一条
mcfog
2015-08-21 10:44:31 +08:00
还有个反向的例子



浏览器里不高兴找哪里有 util.inherits 了就用了 node
wssgcg1213
2015-08-21 10:47:32 +08:00
跨 context 比如 iframe
YuJianrong
2015-08-21 11:02:55 +08:00
@zrp1994 typeof 跨浏览器有什么问题?

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

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

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


@mcfog 你的例子, MyFunction 是一个 constructor , b 是 MyFunction 的一个实例,这个 constructor 只是构造了一个普通的 object 就是 b 但它不是一个 function 类型,但却是从 MyFunction 分娩来的,所以 instanceof 一定是真。
zrp1994
2015-08-21 11:28:00 +08:00
@mcfog
@spance
是不是可以这么理解?
MyFunction.prototype = Function;
b = new MyFunction
因为这时:
b.__proto__.__proto__ === MyFunction.prototype === Function
所以导致 instanceof 无法真实反映 b 的类型?
spance
2015-08-21 11:37:32 +08:00
@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
2015-08-21 11:44:19 +08:00
@zrp1994 sorry,b instanceof Function====false 因为 b.__proto__ ==== {} object
而 Function.prototype=Function
instanceof 判断依据是 左.__proto__===右.prototype 并且不断向上递推直到左的.__proto__是 null
zrp1994
2015-08-21 11:50:33 +08:00
@spance 明白了
一般的函数字面量表示的函数它们已经是 Function 的实例了,他们的直接 prototype 指向的不是 Function ,在此基础上构造出的新实例的__proto__指向的也不是 Function ,所以 instanceof 不是 Function

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

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

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

MyFunction.prototype = Function;

这个基本没有意义不大会有人这样做吧?毕竟 function 是特殊对象……
spance
2015-08-21 12:17:30 +08:00
@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
2015-08-21 12:24:01 +08:00
@YuJianrong 低版本 IE 中 native functions 的 typeof 的结果不是“ function ”而是“ object ”
YuJianrong
2015-08-21 12:35:57 +08:00
原来如此。不过 native function 本来就不大会用上 typeof 吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/214749

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX