在我的特殊情况下:
callback instanceof Function
或者
typeof callback == "function"
有什么区别吗?
额外资源:
JavaScript-Garden typeof与instanceof
在我的特殊情况下:
callback instanceof Function
或者
typeof callback == "function"
有什么区别吗?
额外资源:
JavaScript-Garden typeof与instanceof
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
两者在功能上相似,因为它们都返回类型信息,但我个人更喜欢,instanceof
因为它比较实际类型而不是字符串。类型比较不太容易出现人为错误,并且在技术上更快,因为它比较内存中的指针而不是进行整个字符串比较。
使用 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"
所以在我看来,这取决于您正在检查的可能数据的类型。
为了把事情说清楚,你需要知道两个事实:
Object.setPrototypeOf()
方法(ECMAScript 2015)或__proto__
属性(旧浏览器,已弃用)显式设置。但是,由于性能问题,不建议更改对象的原型。 因此 instanceof 仅适用于对象。在大多数情况下,您不会使用构造函数来创建字符串或数字。你可以。但你几乎从不这样做。
instanceof 也无法检查究竟是哪个构造函数用于创建对象,但会返回 true,即使对象是从被检查的类派生的。在大多数情况下,这是所需的行为,但有时并非如此。所以你需要保持这种心态。
另一个问题是不同的作用域有不同的执行环境。这意味着它们具有不同的内置函数(不同的全局对象、不同的构造函数等)。这可能会导致意想不到的结果。
例如,[] instanceof window.frames[0].Array
将返回false
,因为Array.prototype !== window.frames[0].Array
和数组继承了前者。
此外,它不能用于未定义的值,因为它没有原型。
现在让我们谈谈一件棘手的事情。如果使用构造函数来创建原始类型会怎样?
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);
更新: 从 ECMAScript 2015 开始,还有一种类型叫做 Symbol,它有自己的 typeof == "symbol"。
console.log(typeof Symbol());
// expected output: "symbol"
我在 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
所以从现在开始我将同时使用两者。