文章目录
- 前言
- 一、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):第一个参数是拷贝指标,剩下的参数是拷贝的源对象。返回值:拷贝指标
留神:
- 不会拷贝对象继承的属性
- 如果指标对象中和源对象中有雷同属性,则源对象会笼罩指标对象的属性
代码如下(示例):
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