typeof(不可以)
注意:不可以使用typeof,这里只是讨论typeof
var n = 10, str = "string", b = true, nu = null, un;
var obj1 = {}
var f = function() {}
var arr = []
var obj2 = new Date();
typeof n; // number
typeof str; // string
typeof b; // boolean
typeof nu; // object !!!!!!!!!!!!!!
typeof un; // undefined
typeof f; // function
typeof obj1; // object
typeof arr; // object !!!!!!!!!
typeof obj2; // object
null:经常被使用在销毁对象的方法,把对象变量设置成null。常被用作特殊的空地址。用法上null更像没意义的对象。这里也是js中说不清的地方- 数组、对象、new Date三个数据
方法一:判断爹(3种)
判断爹也有3种方法
1.1 _ proto_
使用__proto__获得对象的爹,然后和数组的爹作比较
var arr = []
arr.__proto__ == Array.prototype;
缺点:__proto__可能被浏览器禁用
1.2 Object.getPrototypeOf()
这个方法等价于上面的__proto__;
var arr = []
Object.getPrototypeOf(arr) == Array.prototype;
1.3 XX.prototype.isPrototypeOf(child)
isPrototypeof()是天生判断
var arr = []
Array.prototype.isPrototypeof(arr)
方法二:用妈妈判断(2种)
2.1 constructor
var arr = [];
arr.constructor == Array
缺点:直接使用constructor也不是很好的习惯
2.2 instanceof
返回:boolean
var arr = []
arr instanceof Array
方法三:内部隐藏属性class(利用call)
这个是 最可靠 的方法!!
因为在原型链中,可以通过修改实例常量的 ·proto· 来修改父亲,那么上面的判断就失效了。
在这样的情况下,可以访问隐藏的内部class,无论你怎么修改原型对象。这个class都不会改变
但是,class不可以直接访问。要想办法访问到顶级父对象的toString,也就是Object.prototype.toString方法实现的就是这个方法。看下面例子
var obj = {}
obj.toString(); // [object, Object]
上面返回的是[object, Object]对应的是[object, 类型名],第一个object是引用类型对象。第二个Object就是class属性值
但是因为多态,数组和Date输出的完全不是我想要的
var arr = [1, 2]
arr.toString(); // 1,2
则可以使用call(),可以让任何一个对象,抢到原来不属于它的任何一个函数
var arr = []
Object.prototype.toString.call(arr); // [object Array]
如果修改arr的爹和妈,再看下结果
var arr = []
arr.__proto__ = Object.prototype;
arr instanceof Array // false 。你看,这里就是false了
Object.prototype.toString.call(arr); // [object Array]
所以说,这个方法最可靠
方法四:Array.isArray
返回值:boolean
注意:isArray方法,也不会受到修改爹的干扰。所以isArray就是使用上面的.call()实现的获取class
var arr = []
arr.__proto__ = Object.prototype;
Array.isArray(arr); // true。因为isArray不受修改父母的干扰