文章目录

  • 前言
  • 一、JavaScript有几种数据类型?
  • 二、判断数据类型的办法
    • 1.typeof
    • 2.instanceof
    • 3.constructor
    • 4.Object.prototype.toString.call()
    • 5.比拟一下四种办法优缺点!!
  • 三,深浅拷贝
    • 浅拷贝
    • 浅拷贝的办法
  • 总结
    • *

前言

明天温习一下无关数据类型的内容

一、JavaScript有几种数据类型?

在JavaScript中有两种数据类型,分为根本数据类型援用数据类型
根本数据类型中包含:String,Number,Undefined,Null,Boolean,Symbol
援用数据类型中包含:Object,Funtion,Array,Error,Set,Map等等…

两者次要区别在于:
根本数据类型存储的是值,援用数据类型中存储的是地址。当创立一个援用类型的时候,计算机会在内存中帮咱们开拓一个空间寄存,这个空间有一个地址。

二、判断数据类型的办法

罕用判断数据类型的办法有四种:typeof,instanceof,constructor,Object.prototype.toString.call()

1.typeof

typeof:能够对根本数据类型(除Null)做出精确判断,对于援用类型(除Function)都无奈做出精确判断,返回均为Object,因为所有对象的原型链最终都指向了Object。

typeof返回一个示意数据类型的字符串,返回后果包含了:number,boolean,string,object,function,undefined,symbol七种数据类型。

typeof null返回的是Object,typeof function返回 function

2.instanceof

instanceof运算符用于检测构造函数的prototype属性是否呈现于某个实例对象的原型链上。 ——MDN

代码如下(示例):

var str = '放牛小户'console.log(str instanceof String) // falsevar bool = trueconsole.log(bool instanceof Boolean) // falsevar num = 123console.log(num instanceof Boolean) // falsevar nul = nullconsole.log(nul instanceof Object) // falsevar und = undefinedconsole.log(und instanceof Object) // false// 从下面的运行后果来看,根本数据类型是没方法检测进去的// 然而通过构造函数创立的根本数据类型是能够检测进去的,看上面代码var num = new Number(123)console.log(num instanceof Number) // truevar str = new String('abc')console.log(str instanceof String) // truevar boolean = new Boolean(true)console.log(boolean instanceof Boolean) // true// 剩下的本人试一下,通过构造函数创立的根本数据类型是能够检测进去的// 对于援用类型也是能够检测进去的var oDate = new Date();console.log(oDate instanceof Date) // truevar json = {};console.log(json instanceof Object) // truevar arr = [];console.log(arr instanceof Array) // truevar reg = /a/;console.log(reg instanceof RegExp) // truevar fun = function(){};console.log(fun instanceof Function) // truevar error = new Error();console.log(error instanceof Error) // true 

这里有人说instanceof无奈判断根本数据类型,依据定义我了解的是只有是通过构造函数创立的,无论是根本数据类型还是援用数据类型都是能够检测出的,欢送打脸!

3.constructor

constructor:查看对象对应的构造函数
这种形式能够判断(除null和undefined之外)所有数据类型。因为undefined和null是有效对象,没有constructor存在。

代码如下(示例):

// 这里就不都一一列举啦!var str = '放牛小户'console.log(str.constructor == String) // truevar bool = trueconsole.log(boor.constructor ==Boolean) // truevar arr = [];console.log(arr.constructor == Array) //truevar fun = function() {};console.log(fun.constructor == Function) //true// 上面这两个会报错哦!// var nul = null;// console.log(nul.constructor == Object) //报错//var und = undefined;//console.log(und.constructor == Object) //报错 

constructor是不保险的,因为constructor属性是能够被批改的,会导致检测出的后果不正确

function A() {}function B() {}// 这里咱们申明两个构造函数A.prototype.constructor = B// 批改一下A构造函数的指向console.log(A.constructor == A) // false 

4.Object.prototype.toString.call()

Object.prototype.toString.call():该办法是通过子类在外部借用Object中提供的toString()办法,默认返回其调用者的具体类型。

格局为[object xxx],xxx是具体的数据类型。

代码如下(示例):

var str = '放牛小户';console.log(Object.prototype.toString.call(str));//[object String]var bool = true;console.log(Object.prototype.toString.call(bool))//[object Boolean]var num = 123;console.log(Object.prototype.toString.call(num));//[object Number]var nul = null;console.log(Object.prototype.toString.call(nul));//[object Null]var und = undefined;console.log(Object.prototype.toString.call(und));//[object Undefined]var oDate = new Date();console.log(Object.prototype.toString.call(oDate));//[object Date]var json = {};console.log(Object.prototype.toString.call(json));//[object Object]var arr = [];console.log(Object.prototype.toString.call(arr));//[object Array]var reg = /a/;console.log(Object.prototype.toString.call(reg));//[object RegExp]var fun = function(){};console.log(Object.prototype.toString.call(fun));//[object Function]var error = new Error();console.log(Object.prototype.toString.call(error));//[object Error] 

5.比拟一下四种办法优缺点!!


我想下面那局部内容对你来说都是开胃菜了,铺垫完根本数据类型和援用数据类型,明天的最重要的局部要来了!深浅拷贝冲呀!!!你点目录跳到这里会不会看不到我这部分内容,我想和你互动一下????????????

三,深浅拷贝

在介绍根本数据类型和援用数据类型的区别时说,根本数据类型是按值拜访的,当变量复制根本类型后,这两个变量是齐全独立的。即便批改第一个变量,也不会影响到第二个变量!!(不信你试一下?要不我写段代码吧)

代码如下(示例):

var str1 = 'a'var str2 = str1str2 = 'b'console.log(str1)  // aconsole.log(str2) // b 

但对于援用数据类型,当变量复制援用类型后,和根本类型一样的是都将变量值复制到新的变量上。然而它是一个指针指向存储在堆内存中的对象,这里我上个图看一下。

这图好不容易找到的呢,没方法谁叫我不会画呢,先谢谢原博主了,因为我没通过人家批准用的!!

浅拷贝

浅拷贝:创立一个新的对象,这个对象有着原始对象属性值的一份准确拷贝。如果属性是根本类型,拷贝的就是根本类型的值;如果属性是内存地址(援用类型),拷贝的就是内存地址,因而如果其中一个对象扭转了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制,只复制资源而不复制空间——百度百科

浅拷贝的办法

1.Object.assign(target,…sources):第一个参数是拷贝指标,剩下的参数是拷贝的源对象。返回值:拷贝指标

留神:

  1. 不会拷贝对象继承的属性
  2. 如果指标对象中和源对象中有雷同属性,则源对象会笼罩指标对象的属性

代码如下(示例):

const target = { a: 1, b: 2 };const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);// expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget);// expected output: Object { a: 1, b: 4, c: 5 } 

Object.assign():这种办法实现了单层深拷贝,当对象只有一层属性是为深拷贝,对深层(对象中还有对象)还是浅拷贝

代码如下(示例):

 let obj1 = {        a: 1,        b: {c: {d: 0 } }    };let obj2 = Object.assign({}, obj1)let obj3 = JSON.parse(JSON.stringify(obj1)); // 这是深拷贝办法,在这里咱们做一个比照// 第一层都是深拷贝时,批改拷贝源对象也就是obj时,对其余两个对象并没有影响obj1.a = 2; console.log(obj1.a) //2console.log(obj2.a) //1console.log(obj3.a) //1// 深层时为浅拷贝,再批改源对象时,对obj2产生了影响obj1.b.c.d = 1; console.log(obj1.b.c.d); //1console.log(obj2.b.c.d); //1console.log(obj3.b.c.d); //0