这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战
三、类型判断
JavaScript 判断变量的方式有:
typeof(variable)variable instanceof Arrayvariable.constructor = ArrayObject.prototype.toString.call(variable)
3.1 typeof
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();
var nan = NaN;
console.log(
typeof num, // number
typeof str, // string
typeof bool, // boolean
typeof arr, // object
typeof json, // object
typeof func, // function
typeof und, // undefined
typeof nul, // object
typeof date, // object
typeof reg, // object
typeof error, // object
typeof nan, // number
typeof 10n; // bigint
typeof BigInt(10); // bigint
typeof Symbol(); // symbol
);
typeof 能区分的:
numberstringbooleanundefinedsymbol
function- 检测其他类型的时候,都返回
object。
PS:为什么会出现
type null // object这种情况呢?因为在 JS 的最初版本中,使用的是 32 位系统,为了性能考虑使用低位存储了变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
3.2 instanceof
用于实例和构造函数的对应。例如判断一个变量是否是数组,使用 typeof 无法判断,但可以使用 [1, 2] instanceof Array 来判断。因为,[1, 2] 是数组,它的构造函数就是 Array。
instanceof 判断原型链指向,我们可以看一下它的实现原理:
function myInstanceof(left, right) {
if (typeof left !== 'object' || right === null) {
return false;
}
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.__proto__
// 判断对象的类型是否等于类型的原型
while (true) {
if (left === null)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
console.log(myInstanceof([1,2,3], Array)) // true
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();
console.log(
num instanceof Number, // false
str instanceof String, // false
bool instanceof Boolean, // false
und instanceof Object, // false
nul instanceof Object, // false
arr instanceof Array, // true
json instanceof Object, // true
func instanceof Function, // true
date instanceof Date, // true
reg instanceof RegExp, // true
error instanceof Error, // true
)
instanceof 能判断的有:
ArrayFunctionDateRegExpError
3.3 constructor
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();
function Person(){
}
var Tom = new Person();
console.log(
Tom.constructor === Person, // true
num.constructor === Number, // true
str.constructor === String, // true
bool.constructor === Boolean, // true
arr.constructor === Array, // true
json.constructor === Object, // true
func.constructor === Function, // true
date.constructor === Date, // true
reg.constructor === RegExp, // true
error.constructor === Error // true
);
得到的所有结果都是 true,除了 undefined 和 null,其他类型基本可以通过 constructor 判断。
不过因为 constructor 的属性是可以被修改的,可能导致检测出的结果不正确。
3.4 Object.prototype.toString.call
var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = { name: 'jsliang', age: 25 };
var func = function () { console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error = new Error();
console.log(
Object.prototype.toString.call(num), // [object Number]
Object.prototype.toString.call(str), // [object String]
Object.prototype.toString.call(bool), // [object Boolean]
Object.prototype.toString.call(arr), // [object Array]
Object.prototype.toString.call(json), // [object Object]
Object.prototype.toString.call(func), // [object Function]
Object.prototype.toString.call(und), // [object Undefined]
Object.prototype.toString.call(nul), // [object Null]
Object.prototype.toString.call(date), // [object Date]
Object.prototype.toString.call(reg), // [object RegExp]
Object.prototype.toString.call(error), // [object Error]
);
一个完美的判断方法,可以检测上面提到的所有类型,只需要将它的结果 result.slice(8, -1) 就能得到具体的类型。