顺便查了下 instanceof 的原理。暂时没发现这样判断有什么问题……
1
immjun 2015-08-21 10:26:50 +08:00
typeof
|
2
exoticknight 2015-08-21 10:27:22 +08:00
我用 typeof
|
3
zrp1994 OP |
4
learnshare 2015-08-21 10:34:26 +08:00
可以看看 underscore 或 lodash 的实现方式
|
5
mcfog 2015-08-21 10:36:17 +08:00 2
|
7
mcfog 2015-08-21 10:44:31 +08:00
还有个反向的例子
浏览器里不高兴找哪里有 util.inherits 了就用了 node |
8
wssgcg1213 2015-08-21 10:47:32 +08:00
跨 context 比如 iframe
|
9
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 |
11
zrp1994 OP @YuJianrong 你再 IE 8 及以下试下 alert (window.open )
|
12
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 一定是真。 |
13
zrp1994 OP |
14
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 |
15
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 |
16
zrp1994 OP @spance 明白了
一般的函数字面量表示的函数它们已经是 Function 的实例了,他们的直接 prototype 指向的不是 Function ,在此基础上构造出的新实例的__proto__指向的也不是 Function ,所以 instanceof 不是 Function 然而按照上面的修改,改变了 MyFunction 的 prototype 指向, instanceof 从功能上讲是准确的 其实我的意思是 b 在这个时候从意义上讲更应该是一个 object ,而且 typeof b 也是“ object ”,我觉着这个时候用 instanceof 判断 b 的“类型”就不准确了 |
17
YuJianrong 2015-08-21 12:16:59 +08:00
@zrp1994 没 IE8 及以下,不能直接说一下吗……
完全看不懂后面你们在说啥了…… MyFunction.prototype = Function; 这个基本没有意义不大会有人这样做吧?毕竟 function 是特殊对象…… |
18
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 的语义了。 |
19
zrp1994 OP @YuJianrong 低版本 IE 中 native functions 的 typeof 的结果不是“ function ”而是“ object ”
|
20
YuJianrong 2015-08-21 12:35:57 +08:00
原来如此。不过 native function 本来就不大会用上 typeof 吧。
|
21
scriptfans 2015-08-21 13:02:05 +08:00
|
22
LancerComet 2015-08-21 13:10:40 +08:00
好像 Object.prototype.toString.call () 很少有人使用
|
23
an168bang521 2015-08-22 22:40:50 +08:00
Object.prototype.toString.call ()是最完美的判断方法, instanceof 如果原型中修改了,就不准了; typeof 再检测 Object 的时候,正则,数组,日期,等所有的都是返回 Object ,不精确;
上面的方法也可以用 Object 的实例来代替,比如[].toString.call () |