原型类型、引用类型

☆樱花仙子☆ 提交于 2019-12-21 11:08:51

原始类型

原始类型的数据都是一些比较简单数据,比如字符串,数字等,比如:true和25,这些数据会被直接存储在变量的内存空间中。ECMAScript 5 给我们提供了5种原始类型:

类型

数据

说明

Boolean

true、false

布尔值,true或false

Number

12、12.5、NaN

整型、浮点型、特殊值NaN(Not a number)

String

'hello'、"hello"

被单引号或双引号扩起来的字符或字符串

Null

null

只有一个值null

Undefined

undefined

只有一个值undefined。任何只声明而没有赋值的变量都会被赋值为undefined。

变量在存储原始类型的数据时,直接将数据存储到变量的内存空间中。当我们将存储原始类型数据的变量赋值给另一个变量时,其实是将变量存储的值复制了一份保存到了另一个变量中。

正因为每一个变量都是使用自己独立的存储空间保存原始类型的数据,因此当我们改变一个变量中的数据时不会影响到另个变量中的数据。

检测原始类型的数据

检测原始类型的数据最好的方式是使用typeof操作符,该操作符会返回一个表示数据类型的字符串。

原始类型数据的方法

虽然字符串,数字,布尔值是原始数据类型,但是也有很多方法可以使用(null和undefined没有方法)。

引用类型

引用类型的数据稍微复杂一点,指的是JS中的对象,类似于其他编程语言中的类。对象是由一系列的键值对(属性名和属性值)组成的无序列表。ECMAScript给我们提供了如下几种内置对象:

      Object     Array     Date     RegExp(regular expression)      Function      Error      String       Number         Boolean

我们可以通过new操作符和构造函数创建对象的实例,还可以通过字面量的方式创建对象的实例。例如,下面的代码通过new操作符和创建一个Object对象的实例,并将实例保存到obj变量中,引用类型的数据并没有直接存储在变量的内存空间中,变量的内存空间中保存的仅仅是引用类型数据在内存中的地址(指针),当我们将一个引用类型的变量赋值给另一个变量时,实际上将变量的中保存的地址拷贝了一份给了另一个变量,这时这两个变量都指向了同一个对象。通过其中一个变量改变对象的 name 属性值后,会影响到另一个变量。

虽然JavaScript是一种具有垃圾回收机制的语言,我们不用关心引用类型数据的内存分配问题。但是当我们不再使用某个引用类型的变量时,最好还是解除变量对实例的引用,这样有利于垃圾回收机制及时的进行回收,从而释放内存。解除引用最简单的方式就是,将变量赋值为null。

通过构造函数的方式

我们可以使用new操作符实例化每一个内置引用类型,例如:

var items = new Array();

    var now = new Date();

    var func = new Function('a','b','return a + b');

    var obj = new Object();

    var re = new RegExp('\\d+');
    
    var error = new Error('你的浏览器不支持canvas');

通过字面量的方式

使用字面可以使我们在不使用new操作符和构造函数的情况下也可以实例化引用类型。

Object 和 Array的字面量

通过字面量的方式创建Object的实例,我们还可以使用字符串作为属性名,当我们的属性名中有空格或其他特殊字符时,尽管这两种写法在语法上有差异,但是它们的作用是相同的。

函数的字面量

在我们创建方法的时候,使用最多的方式字面量的方式。使用Function构造函数的方式很少见,通过字面量的方式创建Function类型的实例

function reflect(value) {
            return value;
        }
        // 上面代码等价于:
        var reflect = new Function('value', 'return value');

使用字面量比使用构造函数更易于编写和理解。使用构造函数的方式不利于代码的调试,JavaScript的调试器不能正确识别它们。

正则表达式字面量

JavaScript给正则表达式提供了字面量的形式:

var pattern1 = /\d+/gi;
        //等价于:
        var pattern2 = new RegExp('\\d+', 'gi');

正则表达式的字面量形式比构造函数形式更容易处理,我们不用关心字符串中的字符是否需要转义。在使用构造函数的时候,匹配模式是以字符串的形式传递的,所以需要将反斜杠进行转义。

在实例化内置引用类型时,使用字面量或构造函数都可以,没有对错之分,但是在实例化Function类型的时,建议使用字面量的形式。

访问对象的属性

属性是以键值对的形式存储在对象中,访问属性最常用的方式是使用点的方式,但也可以是方括号的形式访问:

var obj = {
            name: 'zhansan',
            age: 34
        };

        console.log(obj.name);      //'zhansan'
        //等价于:
        console.log(obj['name']);  //'zhansan'

检测引用类型的数据

var arr = new Array('1', 2, false);
    var date = new Date();
    var rp = new RegExp('\d+', 'g');
    var func = new Function('a', 'b', 'return a + b');
    var obj = new Object();
    var error = new Error('你的代码有错误');

    // 使用 typeof 操作符检测引用类型
    console.log(typeof arr);        // 'object'
    console.log(typeof date);       // 'object'
    console.log(typeof rp);         // 'object'
    console.log(typeof func);       // 'function'
    console.log(typeof obj);        // 'object'
    console.log(typeof error);      // 'object'

使用typeof检测引用类型时,除了Function以外,其他的引用类型都不能被正确的识别。这个时候我们可以使用instanceof来检测它们。

instanceof操作符需要一个对象的实例和对象的构造函数作为参数,如果实例是使用该构造函数创建话,返回true,否则返回false:

 

var arr = new Array('1', 2, false);
    var date = new Date();
    var rp = new RegExp('\d+', 'g');
    var obj = new Object();
    var error = new Error('你的代码有错误');

    // 使用instanceof操作符检测引用类型
    console.log(arr instanceof Array);         // true
    console.log(date instanceof Date);         // true
    console.log(rp instanceof RegExp);         // true
    console.log(obj instanceof Object);        // true
    console.log(error instanceof Error);       // true

因为所有的引用类型都继承自Object,因此每个引用类型的实例其实也是Object的实例:

console.log(arr instanceof Object);         // true
    console.log(date instanceof Object);        // true

原始包装器类型

JavaScript中最让疑惑的可能就是原始包装器类型。JavaScript给我们提供了 3 种包装器类型(String,Number,Boolean)。

原始包装器类型也是引用类型,当字符串,数字或布尔值被读取的时候,原始包装器类型会自动在后台创建。例如:

var name = 'zhangsan';
    var firstChar = name.charAt(0);
    console.log(firstChar);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!