如果有的话,Javascript的“typeof”会返回错误的类型吗?

时间:2014-01-30 14:59:39

标签: javascript

我正在尝试通过其他人的代码,并找到一些奇怪的事情。我在程序的一部分中找到了以下代码:

if(typeof func == "function" || (typeof func == "object" && typeof func.document == "undefined"))
{
    func();
}

这对我没有意义,因为我不确定这样的事件何时会发生? typeof返回错误的类型?或者非功能对象是否可以调用?

代码很乱,所以我无法找到这个特定检查可能成功的例子。我应该注意,代码可能超过10年。我收到的声明是它是必需的,因为有时,当代码最初编写时,typeof没有将函数作为类型返回。

此外,这项检查是必需的,因为有时func会传递一个窗口对象(?),所以有必要确保它不是一个窗口对象。

2 个答案:

答案 0 :(得分:5)

请记住:typeof适用于文字。

typeof undefined === "undefined"
typeof 5 === "number"
typeof true === "boolean"
typeof "" === "string"
typeof {} === "object"
typeof [] === "object"
typeof function { } === "function"

// null is a weird exception:
typeof null === "object"

instanceof区分什么东西是“函数”(请注意,对字符串"object"进行了类型检查,对函数Object进行了检查:

{} instanceof Object

function {} instanceof Object
function {} instanceof Function

[] instanceof Object
[] instanceof Array

如您所见,typeof表示=== "function"!== "object":这可能会产生误导,因为函数也是一个对象。这是instanceof发挥作用的时候。

现在,当您编写构造函数时,构造的对象也是函数的实例:

// the constructor
function Example { }

// the object
var ex = new Example();

typeof Example === "function"
typeof ex === "object"
ex instanceof Object
ex instanceof Example

使用原型你也可以扩展链,其中typeof始终表示对象:

function DerivedExample { }

DerivedExample.prototype = new Example();
// DerivedExample.prototype.constructor = DerivedExample;

var ex1 = new DerivedExample();

typeof DerivedExample === "function"
typeof ex1 === "object"
ex1 instanceof Object
ex1 instanceof Example
ex1 instanceof DerivedExample

所以关于javaScript typeof以及instanceof。希望它澄清正在发生的事情。


有些东西也很有用(建议不要在生产代码中使用,但我在CoffeeScript源代码中也看到过):

typeof new Number(5) === "object"
new Number(5) instanceof Object
new Number(5) instanceof Number

typeof new Boolean("true") === "object"
new Boolean("true") instanceof Object
new Boolean("true") instanceof Boolean

typeof new String("") === "object"
new String("") instanceof Object
new String("") instanceof String

关于函数和窗口对象:

每个独立函数都将在窗口的上下文中调用 (除非)当你"use strict"“指令”时,将使用未定义的上下文调用独立函数。

function world() {
    // non-strict: this === window
    // use-strict: this === undefined
}
world();

现在,当您将函数编写为对象的成员时,函数的上下文就是对象:

var hello = {
    world: function () {
        // this === hello
    }
};
hello.world();

对于在新构造的对象的上下文中调用的原型函数也是如此:

function Hello() { }

Hello.prototype.world = function () {
    // this instanceof Hello
    // this will be === ex
};

var ex = new Hello();
ex.world();

至少,您可以使用callapply更改任何功能的上下文:

var ex = { };

function Example() {
    // (1) non-strict: this === window
    // (1) use-strict: this === undefined
    // (2) this === ex
}

Example(); // (1)
Example.call(ex);  // (2)
Example.apply(ex); // (2)

答案 1 :(得分:0)

考虑这个例子

var a = [];
typeof a; // object
Object.prototype.toString.call(a); // [object Array]

var b = {};
typeof b; // object
Object.prototype.toString.call(b); // [object Object]

所以是的,typeof有时会让人感到困惑