Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数据类型判断 #19

Open
Genluo opened this issue Aug 31, 2019 · 4 comments
Open

数据类型判断 #19

Genluo opened this issue Aug 31, 2019 · 4 comments

Comments

@Genluo
Copy link
Owner

Genluo commented Aug 31, 2019

基本数据类型

  • 原始类型(Undefined、Null、Boolean、Number、String、Symbol)
  • 对象(Object)

Null类型只有一个值为null,作为原型链的重点,表示的是一个空对象,这里要注意和undefined的区别,首先从意义上来讲,null用来表示无法识别的对象值,undefined代表不存在的值,可以理解为undefined代表一个意想不到的没有值,而null作为预期没有值的代表

使用Typeof来判断数据类型

console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function

由结果可知typeof可以测试出numberstringbooleanundefinedfunction,而对于null及数组、对象,typeof均检测出为object,不能进一步判断它们的类型。

使用instanceof来检测继承对象

console.log(bool instanceof Boolean);// false
console.log(num instanceof Number);// false
console.log(str instanceof String);// false
console.log(und instanceof Object);// false
console.log(arr instanceof Array);// true
console.log(nul instanceof Object);// false
console.log(obj instanceof Object);// true
console.log(fun instanceof Function);// true

var bool2 = new Boolean()
console.log(bool2 instanceof Boolean);// true

var num2 = new Number()
console.log(num2 instanceof Number);// true

var str2 = new String()
console.log(str2 instanceof String);//  true

function Person(){}
var per = new Person()
console.log(per instanceof Person);// true

function Student(){}
Student.prototype = new Person()
var haoxl = new Student()
console.log(haoxl instanceof Student);// true
console.log(haoxl instanceof Person);// true

从结果中看出instanceof不能区别undefined和null,而且对于基本/原始类型如果不是用new声明的则也测试不出来,对于是使用new声明的类型,它还可以检测出多层继承关系。对于原始类型,会使原始类型处于读取模式,自动建立基本包装类型,但是事实上instanceof运算符是直接访问变量的原始值,所以instanceof不能直接用来判断五种基本类型

使用constructor(目前运算最快的判断变量类型的方式)

null 和undefined没有constructor属性

console.log(bool.constructor === Boolean);// true
console.log(num.constructor === Number);// true
console.log(str.constructor === String);// true
console.log(arr.constructor === Array);// true
console.log(obj.constructor === Object);// true
console.log(fun.constructor === Function);// true

console.log(haoxl.constructor === Student);// false
console.log(haoxl.constructor === Person);// true
// 封装之后
function cstor(variable) {
    if (variable === null || variable === undefined) {
        return 'Null or Undefined';
    }

    var cst = variable.constructor;

    switch (cst) {
        case Number:
            return 'Number'
        case String:
            return 'String'
        case Boolean:
            return 'Boolean'
        case Array:
            return 'Array'
        case Object:
            return 'Object'
    }
}

constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

使用Object.prototype.toString.call

console.log(Object.prototype.toString.call(bool));//[object Boolean]
console.log(Object.prototype.toString.call(num));//[object Number]
console.log(Object.prototype.toString.call(str));//[object String]
console.log(Object.prototype.toString.call(und));//[object Undefined]
console.log(Object.prototype.toString.call(nul));//[object Null]
console.log(Object.prototype.toString.call(arr));//[object Array]
console.log(Object.prototype.toString.call(obj));//[object Object]
console.log(Object.prototype.toString.call(fun));//[object Function]

function Person(){}
function Student(){}
Student.prototype = new Person()
var haoxl = new Student()
console.log(Object.prototype.toString.call(haoxl));//[object Object]

原理(摘自高级程序设计3):在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。
但是它不能检测非原生构造函数的构造函数名。

使用官方API

  • Array.isArray()
@Genluo
Copy link
Owner Author

Genluo commented Sep 2, 2019

提示:项目库中使用typeof 判断类型的好处是不会产生报错问题

@Genluo
Copy link
Owner Author

Genluo commented Sep 2, 2019

数字:JavaScript 没有真正意义上的整数,这也是它一直以来为人诟病的地方,与大部分现代编程语言(包括几乎所有的脚本语言)一样,JavaScript 中的数字类型是基 于 IEEE 754 标准来实现的,该标准通常也被称为“浮点数”。JavaScript 使用的是“双精 度”格式(即 64 位二进制)。
通常一些数字无法做到完全精确,通常我们会设置一个误差范围,通常称之为“机器精度”,这个值通常是( 2^-52 (2.220446049250313e-16)),在ES6开始该值被定义为Number.EPSILON ,在这之前的版本写polyfill:

if (!Number.EPSILON) {
   Number.EPSILON = Math.pow(2,-52);
}

@Genluo
Copy link
Owner Author

Genluo commented Sep 2, 2019

注意:虽然整数最大能够达到 53 位,但是有些数字操作(如数位操作)只适用于 32 位数字, 所以这些操作中数字的安全范围就要小很多,变成从 Math.pow(-2,31)(-2147483648, 约-21 亿),Math.pow(2,31) - 1(2147483647,约 21 亿)

a | 0可以将变量a中的数值转换为32位有符号整数,因为数位运算符|只适用于32位 整数(它只关心 32 位以内的值,其他的数位将被忽略)。因此与 0 进行操作即可截取 a 中 的 32 位数位

@Genluo
Copy link
Owner Author

Genluo commented Sep 2, 2019

void 0 === undefined; 通过void 运算符可以得到undefined值

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant