JS获取对象数据类型的⽅法1.typeof:  语法:typeof 对象或者 typeof(对象)
  返回对象的数据类型:只有原始数据类型:boolean number string undefined function object
由于最初的BUG导致null的数据类型成为了object,现在,null 被认为是对象的占位符,从⽽解释了这⼀⽭盾。
缺陷:对于Array,null,Object对象和其他⾃定义对象使⽤typeof⼀律返回object;
console.log(typeof(x)); //未声明x,返回undefined
var y = false;
console.log(typeof y);  //boolean
var str = "字符串";
console.log(typeof str);    //string
var num = 5;
console.log(typeof(num));  //number
console.log(typeof NaN);    //number    NaN是⼀个特殊的数字---⾮数字
var f1 = function () {
};
console.log(typeof f1); //function
console.log(typeof null);  //object
var arr = [1, 2, 3];
console.log(typeof arr);    //object
var obj = {name: "⼩伟", age: 15};
console.log(typeof obj);    //object
var Person = function (name) {
this.name = name
};
var per = new Person("⼩王");
console.log(typeof per);    //object
2.instanceof  ⽤于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
        解读:⽤于判断某个对象是不是某个构造函数的⼀个实例,或者是不是某个构造函数的⼀个后代实例
        语法:对象 instanceof 数据类型(或者构造函数名):返回true/false
instanceof的原理:function instance_of(L, R) {//L 表⽰左表达式,R 表⽰右表达式
var O = R.prototype;// 取 R 的显⽰原型
L = L.__proto__;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这⾥重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
即⽐较对象.__proto__和数据类型(构造函数).prototype,如果相等就为true,
不同就继续跟着对象的原型链,⽐较对象隐式原型⾥的隐式原型与数据类型(构造函数).prototype
根据原型链的知识直到原型链的最终,指向Object.prototype.__proto__---为null
console.log(per instanceof Person);    //true
//per.__proto__指向其构造函数的原型对象Person.prototype,所以返回true
console.log(f1 instanceof Function);    //true
console.log(arr instanceof Array);  //true
console.log(obj instanceof Object);  //true
//同理,这些引⽤类型:Function、Array、Object、都可以视为⼀个构造函数
//对于继承的数据类型:新的实例对象根据原型链,数据类型可以是其构造函数名,也可以是其祖辈的构造函数名
var Student = function (score) {
this.score = score;
}
Student.prototype = new Person("⼩李");
var stu = new Student(100);
console.log(stu instanceof Student);    //true  stu.__proto__ == Student.prototype很易理解
console.log(stu instanceof Person);    //true
/*
* 根据原型链:stu.__proto__ == Student.prototype == new Person
*          stu.__proto__.__proto__ == new Person.__proto__ == Person.prototype
*
*
* */
注意:
* 在JavaScript中,⼀切都是⼀个对象( 或者⾄少被视为⼀个对象) 。
*    唯⼀的non-objects是基本类型:布尔值,数字,字符串和undefined ,
*    直接声明的这⼏种类型的实例不是object对象,但是可以访问其作为对象的⼀些属性和⽅法?为什么呢?
*
*    在访问基本类型数据的属性和⽅法时会临时出现⼀个包装对象:
*    ⾃动创建基本包装类型的对象,只执⾏⼀⾏代码的瞬间之后就会⽴即销毁。
    这意味着在运⾏时为基本包装类型值添加属性和⽅法是⽆效的。
*    ⽐如只要引⽤了字符串s的属性,JavaScript就会将字符串值通过调⽤new String(s)的⽅式转换成对象,成为了基本包装类型,
*    这个对象继承了字符串(String)对象的⽅法,并被⽤来处理属性的引⽤。⼀旦属性引⽤结束,这个新创建的对象就会被销毁
*
*      instanceof 运算符只对对象有效:所以对于上述的⼏个non-object⽆效,所以判断他们的数据类型时返回值会是false
*
*  另外:布尔,数字,字符串有其构造函数,如果⽤其构造函数实例化⼀个对象,则可以使⽤instanceof判断其数据类型
*
var y = false;
console.dir(y); //只是⼀个基本布尔值,没有内部结构
console.log(y instanceof Boolean);  //false
var z = new Boolean(false);
console.dir(z); //利⽤构造函数创建布尔值,可以得到内部结构,具有对象的特征
console.log(z instanceof Boolean);  //true
console.log(y.__proto__);  //由于基本包装类型的存在,可以临时访问其作为对象的属性,
// 这样做时,会将y通过调⽤new Boolean得到⼀个临时的包装对象,具有对象特征,但是语句执⾏结束后就消失
y.name = "布尔false";
console.log(y.name);    //undefined,⽆法对基本类型添加属性或⽅法
//⽆法对基元类型的数据声明属性和⽅法,因为他们不是对象,
// 可以利⽤包装类型的原理访问基元类型数据的属性和⽅法(如果他们所对应的包装对象有这个属性和⽅法的话,如果没有,返回undefined很容易理解)    console.log(str instanceof String); //false
console.log(num instanceof Number); //false
3.借⽤Object原型⾥的⼀个⽅法:String.call(对象)
可以得到对象的数据类型:包括:String、Number、Boolean、undefined、null、Object、function、Array、Date、Regexp
解决了typeof的缺陷
但是⽆法得到⾃定义构造函数实例化对象的数据类型(构造函数名),只能获得Object
注意:使⽤这个⽅法实际上是⽤call()⽅法借⽤Object原型⾥的⼀个⽅法,不能直接使⽤对象.toString(),
typeof array因为对于⼀个对象,toString⽅法是被重新定义了的,是将obj转换为字符串的⽅法,
直接使⽤对象.toString()根据原型链,在访问到这个重写的⽅法时就调⽤了,不能访问到Object原型⾥的这个同名的⽅法
console.log(String.call(null));//[object Null]
console.log(String.call(undefined)); //[object Undefined]
console.log(String.call(y)); //[object Boolean]
console.log(String.call(str));//[object String]
console.log(String.call(num));//[object Number]
console.log(String.call(f1));//[object Function]
console.log(String.call(arr));//[object Array]
console.log(String.call(obj));//[object Object]
console.log(String.call(per));//[object Object]
console.log(String.call(new Date));//[object Date]

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。