560 JS数据类型检测,自定义检测数据类型函数,对象转换为字符串、数字

4种检测数据类型的方法

* 1. typeof xxx

* => typeof null => "object"

* => typeof 数组、正则、日期、对象 => "object"

*

* 2. xxx instanceof xxx

* 检测当前实例是否属于这个类(也可以用来检测数据类型:对typeof的补充)

* => 不能用来处理基本数据类型(基本数据类型基于构造函数方式创建的实例是可以的)

* => 只要出现在实例的原型链上的类,检测结果都是TRUE(页面中可以手动更改原型链的指向,这样导致检测结果不一定准确)【MDN:instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上】

*

* 3. xxx.constructor === xxx

* => constructor也是一样可以被更改的(这个检测结果也不一定准确)

* => 基本数据类型也可以处理

*

* 4. Object.prototype.toString:其它类的原型上的toString基本上都是转换为字符串的,只有Object原型上的是检测数据类型的 返回结果 "[object 所属的类]"

* => Object.prototype.toString执行,它中的this是谁,就是检测谁的数据类型

* => Object.prototype.toString.call(xxx)

* => ({}).toString.call(xxx)

* => 最强大的检测数据类型方法(基本上没有弊端)

let arr = [];
let reg = /^$/;
console.log(arr instanceof Array); // => true
console.log(reg instanceof Array); // => false

console.log(1 instanceof Number); // => false
console.log(new Number(1) instanceof Number); // => true
console.log(Symbol() instanceof Symbol); // => false

console.log(arr instanceof Object); // => true
function Fn() { }
Fn.prototype = Array.prototype;
let f = new Fn;
console.log(f instanceof Array); // => true

自己封装检测数据类型的方法

// 补充的代码
let aa = "[object Object]"
let bb = "[object Number]"
let res = aa.split(' ') // ["[object", "Object]"]
let res2 = bb.split(' ') // ["[object", "Number]"]
console.log(res2)
let second1 = res[1] // Object]
let second2 = res2[1] // Number]
console.log(second1, second2)
console.log(second1.slice(0, -1), second2.slice(0, -1))  // Object Number



// 我的方案
function toType(obj) {
  let type = Object.prototype.toString.call(obj)
  return type.split(' ')[1].slice(0, -1).toLowerCase()
}



// 编写toType方法,实现数据类型检测
function toType(obj) {
    let type = Object.prototype.toString.call(obj);
    return /^\[object ([a-z]+)\]$/i.exec(type)[1].toLowerCase();
}

console.log(toType(1)); // => "number"
console.log(toType(NaN)); // => "number"
console.log(toType([])); // => "array"
console.log(toType(/^\d+$/)); // => "regexp"
console.log(toType({})); // => "object"
console.log(toType(Symbol('aa'))); // => "symbol"
console.log(toType(BigInt(10))); // => "bigint"

1594604261388

1594604282094

第一个是大正则捕获的,第二个是小正则捕获的

1594604314019


* 创建一个变量值两种方式

* 1.字面量

* 2.构造函数

* 对于基本类型来说,第一种方式创建的是 值类型,第二种方式创建的是 引用类型,但是不论哪一种类型都是当前类的一个实例。

* 把一个对象转换为字符串、数字:

​ 1.先调用其valueOf这个方法,如果返回了对应的原始值(值类型), 接下来会基于原始值进行相关的操作

​ 2.如果没有对应的原始值,才去调用toString

​ 3.Number、String、Boolean、Symbol、BigInt这些类的原型上都有自己的valueOf方法,可以获取原始值[[PrimitiveValue]]

​ 4.基本上数据类型的类的原型上都有自己的toString,但是只有基本类型所属类的原型上才有valueOf,引用类型只有Object的原型上才有valueOf(Date比较特殊,它的原型上也有valueOf)

let obj1 = {};
let obj2 = new Object();
let arr1 = [10];
let arr2 = new Array(10);

let n1 = 10;
let n2 = new Number(10);
console.log(n2 + 10); // => 20

let arr = [10];
console.log(arr + 10); // => "1010"
// 补充:对象转Number,Number函数
const obj = {
  valueOf() {
    // return 'aaa'
    // return [11, 22]
    return {name: '哈哈'}
  },
  toString() {
    return 33
  }
}

console.log(obj.valueOf())
console.log(obj.toString())
// 返回基本数据类型,则结果是NaN,说明此时不会去调用toString;返回引用类型,则结果是33,说明此时会去调用toString
console.log(Number(obj))

posted on 2020-10-23 20:51  冲啊!  阅读(134)  评论(0编辑  收藏  举报

导航