js的基本类型、引用类型、包装类型

最近重温JS高程设计以及与朋友的讨论。决定趁热打铁记录JS的各类类型,并作下深刻总结。面试

js的几种类型

  1. 基本类型:Boolean、String、Number、Null、Undefined
  2. 引用类型:
    2.1 Object、Array、Date、RegExp等
    2.2 基本包装类型:Boolean、String、Number

基本类型

就是咱们日常用来作简单赋值的类型。这种数据类型是存在栈中以值得形式存在,赋值时也是直接进行值传递segmentfault

引用类型

是高级的类型,能够添加方法和熟悉等。真正的数据存在堆中,赋值时是进行址传递数组

//举个例子
    var a = [3,4,5];
    var b = a;//赋值的是 存储 a变量的地址。这时候a、b指向同一片内存区域
    b[0] = 9;//改变内存区域中的值 a的值也进行更改
    console.log(a);//[9,4,5]

基本包装类型介绍

咱们都知道只有引用类型才能添加、调用属性和方法,那为何基本类型Boolean、String、Number能调用方法?按说它是没有方法才对呀!这是由于ECMAScript提供了三个特殊的包装类型:Boolean、String、Number。每当读取这个基本类型时,后台会建立一个对应的基本包装类型的对象。使得能够操做这个基本类型了。prototype

当咱们在内存中读取基本类型时,后台会作如下操做:

1.建立对应包装类型(Boolean、String、Number)的实例
2.在实例上调用对应的方法
3.销毁这个实例
//举个实际操做的例子  
    var str = 'have a good time';
    var str2 = str.charAt(0);//h;
    str.color = 'red';
    console.log(str.color);//undefined

这是由于引用类型和基本包装类型的生存期不同。引用类型在执行流离开当前做用域时一直存在内存中。自动建立的基本包装类型的对象,只存在于执行这一行代码的一瞬间,执行完立马被销毁了。这就是为何咱们给str.color添加对象时打印出来为undefined。由于在执行完str的color这一行代码时,自动建立的包装类型对象被销毁了。下面console出来的str是新建立的String对象,没有color这个属性。设计

js类型判断

  1. typeof 主要是用来判断基本数据类型code

    //返回类型: string、number、boolean、object、undefined、function、Symbol(ES6新增)
    typeof 123; // "number"
    typeof 'cherry';// "string"
    typeof false; //"boolean"
    typeof undefined; //"undefined"
    typeof null; // "object"
    typeof {name:"cherry"};//"object"
    var fun = function(){};
    typeof fun; //"function"
    typeof new String('xxx');//"object"

    因此typeof只能用来判断基本数据类型。null、引用类型、基本包装类型都会返回object。对象

  2. instanceof 用法:A instanceof B,主要是判断A是不是某个对象的实例,简单来讲就是A的原型链上(__proto__)是否有B的原型对象(prototype)。ip

    // 例子
    var obj= {"name":"cherry"};
    obj instanceof Object; //true
    
    var strObj = new String('hello');
    strObj instanceof String;//true
    
    var str = 'hello';
    str instanceof String;//false
    //判断的原理 就是计算逐级计算左边对象的__proto__是否等于右边对象的prototype便可
    function instance(left,right){
        var obj = right.prototype;
        var left = left.__proto__;
        while(true){
            if(left === null){
                return false;
            }
            if(left == obj){
                return true;
            }
            left = left.__proto__;
        }
    }
  3. Object.prototype.toString.call()(点击看此方法具体原理)
    Object.toString()返回对象的字符串表示。可是因为数值、布尔、字符串、数组都有重写toString方法,直接调用的时候使用的是自身原型对象上有toString方法则不会往上去找Object的toString方法。这里强制使用Object原型对象上的toString方法。内存

    Object.prototype.toString.call('123');//[object String]
    var objStr = new String('123');//包装类型检测出来也是对应类型而不是对象
    Object.prototype.toString.call(objStr);//[object String]
    Object.prototype.toString.call(123);//[object Number]
    Object.prototype.toString.call(true);//[object Boolean]
    Object.prototype.toString.call(null);//[object Null]
    Object.prototype.toString.call(undefined);//[object Undefined]
    var obj = {"name":"cherry"};
    Object.prototype.toString.call(obj);//[object Object]
    var arr = [1,2,3];
    Object.prototype.toString.call(arr);//[object Array]

    总结:使用Object的toString(),能够检测出各值的类型。基本数据类型和基本包装类型返回的值是同样。因此不用担忧别人是经过基本包装类型定义的变量(面试时被问过)原型链



    面试题:判断一个值的数据类型

    function valueType(data){
        var type = null;
        var typeList = ['Object','Number','Boolean','String','Function','Object','Null','Undefined'];
        for(var item of typeList){
            if(Object.prototype.toString.call(str) == `[object ${item}]`){
                type = item;
                break;
            }
        }
        return type;
    }
相关文章
相关标签/搜索