js 判断数据类型方法

js 判断数据类型方法

1. typeof()

参考:https://www.jianshu.com/p/8107d25f54ac

js 是一门弱语言,它在声明变量时无需确定变量的类型,js 在运行时会自动判断。那么如何判断一个变量的类型呢,js 提供了 typeof 运算符,用来检测一个变量的类型。

1.1 typeof 语法

typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。

1.2 typeof 返回值

typeof运算符的返回类型为字符串,值包括如下几种:

​ ① 'undefined' --未定义的变量或值

​ ② 'boolean' --布尔类型的变量或值

​ ③ 'string' --字符串类型的变量或值

​ ④ 'number' --数字类型的变量或值

​ ⑤ 'object' --对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理)

​ ⑥ 'function' --函数类型的变量或值

1.3 示例

// 'number'
console.log(typeof 123);   //'number'
console.log(typeof NaN);   //'number'

// 'string'
console.log(typeof '123');  //'string'

// 'object'
console.log(typeof null);  //'object'  
var obj = new String();
console.log(typeof(obj));    //'object'
let a = [];
console.log(typeof a);        //'object'

// 'function'
var fn = function(){};
console.log(typeof(fn));  //'function'
console.log(typeof(class c{}));  //'function'

// 'undefined'
console.log(typeof a);    //'undefined'

// 'boolean'
console.log(typeof(true));  //'boolean'

// 'symbol'
let a = Symbol();
console.log(typeof a);    //'symbol'

总结:typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回'object',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符。

2. instanceof

参考:https://blog.csdn.net/wyhstars/article/details/87918178

在 JavaScript 中,有7种基本类型(包括6种原始类型以及对象类型)。

在某些场景下,可能会需要我们做类型的判断,通常我们使用 typeof 。但是 typeof 在进行类型判断时有局限—— typeof 对于对象来说,除了函数都会显示 object 。因此,我们可以考虑使用 instanceof 来进行类型判断,因为 instanceof 内部机制是通过原型链来实现的

function foo() {
    console.log('我是函数');
}
let obj = {
    name: 'wyh',
    age: '23'
}
let arr = [1, 2, 3];

console.log(typeof(123))      // number
console.log(typeof('haha'))   // string
console.log(typeof(true))     // boolean
console.log(typeof(foo))      // function
console.log(typeof(obj))      // object
console.log(typeof(arr))      // object

2.1 instanceof 判断继承

刚才提到 instanceof 内部机制是通过原型链实现的,所以不难想到,可以通过 instanceof 来进行继承关系的判断

function Foo() {
    this.name = 'wyh'
    this.age = '23'
}

let foo = new Foo()
console.log(foo instanceof Foo) // true

同样的,在多层继承关系中,instanceof 同样适用:

function Foo() {
    this.name = 'wyh';
    this.age = '23';
}

function GFoo() {
    this.country = 'China';
}

Foo.prototype = new GFoo();

let foo = new Foo()
console.log(foo instanceof Foo)  // true
console.log(foo instanceof GFoo) // true

2.2 instanceof 实现原理

上面看过 instanceof 其实是通过原型链来实现继承关系的判断。那么我们如何来手写一个函数来实现 instanceof 的功能呢。首先,我们通过 ECMA 标准可以得到关于 instanceof 的底层原理:

我们只需要关注 instanceof 实现实际上是调用 JS 内部函数 [[HasInstance]] 来实现的。看到这里其实我们并不陌生,因为在 es6Symbol 章节也有类似的说明:

那么我们来看一下,ECMA 中是如何描述 HasInstance 的:

function instance_of(L, R) {     // L 表示instanceof左边,R 表示instanceof右边
    let O = R.prototype;         // 取 R 的显示原型
    L = L.__proto__;             // 取 L 的隐式原型
    while (true) {               // 循环执行,直到 O 严格等于 L
        if (L === null) return false;
        if (O === L) return true;
        L = L.__proto__;
    }
}    // 一直取 L 的隐式原型 __proto__,直到等于 R 的显示原型 prototype

instance_of 函数即是 instanceof 操作符的代码实现,并需要注意传入的参数都要为 object 类型。

2.3 instanceof 易错问题

我们通过上文已经知道, instanceof 是通过原型链来实现继承关系判断以及类型判断的。那么 instanceof 有没有弊端呢?或者说它就是判断类型的终极方法了吗? 并不是!

我们来看几个问题:

function Foo() {
    console.log('我是函数');
}

let a = 1;
console.log(a instanceof Number)       // false
console.log(Number instanceof Number)  // false
console.log(String instanceof String)  // false
console.log(Foo instanceof Foo)        // false

分析:

  • 对于 a instanceof Number ,上文提到的 ECMA 规范中指出,instanceof 用来判断的是 object 类型的,如果不是则会返回 false
  • 对于 Number instanceof Number 以及 String instanceof String ,都可以看做是 Foo instanceof Foo ,因为 NumberString 都是构造函数,原型链上都是由 Function 实例化出来的。那么我们只需要分析 Foo instanceof Foo 即可将这三个搞懂,将 { L : Foo , R : Foo } 代入到由 ECMA 规范得出的 instance_of 函数中去,即可得到:
let O = R.prototype = Foo.prototype
L = L.__proto__ = Foo.__proto__ = Function.prototype

O !== L     // 循环
L = L.__proto__.__proto__ = Function.prototype.__proto__ = Object.prototype

O !== L     // 循环
L = L.__proto__.__proto__.__proto__ = Object.prototype.__proto__ = null

return false

3. Object.prototype.toString.call()

JavaScript 文章被收录于专栏

前端技术分享

全部评论

相关推荐

Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
11-08 13:58
门头沟学院 Java
程序员小白条:竟然是蓝桥杯人才doge,还要花钱申领的offer,这么好的公司哪里去找
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务