JavaScript 类型检测

151 阅读2分钟

如何进行类型区分判断?几种对类型做判断区分的方式?*

typeof

typeof 2 // number
typeof true // boolean

// 问题
typeof {} // object
typeof [] // object
  • 有哪些需要注意的特例
typeof null // object
typeof NaN // number
  • 所有的数据,在计算机底层都是按照 “64位” 的二进制存储

    • typeof是按照二进制值进行检测类型的

    • 二进制的前三位是零,认为是对象,再去看有没有实现call方法

      • 实现 => 返回 'function'

      • 没有实现 => 返回 'object'

    • null是64个零 typeof null -> 'object' 「局限性」

    • 检测未被声明的变量,值是'undefined'

instanceof

[] instanceof Object // true

  • [] 是一个空数组,也被认为是一个对象实例
2 instanceof Number  // true
[] instanceOf Array   // true
{} instanceof Array  // false
[] instanceof Object // true

instanceof 的原理实现 ***

// 通过翻户口本,查家庭信息
function myInstance(left, right) {
// 获取对象的原型
let _proto = Object.getPrototypeOf(left)
// 构造函数的prototype
let _prototype = right.prototype

while (true) {
  if (!_proto) {
    return false
  }

  if (_proto === _prototype) {
    return true
  }

  _proto = Object.getPrototypeOf(_proto)
}
}
myInstance(2, Number)

constructor

;((2).constructor ===
  Number(
    // true
    []
  ).constructor) ===
  Array // true
  • 隐患 ***

    • constructor 代表的是构造函数指向的类型,可以被修改的,而不是构造出来实例的类型

      function Fn() {}
      Fn.prototype = new Array()
      
      var f = new Fn()
      

Object.prototype.toString.call()

let a = Object.prototype.toString

a.call(2)
a.call([])
  • obj.toString()的结果 Object.prototype.toString.call(obj)结果不一样?为什么? **

    • 保证toString是Object上的原型方法

    • 优先调用本对象属性 => 原型链

  • 当对象中有某个属性和Object的属性重名时,使用的顺序是什么样的?如果说优先使用Object属性,如何做?**

    • Object.prototype.toString.call()

判断数组

  • Array.isArray() 
var arr = [1, 2, 3]; var obj = {a: 1, b: 2};
console.log(Array.isArray(arr)); // true 
console.log(Array.isArray(obj)); // false

练习题

  • 属性名不能重复,数字属性名==字符串属性名
let a={}, b='0', c=0;  
a[b]='珠峰';
a[c]='培训';  
console.log(a[b]);

// '培训'
// 基本类型直接存,引用类型存在堆里,把地址赋值给值
  • Symbol('1')!==Symbol('1')
let a={}, b=Symbol('1'), c=Symbol('1');  
a[b]='珠峰';
a[c]='培训';  
console.log(a[b]);

// '珠峰'
  • 对象属性的键会被转换为字符串

    • 在给对象a赋值时,b和c对象被转换为字符串 “[object Object]”

    • a[b]、a[c] 都会被转换为 a[“[object Object]”],它们会覆盖之前的赋值

let a={}, b={n:'1'}, c={m:'2'};  
a[b]='珠峰';
a[c]='培训';  
console.log(a[b]); //培训

// object.toString()==="[object object]"
// Object.prototype.toString / valueOf