typeof

  1. var str='laoliang'
  2. //使用
  3. if(typeof str === 'string'){}
  4. typeof ''; // string 有效
  5. typeof 1; // number 有效
  6. typeof Symbol(); // symbol 有效
  7. typeof true; //boolean 有效
  8. typeof undefined; //undefined 有效
  9. typeof null; //object 无效
  10. typeof [] ; //object 无效
  11. typeof new Function(); // function 有效
  12. typeof new Date(); //object 无效
  13. typeof new RegExp(); //object 无效

总结:

  • 对于基本类型,除了null外,其他都可以返回正确的类型
  • 对于引用类型,除了function,都是object类型

    instanceof

    instanceof判断A是否为B的实例,是则返回true,否则false:A instanceof B
    1. var arr=[]
    2. arr instanceof Array // true
    ```javascript //instanceof的实现 function newinstanceof(leftVaule, rightVaule) { let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值 let leftVaule = leftVaule.proto; // 取左表达式的__proto值 while (true) { // 无限循环,在原型链上查找,知道满足条件return 跳出循环 if (leftVaule === null) { // 原型链的顶端
    1. return false;
    } if (leftVaule === rightProto) {
    1. return true;
    } leftVaule = leftVaule.proto } }

var arr = [] let d = new_instance_of(arr, Array) console.log(d)

  1. A instanceof B, A的原型链中层层查找,是否有原型等于B.prototype,如果一直找到A的原型链的顶端(null;即Object.prototype.__proto__),仍然不等于B.prototype,那么返回false,否则返回true.<br />总结:
  2. - instanceof只能判断两个对象是否为实例关系,而不能判断一个对象实例具体属于哪个类型
  3. ```javascript
  4. [] instanceof Array; // true
  5. {} instanceof Object;// true
  6. new Date() instanceof Date;// true
  7. function Person(){};
  8. new Person() instanceof Person;
  9. [] instanceof Object; // true
  10. new Date() instanceof Object;// true
  11. new Person instanceof Object;// true

constructor

当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用
image.png
当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时 F 原型上的 constructor 传递到了 f 上,因此 f.constructor == F
image.png
从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型
image.png
总结

  • null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
  • 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
  • 类型校验 - 图4

为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
因此,为了规范开发,在重写对象原型时一般都需要重新给 constructor 赋值,以保证对象实例的类型不被篡改。

  1. var o={a:"MMM"}
  2. function F(){}
  3. F.prototype=o
  4. var f =new F()
  5. F.prototype.constructor=F
  6. f.constructor ===F
  7. //true

Object.prototype.toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

  1. Object.prototype.toString.call('') ; // [object String]
  2. Object.prototype.toString.call(1) ; // [object Number]
  3. Object.prototype.toString.call(true) ; // [object Boolean]
  4. Object.prototype.toString.call(Symbol()); //[object Symbol]
  5. Object.prototype.toString.call(undefined) ; // [object Undefined]
  6. Object.prototype.toString.call(null) ; // [object Null]
  7. Object.prototype.toString.call(new Function()) ; // [object Function]
  8. Object.prototype.toString.call(new Date()) ; // [object Date]
  9. Object.prototype.toString.call([]) ; // [object Array]
  10. Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
  11. Object.prototype.toString.call(new Error()) ; // [object Error]
  12. Object.prototype.toString.call(document) ; // [object HTMLDocument]
  13. Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用
  14. Object.prototype.toString(Object) // '[object Object]'