当前位置:  开发笔记 > 编程语言 > 正文

typeof和instanceof有什么区别,何时应该使用另一个?

如何解决《typeof和instanceof有什么区别,何时应该使用另一个?》经验,为你挑选了7个好方法。

在我的特殊情况下:

callback instanceof Function

要么

typeof callback == "function"

甚至重要,有什么区别?

额外资源:

JavaScript-Garden typeof vs instanceof



1> Szymon Wygna..:

使用instanceof自定义类型:

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

使用typeof了内置的简单类型:

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

使用instanceof了内建类型复杂:

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

而最后一个有点棘手:

typeof null; // object


这个答案清楚地表明为什么instaceof应该**不能用于原始类型.很明显,当涉及到自定义类型时,你没有选项,以及"对象"类型的好处.但是什么使得函数与"简单的内置类型"混为一谈?我发现一个函数如何像一个对象一样奇怪,但它的类型是'function',使得'typeof'可行.你为什么不劝阻它呢?
`对于复杂的内置类型使用instanceof` - 这仍然容易出错.最好使用ES5`Array.isArray()`等.或推荐的垫片.
@Assimilater你可以将instanceof与函数一起使用,但我认为这3条规则很容易记住,是的,函数是一个例外:)
另一个棘手的部分 - >'example string'instanceof String; // false但是新的String('example string')instanceof String; //真正
@Luke一般不会像这样使用"new String".这会创建一个"字符串对象"而不是字符串基元.请参阅此处的部分https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String

2> Soviut..:

两者在功能上都相似,因为它们都返回类型信息,但我个人更喜欢,instanceof因为它是比较实际类型而不是字符串.类型比较不容易出现人为错误,并且技术上更快,因为它比较内存中的指针而不是进行整个字符串比较.


instanceof使用同一窗口中的对象.如果您使用iframe/frame或popup-windows每个(i)帧/窗口都有自己的"函数"对象,如果您尝试比较另一个(i)帧/窗口中的对象,则instanceof将失败.typeof将在所有情况下都有效,因为它返回字符串"function".
http://jsperf.com/typeof-function-vs-instanceof/3我试过Chrome和FF3.X,"typeof"方法更快.
这只是假的.它们不完全相同.它们不会在所有相同的情况下工作,尤其是在不同的JavaScript VM和浏览器中.
在某些情况下,instanceof将无法按预期工作,并且typeof运行良好... https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Operators/Special_Operators/Instanceof_Operator#Description
你的回答是"两者在功能上基本相同." 恭敬地,这显然是错误的.正如在我的回答中所概述和解释的那样,这两种选择都不适用于所有情况 - 尤其是跨浏 更好的方法是同时使用|| 运营商.

3> Kenneth J..:

使用typeof的一个很好的理由是变量可能未定义.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

使用instanceof的一个很好的理由是变量可能为null.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

所以我认为这取决于您检查的数据类型.


+1还注意到`instanceof`无法与原始类型比较,typeof可以.
`undefined instanceof Object`不会抛出异常,因为,呃,'undefined`被定义了.常量存在于命名空间中.当变量不存在时(例如由于拼写错误),instanceof将抛出异常.另一方面,在不存在的变量上使用typeof会产生'undefined'.
在Chrome 29.0.1541.0中,dev`undefined instanceof Object`返回false,并且不会抛出异常.我不知道最近的改变是什么,但它使`instanceof`更具吸引力.

4> Vladimir Liu..:

为了弄清楚,你需要知道两个事实:

    的instanceof运算符测试是否原型属性一的构造函数中的任何地方出现的原型链的对象.在大多数情况下,这意味着该对象被创建通过使用此构造或者其后代的.但也可以通过Object.setPrototypeOf()方法(ECMAScript 2015)或__proto__属性(旧浏览器,不推荐使用)明确设置原型.但是,由于性能问题,不建议更改对象的原型.

因此,instanceof仅适用于对象.在大多数情况下,您不使用构造函数来创建字符串或数字.您可以.但你几乎从不这样做.

instanceof也无法检查,确切地使用了哪个构造函数来创建对象,但是返回true,即使object是从被检查的类派生的.在大多数情况下,这是期望的行为,但有时并非如此.所以你需要保持这种想法.

另一个问题是不同的范围具有不同的执行环境.这意味着它们具有不同的内置函数(不同的全局对象,不同的构造函数等).这可能会导致意外结果.

例如,[] instanceof window.frames[0].Array将返回false,因为Array.prototype !== window.frames[0].Array和数组继承自前者.
此外,它不能用于未定义的值,因为它没有原型.

    typeof运算操作测试值是否属于六种基本类型之一:" 号码 "," "," 布尔 "," 对象 "," 函数 "或" 不确定 ".字符串"object"属于所有对象(函数除外,它们是对象,但在typeof运算符中有自己的值),还有"null"值和数组(对于"null",它是一个bug,但是这个bug太旧了,所以它成为一个标准).它不依赖于构造函数,即使值未定义也可以使用.但它没有提供有关对象的任何细节.因此,如果您需要它,请转到instanceof.

现在让我们谈谈一件棘手的事情.如果使用构造函数创建基本类型怎么办?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

看起来像魔术.但事实并非如此.它就是所谓的装箱(按对象包装原始值)和拆箱(从对象中提取包装的原始值).这种代码似乎"有点"脆弱.当然,您可以避免使用构造函数创建基本类型.但还有另一种可能的情况,拳击可能会打你.在基本类型上使用Function.call()或Function.apply()时.

function test(){
  console.log(typeof this);
} 
test.apply(5);

要避免这种情况,您可以使用严格模式:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

upd: 自ECMAScript 2015以来,还有一个名为Symbol的类型,它有自己的typeof == "symbol".

console.log(typeof Symbol());
// expected output: "symbol"

您可以在MDN上阅读它:( 符号,typeof).


`如果对象是由给定的构造函数创建的`这是不正确的.如果o继承自C.prototype,则`o instanceof C`将返回true.您在答案中稍后提到了一些相关内容,但目前尚不清楚.

5> Justin Force..:

我在Safari 5和Internet Explorer 9中发现了一些非常有趣(读作"可怕")的行为.我在Chrome和Firefox中使用它非常成功.

if (typeof this === 'string') {
    doStuffWith(this);
}

然后我在IE9中测试,它根本不起作用.大惊喜.但在Safari中,它是断断续续的!所以我开始调试,我发现Internet Explorer 总是返回false.但最奇怪的是,Safari浏览器似乎是在做某种在它的JavaScript虚拟机优化的地方是true第一时间,但false 每次你打一次重装!

我的大脑几乎爆炸了.

所以现在我已经解决了这个问题:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

现在一切都很好.请注意,您可以调用"a string".toString()它只返回字符串的副本,即

"a string".toString() === new String("a string").toString(); // true

所以我从现在开始都会使用它们.



6> newacct..:

instanceof我认为,当它callback是一个子类型时也有用Function



7> 小智..:

其他重大的实际差异:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有