typeof
typeof undefined //"undefined"
typeof null //"object"
typeof 123 //"number"
typeof true //"boolean"
typeof "hello" //"string"
typeof Symbol() //"symbol"
function fun(){};
typeof fun //"function"
var obj = {};
typeof obj //"object"
为什么对null
使用typeof
运算符会返回object
?
因为在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0
。由于 null
代表的是空指针(大多数平台下值为 0x00),因此,null
的类型标签也成为了 0
,typeof null
就错误的返回了"object"
。
instanceof
instanceof
运算符用于测试构造函数的prototype
属性是否出现在对象的原型链中的任何位置。
function Fun(age){
this.age = age;
}
var obj = new Fun(18);
obj instanceof Fun //true
obj instanceof Object //true
var obj2 = {};
obj2 instanceof Object //true
var arr = [];
arr instanceof Array //true
arr instanceof Object //true
function fun(){}
fun instanceof Function //true
var reg = /[hbc]at/gi;
reg instanceof RegExp //true
var date = new Date();
date instanceof Date //true
instanceof
的实现原理:
function instanceofFun(left,right){
var leftProto = left.__proto__, //取left的隐式原型
rightProto = right.prototype; //取right的显式原型
while(true){
if(leftProto === null){
return false;
}
if(leftProto === rightProto){
return true;
}
leftProto = leftProto.__proto__;
}
}
constuctor
基本数据类型中只有boolean
,string
和symbol
可以通过constructor
属性查询到构造函数。
true.constructor === Boolean //true
''.constructor === String //true
Symbol().constructor === Symbol //true
var obj = {};
obj.constructor === Object //true
var arr = [];
arr.constructor === Array //true
function fun(){}
fun.constructor === Function //true
var reg = /[hbc]at/gi;
reg.constructor === RegExp //true
var date = new Date();
date.constructor === Date //true
Object.prototype.toString.call()
Object.prototype.toString.call(null); //"[object Null]"
Object.prototype.toString.call(undefined); //"[object Undefined]"
Object.prototype.toString.call("abc"); //"[object String]"
Object.prototype.toString.call(123); //"[object Number]"
Object.prototype.toString.call(true); //"[object Boolean]"
Object.prototype.toString.call(Symbol()); //"[object Symbol]"
function fun(){}
Object.prototype.toString.call(fun); //"[object Function]"
var obj = {};
Object.prototype.toString.call(obj); //"[object Object]"
var arr = [];
Object.prototype.toString.call(arr); //"[object Array]"
var reg = /[hbc]at/gi;
Object.prototype.toString.call(reg); //"[object RegExp]"
var date = new Date();
Object.prototype.toString.call(date); //"[object Date]"
很明显这种方法不能准确判断某个对象是某个构造函数的实例,而只能用instanceof
操作符来进行判断,如下所示:
function Fun(age){
this.age = age;
}
var obj = new Fun(18);
Object.prototype.toString.call(obj); //"[object Object]"
obj instanceof Fun //true
Object.prototype.toString()
在被调用时,会执行下面的操作步骤:
-
获取
this
对象的[[Class]]
属性的值。 -
计算出三个字符串
"[object "
, 第一步的操作结果Result(1)
, 以及"]"
连接后的新字符串。 -
返回第二步的操作结果
Result(2)
。
[[Class]]
是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性,在规范中,[[Class]]
是这么定义的:内部属性描述 [[Class]]
一个字符串值,表明了该对象的类型。
$.type()
$.type()
函数用于确定JavaScript内置对象的类型,并返回小写形式的类型名称。
$.type(undefined) //"undefined"
$.type(null) //"null"
$.type(123) //"number"
$.type("abc") //"string"
$.type(true) //"boolean"
$.type(Symbol()) //"symbol"
var obj = {};
$.type(obj) //"object"
var arr = [];
$.type(arr) //"array"
function fun(){}
$.type(fun) //"function"
var reg = /[hbc]at/gi;
$.type(reg) //"regexp"
var date = new Date();
$.type(date) //"date"
$.type()
的源码内部也是使用Object.prototype.toString.call()
来判断类型的。