zoukankan      html  css  js  c++  java
  • js 数据类型及检测

    js中基本数据类型有6种number、string、undefined、null、boolean,Symbol (ES6 新增,表示独一无二的值),还有一种数据类型为引用数据类型统称为Object对象,其中包括常见的Arry(数组)、Function(函数)、Date等,

      基本数据类型

    1、值是不可变的

        var a='apple';
        var b=a.toUpperCase();
        console.log(a)    //apple
        console.log(b)    //APPLE

    2、基本数据类型直接存放在栈中,占据空间、大小固定,属于被频繁使用的,所以放入栈中存储。

    引用数据类型

    1、值是可以变的

        var a={
            name:"yuan",
            sex:"man"
        };
        a.name='zhi';
        console.log(a)    //{name: "zhi", sex: "man"}

    2、同时保存在栈和堆中

    引用数据类型数据一般比较大、结构比较复杂,如果存储在栈中会影响到程序的性能,所以分为两部分指针和实体,指针类似地址名片记录着数据存放的实际位置,存放于栈中,实体就是数据的实际起始地址。存放在堆中,使用的时候解释器获得指针地址后去堆中找到相对应的数据。

    因为这种结构,所以引用数据类型的直接赋值是指针的赋值,指向的都是同一个实体对象,所以通过某一个指针修改,存放于堆中的实体对象都会发生改变。

        var a={
            name:"yuan",
            sex:"man"
        };
        var b=a;
        b.name='zhi';    
        console.log(a)    //{name: "zhi", sex: "man"}
        console.log(b)    //{name: "zhi", sex: "man"}

    数据类型的判断(原生js)

    1、typeof

    这是最基本的一个判断方式,该操作符返回一个表示数据类型的字符串,共有7种结果:number、string、boolean、object、function、undefined、symbol。很明显它不能区分引用数据类型里面的数组等对象(包括null);

        var a=[1,2,3];
        var b=null;
        console.log(typeof a)    //object
        console.log(typeof b)    //object

    2、instanceof

    instanceof是用来判断A是否为B的实例,表达式:A instanceof B;如果A是B的实例则返回true,否则返回false;instanceof运算符是通过判断该对象在原型链上是否存在一个构造函数的prototype属性;

        var a=[1,2,3];
        var b=new Date();
        console.log(a instanceof Array)    //true
        console.log(b instanceof Date)    //true

    依上面所说这将主要涉及js中非常重要的原型链继承机制,这里就不详细说了,简单来说在 JavaScript 原型继承结构里面,规范中用 [[Prototype]] 表示对象隐式的原型,在 JavaScript 中用 __proto__ 表示,并且在 Firefox 和 Chrome 浏览器中是可以访问得到这个属性的,但是 IE 下不行。所有 JavaScript 对象都有 __proto__ 属性,但只有 Object.prototype.__proto__ 为 null,前提是没有在 Firefox 或者 Chrome 下修改过这个属性。这个属性指向它的原型对象。 至于显示的原型,在 JavaScript 里用 prototype 属性表示,这个是 JavaScript 原型继承的基础知识。

    根据相关规范和网上例子写一个instanceof:

        function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
            var O = R.prototype;// 取 R 的显示原型
            L = L.__proto__;// 取 L 的隐式原型
            while (true) {
                if (L === null)
                    return false;
                if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
                    return true;
                L = L.__proto__;
            }
        }
        var a=[1,2,3];
        var b=new Date();
        console.log(instance_of(a,Array))    //true
        console.log(instance_of(b,Date))    //true

    instanceof也具有以下三点的不足:

    1、不能检测null和undefined

        console.log(instance_of(null instanceof null))
        console.log(instance_of(undefined instanceof undefined))

    对于特殊的数据类型 null 和 undefined,他们的所属类是 Null 和 Undefined,但是浏览器把这两个类保护起来了,不允许我们在外面访问使用。

    2、通过构造函数实例化和字面量生成的基本类型判断是有一定区别的

        var a=123;
        var b=new Number(123)
    
        console.log(a instanceof Number)    //false
        console.log(b instanceof Number)    //true

    为什么会这样呢?严格意义上讲只有实例创建出来的数据才是标准的对象数据类型值,也是标准的 Number 这个类的一个实例;对于字面量方式创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于 JS 的松散特点,导致了可以使用 Number.prototype 上提供的方法。

    3、constructor

    constructor和prototype 非常相似,但 constructor 检测 Object 与 instanceof 不一样,还可以处理基本数据类型的检测。

        var a=123;
        var b=new Number(123)
    
        console.log(a.constructor==Number)    //true
        console.log(b.constructor==Number)    //true

    constructor具有以下两点不足

    1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

    2、函数的 constructor 是不稳定的,这个主要体现在把对象的原型进行重写,在重写的过程中很有可能出现把之前的 constructor 给覆盖了,这样检测出来的结果就是不准确的。

        function Fn() {
    
        }
        Fn.prototype=new Array();
    
        var a=new Fn();
        console.log(a.constructor==Array)    //true

    4、Object.prototype.toString.call()

    这个是最准确最常用的方式,首先获取Object上面的toString方法,方法执行时让里面的this指向第一个参数的值。

    关于toString:

    • 本意是转换为字符串,但是某些 toString 方法不仅仅是转换为字符串对于 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把当前的数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)

    • 对于 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把当前的数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)
    • Object 上的 toString 并不是用来转换为字符串的

    Object 上的 toString 它的作用是返回当前方法执行的主体(方法中的 this)所属类的详细信息即"[object Object]",其中第一个 object 代表当前实例是对象数据类型的(这个是固定死的),第二个 Object 代表的是 this 所属的类是 Object。

        console.log(Object.prototype.toString.call(123))    //[object Number]
    
        console.log(Object.prototype.toString.call(null))    //[object Null]
        console.log(Object.prototype.toString.call({}))    //[object Object]
        console.log(Object.prototype.toString.call(undefined))    //[object Undefined]
        console.log(Object.prototype.toString.call('123'))    //[object String]

     最后贴个图总结一下(来自网络)

  • 相关阅读:
    在Dictionary使用foreach的注意
    [公告]新增项目交流区
    博客园Blog程序中又一个奇怪问题
    公告
    网络爬客光顾博客园
    爬网的影响
    致歉
    [业界新闻]中文IT百科Beta版于2006年7月10日正式上线
    公告
    疯狂的爬网
  • 原文地址:https://www.cnblogs.com/yuanzhiguo/p/7811990.html
Copyright © 2011-2022 走看看