數(shù)據(jù)類型
對外的,面對編譯器
基本數(shù)據(jù)類型(值類型)
包括
Undefined
Null
Boolean
String
Number
Symbol(ES6) 存放位置:內(nèi)存中的棧區(qū)域。
值的不可變性刽脖,稱這些類型的值為原始值。
基本數(shù)據(jù)類型的值是按值訪問的粒没,基本類型的值是不可變的。
比較:基本數(shù)據(jù)類型的比較是值的比較簇爆,只判斷是否相等癞松。
拷貝:都是值的復(fù)制爽撒,相互沒有影響。
引用數(shù)據(jù)類型(對象類型)
包括
Object
Array
Function
RegExp
Date 存放位置:內(nèi)存中的棧存放指向堆區(qū)域的指針响蓉,內(nèi)容在堆區(qū)域中
值的可變性:引用類型的值是按引用訪問的硕勿,引用類型的值是動態(tài)可變的
比較:引用類型的比較是引用地址的比較,判斷是否指向同一對象枫甲。
拷貝:
賦值:僅改變引用的指針源武,指向同一個對象,相互影響
淺拷貝:拷貝一層想幻,不對對象的子對象進(jìn)行拷貝软能,對第一層的基本類型的修改互不影響,對于子對象會相互影響举畸。
深拷貝:對對象中的子對象進(jìn)行遞歸拷貝,拷貝前后的兩個對象互不影響凳枝。
undefined 和 null 的區(qū)別抄沮?
undefined:是一個沒有設(shè)置值的變量。JavaScript特有的岖瑰。沒有返回值的函數(shù)返回為undefined叛买,沒有實(shí)參的形參也是undefined。
null:它是一個空對象指針蹋订。
null 和 undefined 的值相等率挣,但類型不等:
typeof undefined // undefined typeof null // object null === undefined // false null == undefined // true
基本數(shù)據(jù)類型和引用類型的數(shù)據(jù)結(jié)構(gòu)
基本數(shù)據(jù)類型:數(shù)據(jù)存于內(nèi)存中的棧區(qū)域。
應(yīng)用數(shù)據(jù)類型:內(nèi)存中的棧存放指向堆區(qū)域的指針露戒,內(nèi)容在堆區(qū)域中椒功。
賦值、淺拷貝和深拷貝
如果是基本數(shù)據(jù)類型智什,直接賦值动漾,會拷貝其本身,不存在淺拷貝和深拷貝荠锭。
如果是引用類型:
賦值:僅改變引用的指針旱眯,指向同一個對象,相互影響
淺拷貝:拷貝一層证九,不對對象的子對象進(jìn)行拷貝删豺,對第一層的基本類型的修改互不影響,對于子對象會相互影響愧怜。
深拷貝:對對象中的子對象進(jìn)行遞歸拷貝呀页,拷貝前后的兩個對象互不影響。
賦值
let obj1 = { color: 'red', age: 20, address: { city: 'beijing', }, arr: ['a', 'b', 'c'] }; //賦值 let obj2 = obj1; obj1.age = 21; obj1.address.city = "shanghai"; console.log(obj2.age);//21 console.log(obj2.address.city);//shanghai
淺拷貝
letobj1 = {? ? color:'red',? ? age: 20,? ? address: {? ? ? ? city:'beijing',? ? },? ? arr: ['a','b','c']};//淺拷貝letobj3 = shallowCopy(obj1);obj1.age = 21;obj1.address.city ="shanghai";console.log(obj3.age); //20console.log(obj3.address.city); //shanghai//自定義淺拷貝函數(shù)functionshallowCopy(obj) {if(typeof obj !=='object'|| obj == null) {returnobj;? ? }letresult;if(obj instanceof Array) {? ? ? ? result = [];? ? }else{? ? ? ? result = {};? ? }for(letkeyinobj) {if(obj.hasOwnProperty(key)) {? ? ? ? ? ? result[key] = obj[key];? ? ? ? }? ? }returnresult;}
深拷貝
letobj1 = {? ? color:'red',? ? age: 20,? ? address: {? ? ? ? city:'beijing',? ? },? ? arr: ['a','b','c']};//深拷貝letobj4 = deepCopy(obj1);obj1.age = 21;obj1.address.city ="shanghai";console.log(obj4.age);//20console.log(obj4.address.city);//shanghai//自定義深拷貝函數(shù)functiondeepCopy(obj) {? ? // obj 是 null 或者不是對象和數(shù)組拥坛,直接返回if(typeof obj !=='object'|| obj == null) {returnobj;? ? }? ? // 初始化返回結(jié)果letresult;if(obj instanceof Array) {? ? ? ? result = [];? ? }else{? ? ? ? result = {};? ? }for(letkeyinobj) {if(obj.hasOwnProperty(key)) {? ? ? ? ? ? result[key] = deepCopy(obj[key]);? ? ? ? }? ? }returnresult;}
本地對象
對內(nèi)的赔桌,供開發(fā)者使用
包裝類型對象 Boolean String Number
引用類型 Array Function Date Object RegExp Error
內(nèi)置對象
在腳本程序初始化時被創(chuàng)建供炎,不必實(shí)例化這兩個對象。
Global Math
基本包裝類型
在實(shí)際中每讀取一個基本數(shù)據(jù)值的時候疾党,后臺就會創(chuàng)建一個對應(yīng)的基本包裝類型對象音诫,從而讓我們能夠調(diào)用一些方法操作這些數(shù)據(jù)。
lets1 ="some text"; //值類型沒有方法雪位。lets2 = s1.substring(2);console.log(s1); //some textconsole.log(s2); //me text
引用類型與基本包裝類型的區(qū)別
它們的對象生命周期不同:
引用類型:使用new創(chuàng)建引用類型的實(shí)例竭钝,在執(zhí)行數(shù)據(jù)流離開當(dāng)前作用域時會一直存儲在內(nèi)存中。
基本包裝類型:自動創(chuàng)建基本包裝類型的對象雹洗,只執(zhí)行一行代碼的瞬間之后就會立即銷毀香罐。
這意味著在運(yùn)行時為基本包裝類型值添加屬性和方法是無效的。
lets1 ='some text';s1.color ='red';s1.color // undefined// 但是這樣是可以的lets1 = new String('some text');s1.color ='red';s1.color // red
不建議顯式的創(chuàng)建基本包裝類型的對象,因?yàn)樵诤芏鄷r候會造成一些讓人很迷惑的東西时肿。
letb = new Boolean(false); //b 這個變量就是 Boolean 對象letc = b &&true;console.log(c); //true
letstr ='hello'; // str 本質(zhì)上是一個原始值庇茫,并不存在 prototype 屬性console.log(typeof str); // stringconsole.log(str instanceof String); //false參考文章: https://segmentfault.com/a/11...
類型判斷
typeof
相較于JS基本數(shù)據(jù)類型少null多function。
console.log(typeof null); //objectconsole.log(typeof undefined); //undefinedconsole.log(typeof 123); //numberconsole.log(typeof"123"); //stringconsole.log(typeoftrue); //booleanconsole.log(typeoffunctiona() {}); //functionconsole.log(typeof [1, 2, 3]); //objectconsole.log(typeof {a:"a"}); //object
instanceof
確定原型指向關(guān)系螃成。只適用于對象旦签,因?yàn)橹殿愋蜎]有原型。
不能判斷一個對象實(shí)例具體屬于哪種類型寸宏。
leta = [];console.log(a instanceof Array);//trueconsole.log(a instanceof Object);//true
Object.prototype.toString.call()
Object 的原型方法,返回"[object type]"宁炫,其中type是對象的類型。
toString()調(diào)用null返回[object, Null]氮凝,undefined返回[object Undefined]羔巢。
無法識別自定義的對象類型。
console.log(Object.prototype.toString.call(123)); //[object Number]
functionoptc(obj) {returnObject.prototype.toString.call(obj).slice(8, -1);}console.log(optc(123)); //Numberconsole.log(optc('123')); //Stringconsole.log(optc(true)); //Booleanconsole.log(optc(undefined)); //Undefinedconsole.log(optc(null)); //Nullconsole.log(optc({})); //Objectconsole.log(optc([])); //Arrayconsole.log(optc(function() {})); //Functionconsole.log(optc(/\d/)); //RegExpconsole.log(optc(new Date())); //Date
constructor(構(gòu)造函數(shù))
利用構(gòu)造函數(shù)判斷數(shù)據(jù)類型罩阵。
對象的構(gòu)造函數(shù)名就是該數(shù)據(jù)類型竿秆。
除Null和Undefined外,所有的數(shù)據(jù)類型都是/可以轉(zhuǎn)化為對象稿壁,而如果是對象袍辞,就肯定有構(gòu)造函數(shù)。
functionA() {}leta = new A();console.log(a.constructor.toString()); //functionA() {}
總結(jié)
準(zhǔn)確判斷數(shù)據(jù)類型包括自定義的對象類型
functiondataType(data) {if(!data) { //判斷null常摧、undefinedreturnObject.prototype.toString.call(data).slice(8, -1);? ? }else{returndata.constructor.toString().match(/function\s*([^(]*)/)[1];? ? }}console.log(dataType(null)); //nullconsole.log(dataType(undefined)); //Undefinedconsole.log(dataType(123)); //Numberconsole.log(dataType([])); //ArrayfunctionPoint(x, y) {}console.log(dataType(new Point(1, 2))); //Point