JS基础系列(一)JS数据类型

作者 : 开心源码 本文共2657个字,预计阅读时间需要7分钟 发布时间: 2022-05-13 共242人阅读

原生js数据类型、存储以及拷贝

1、类型

  • 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(ES6引入)
const a =null; // nullconst b = undefined; // undefinedconst c = 123; // numberconst d = `hello world ` // stringconst e = true; // boolean  
  • 引用数据类型:对象(Object)、数组(Array)、函数(Function)。
const obj = {name:’jack’};// Objectconst arr = [1,2,3]; // Arrayconst fn = function(){console.log(’这是一个函数’)} // Function

2、存储

  • 基本数据类型存储在栈中,占用空间较小;
  • 复杂数据类型存储在堆中,占用空间较大;

引用数据类型都是保存在堆内存中的,而后再在栈内存中保存一个对堆内存中实际对象都引用,所以js中对引用数据类型的操作都是操作对象的引用,而不是操作实际对象。

3、拷贝

  • 基本数据类型拷贝的是栈中的地址,拷贝后的变量跟被拷贝变量的值的改变互不影响;
  • 复杂数据类型,又叫引用类型,它的拷贝区分浅拷贝以及深拷贝:浅拷贝拷贝的是引用的地址,也就是只是拷贝了对象在堆中存在的指针,改变了浅拷贝后的对象以及原对象,改变的对应属性的值都会互相影响;而深拷贝就是为了区分以及改变这一问题而来的。深拷贝后的对象数据改变,跟原对象数据改变互不影响;

4、拷贝方式

  • 浅拷贝只要要直接将原变量赋值给另外一个变量;
const a = 123; const b = a;a = 456;console.log(a,b); //456 123
  • 深拷贝:
const obj = {a:123}; const copyA = obj; const copyB = deepClone(obj); obj.a = 456;console.log(copyA, copyB); // {a:456} {a:123}

看上面的输出,就很容易知道为啥要实现深拷贝了。
下面看实现深拷贝思路:

  • 既然要实现深拷贝,我们首先要知道变量的数据类型,在js中获取数据类型,我们通常会使用typeof 变量来获取,但是这在获取引用类型的时候,会发现返回的都是Object,在MDN中找了一遍,终于找到这样一段形容
//使用 toString() 检测对象类型//可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 //Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。var toString = Object.prototype.toString;toString.call(new Date); // [object Date]toString.call(new String); // [object String]toString.call(Math); // [object Math]//Since JavaScript 1.8.5toString.call(undefined); // [object Undefined]toString.call(null); // [object Null]
  • 所以,利用Object.prototype.toSting()方法来检测对象类型,通过Object.prototype.toSting.call(obj)可以返回对象类型的形容,看下面代码。
function getType(obj) {    //tostring会返回对应不同的标签的构造函数    var toString = Object.prototype.toString;    var map = {        '[object Boolean]': 'boolean',        '[object Number]': 'number',        '[object String]': 'string',        '[object Function]': 'function',        ‘[object Array]’: ‘array’,        ‘[object Date]': 'date',        '[object RegExp]': 'regExp',        '[object Undefined]': 'undefined',        '[object Null]': 'null',        '[object Object]’: ‘object’    };    if (obj instanceof Element) {        return ‘element’;    }    return map[toString.call(obj)];}

通过这个函数,我们可以获取变量的最终类型。

  • 获取类型后,我们即可以实现最终深拷贝函数了
function deepClone(data) {    var type = getType(data);    var obj;    if (type === ‘array’) {        obj = [];    } else if (type === 'object') {        obj = {};    } else {        //不再具备下一层次        return data;    }    if (type === 'array') {        for (var I = 0, len = data.length; I < len; i++) {            obj.push(deepClone(data[i]));        }    } else if (type === 'object') {        for (var key in data) {            obj[key] = deepClone(data[key]);        }    }    return obj;}

思路是:在深拷贝函数中,先获取数据类型,并且公告一个变量,开拓新的内存空间,而后根据不同的类型赋值给内部的新对象:假如是简单类型,直接返回该数据,完成拷贝;假如不是,针对ObjectArray递归获取对应的值或者者键值对并复制给内建变量,最终完成深拷贝。

当然,在ES5+中实现深拷贝还是有别的方式,比方常用的JSON.parse(JSON.stringify(obj));扩展运算符、Object.assign()都可以实现简单的深拷贝,但是都会有肯定的缺陷,至于缺陷是啥,就要大家自己去发现了,本文不做深入探讨。

最后总结一下基础数据类型和引用数据类型的区别:

  1. 堆比栈大,栈比堆速度快。
  2. 基础数据类型比较稳固,而且相对来说占用的内存小。
  3. 引用数据类型大小是动态的,而且是无限的。
  4. 堆内存是无序存储,可以根据引用直接获取。
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JS基础系列(一)JS数据类型

发表回复