Skip to content

JS数据类型检测 #30

Open
Open
@conan1992

Description

@conan1992

1. typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
typeof可以检测出除null以外的基本数据类型;对于引用数据类型,除了函数之外,都会显示"object"。

console.log(typeof 42);
// expected output: "number"

console.log(typeof 'blubber');
// expected output: "string"

console.log(typeof true);
// expected output: "boolean"

console.log(typeof undeclaredVariable);
// expected output: "undefined";

console.log(typeof null);
// expected output: "object";


console.log(typeof Symbol("abc"));
// expected output: "symbol";
var fn = function(){}
    console.log(typeof fn);
// expected output: "function";

2. 引用数据类型检测

那么改用什么方法来进行引用数据类型检测呢?
答案是:

//Object.prototype.toString.call();
var fn = function(){}
console.log(Object.prototype.toString.call(fn))
// expected output: "[object Function]";
console.log(Object.prototype.toString.call([]))
// expected output: "[object Array]";

3. 数组类型检测

Array.isArray()

Array.isArray([1, 2, 3]);  
// true
Array.isArray({foo: 123}); 
// false
Array.isArray("foobar");   
// false
Array.isArray(undefined);  
// false

4. instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// expected output: true

console.log(auto instanceof Object);
// expected output: true

5. 拓展

  • 手动实现一下instanceof的功能
function Person(){};
    var p1 = new Person();
    function insOf(left, right){
      if(typeof left !== "object" || left === null) return false
      let target = right.prototype;
      while(left){
        left = Object.getPrototypeOf(left)
        if(left === target){
          return true
        }
      }
      return false
    }
    console.log(insOf(111, String))// false
    console.log(insOf(p1, Person))// true

//三元大佬的方法:
function myInstanceof(left, right) {
    //基本数据类型直接返回false
    if(typeof left !== 'object' || left === null) return false;
    //getProtypeOf是Object对象自带的一个方法,能够拿到参数的原型对象
    let proto = Object.getPrototypeOf(left);
    while(true) {
        //查找到尽头,还没找到
        if(proto == null) return false;
        //找到相同的原型对象
        if(proto == right.prototype) return true;
        proto = Object.getPrototypeof(proto);
    }
}
  • Object.is和===的区别

Object在严格等于的基础上修复了一些特殊情况下的失误,具体来说就是+0和-0,NaN和NaN。

function is(x, y) {
  if (x === y) {
    //运行到1/x === 1/y的时候x和y都为0,但是1/+0 = +Infinity, 1/-0 = -Infinity, 是不一样的
    return x !== 0 || y !== 0 || 1 / x === 1 / y;//考虑x=y=+0的时候
  } else {
    //NaN===NaN是false,这是不对的,我们在这里做一个拦截,x !== x,那么一定是 NaN, y 同理
    //两个都是NaN的时候返回true
    return x !== x && y !== y;
  }
}

参考

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions