這裏有一份簡潔的前端知識體系等待你查收,看看吧,會有驚喜哦~若是以爲不錯,懇求star哈~前端
原始類型 保存爲簡單數據值。 引用類型 保存爲對象,其本質是指向內存位置的引用。git
爲了讓開發者可以把原始類型和引用類型按相同的方式處理,JavaScript 花費了很大的努力來保證語言的一致性。github
其餘編程語言用棧存原始類型,用對存儲引用類型。正則表達式
而 JavaScript 則徹底不一樣:它使用一個變量對象追蹤變量的生存期。編程
原始值被直接保存在變量對象內,而引用值則做爲一個指針保存在變量對象內,該指針指向實際對象在內存中的存儲位置。數組
原始類型表明照原樣保存的一些簡單數據。app
JavaScript 共有5種原始類型:框架
true
or false
JavaScript 和許多其餘語言同樣,原始類型的變量直接保存原始值(而不是一個指向對象的指針)。編程語言
var color1 = "red";
var color2 = color1;
console.log(color1); // "red"
console.log(color2); // "red"
color1 = "blue";
console.log(color1); // "blue"
console.log(color2); // "red"
複製代碼
鑑別原始類型的最佳方式是使用 typeof
操做符。函數
console.log(typeof "Nicholas"); // "string"
console.log(typeof 10); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
複製代碼
至於空類型(null)則有些棘手。
console.log(typeof null); // "object"
複製代碼
對於 typeof null,結果是"object"。(其實這已被設計和維護 JavaScript 的委員會 TC39 認定是一個錯誤。在邏輯上,你能夠認爲 null
是一個空的對象指針,因此結果爲"object",但這仍是很使人困惑。)
判斷一個值是否爲空類型(null)的最佳方式是直接和 null
比較:
console.log(value === null); // true or false
複製代碼
注意:以上這段代碼使用了三等號(全等 ===),由於三等號(全等)不會將變量強制轉換爲另外一種類型。
console.log("5" == 5); // true
console.log("5" === 5); // false
console.log(undefined == null); // true
console.log(undefined === null); // false
複製代碼
雖然字符串、數字和布爾值是原始類型,可是它們也擁有方法(null 和 undefined 沒有方法)。
var name = "Nicholas";
var lowercaseName = name.toLowerCase(); // 轉爲小寫
var count = 10;
var fixedCount = count.toFixed(2); // 轉爲10.00
var flag = true;
var stringFlag = flag.toString(); // 轉爲"true"
console.log("YIBU".charAt(0)); // 輸出"Y"
複製代碼
儘管原始類型擁有方法,但它們不是對象。JavaScript 使它們看上去像對象同樣,以此來提升語言上的一致性體驗。
引用類型是指 JavaScript 中的對象,同時也是你在該語言中能找到最接近類的東西。
引用值是引用類型的實例,也是對象的同義詞(後面將用對象指代引用值)。
對象是屬性的無序列表。屬性包含鍵(始終是字符串)和值。若是一個屬性的值是函數,它就被稱爲方法。
除了函數能夠運行之外,一個包含數組的屬性和一個包含函數的屬性沒有什麼區別。
有時候,把 JavaScript 對象想象成哈希表能夠幫助你更好地理解對象結構。
JavaScript 有好幾種方法能夠建立對象,或者說實例化對象。第一種是使用 new
操做符和構造函數。
構造函數就是經過 new
操做符來建立對象的函數——任何函數均可以是構造函數。根據命名規範,JavaScript 中的構造函數用首字母大寫來跟非構造函數進行區分。
var object = new Object();
複製代碼
由於引用類型再也不變量中直接保存對象,因此本例中的 object
變量實際上並不包含對象的實例,而是一個指向內存中實際對象所在位置的指針(或者說引用)。這是對象和原始值之間的一個基本差異,原始值是直接保存在變量中。
當你將一個對象賦值給變量時,實際是賦值給這個變量一個指針。這意味着,將一個變量賦值給另一個變量時,兩個變量各得到了一份指針的拷貝,指向內存中的同一個對象。
var obj1 = new Object();
var obj2 = obj1;
複製代碼
JavaScript 語言有垃圾收集的功能,所以當你使用引用類型時無需擔憂內存分配。但最好在不使用對象時將其引用解除,讓垃圾收集器對那塊內存進行釋放。解除引用的最佳手段是將對象變量設置爲 null
。
var obj1 = new Object();
// dosomething
obj1 = null; // dereference
複製代碼
在 JavaScript 中,你能夠隨時添加和刪除其屬性。
var obj1 = new Object();
var obj2 = obj1;
obj1.myCustomProperty = "Awsome!";
console.log(obj2.myCustomProperty); // "Awsome!" 由於 obj1 和 obj2 指向同一個對象。
複製代碼
內建類型以下:
可以使用 new
來實例化每個內建引用類型:
var items = new Array();
var now = new Date();
var error = new Error("Something bad happened.");
var func = new Function("console.log('HI');");
var object = new Object();
var re = new RegExp();
複製代碼
內建引用類型有字面形式。字面形式容許你在不須要使用 new
操做符和構造函數顯示建立對象的狀況下生成引用值。屬性的鍵能夠是標識符或字符串(若含有空格或其餘特殊字符)
var book = {
name: "Book_name",
year: 2016
}
複製代碼
上面代碼與下面這段代碼等價:
var book = new Object();
book.name = "Book_name";
book.year = 2016;
複製代碼
雖然使用字面形式並無調用 new Object(),可是 JavaScript 引擎背後作的工做和 new Object() 同樣,除了沒有調用構造函數。其餘引用類型的字面形式也是如此。
可經過 .
和 中括號
訪問對象的屬性。 中括號 []
在須要動態決定訪問哪一個屬性時,特別有用。由於你能夠用變量而不是字符串字面形式來指定訪問的屬性。
函數是最容易鑑別的引用類型,由於對函數使用 typeof
操做符時,返回"function"。
function reflect(value){
return value;
}
console.log(typeof reflect); // "function"
複製代碼
對其餘引用類型的鑑別則較爲棘手,由於對於全部非函數的引用類型,typeof
返回 object
。爲了更方便地鑑別引用類型,可使用 JavaScript 的 instanceof
操做符。
var items = [];
var obj = {};
function reflect(value){
return value;
}
console.log(items instanceof Array); // true;
console.log(obj instanceof Object); // true;
console.log(reflect instanceof Function); // true;
複製代碼
instanceof
操做符可鑑別繼承類型。這意味着全部對象都是 Oject
的實例,由於全部引用類型都繼承自 Object
。
雖然 instanceof 能夠鑑別對象類型(如數組),可是有一個列外。JavaScript 的值能夠在同一個網頁的不用框架之間傳來傳去。因爲每一個網頁擁有它本身的全局上下文—— Object、Array 以及其餘內建類型的版本。因此當你把一個對象(如數組)從一個框架傳到另一個框架時,instanceof 就沒法識別它。
原始封裝類型有 3
種:String、Number 和 Boolean。 當讀取字符串、數字或布爾值時,原始封裝類型將被自動建立。
var name = "Nicholas";
var firstChar = name.charAt(0); // "N"
複製代碼
這在背後發生的事情以下:
var name = "Nichola";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
複製代碼
因爲第二行把字符串當成對象使用,JavaScript 引擎建立了一個字符串的實體讓 charAt(0)
能夠工做。字符串對象的存在僅用於該語句並在隨後銷燬(一種被稱爲自動打包的過程)。爲了測試這一點,試着給字符串添加一個屬性看看它是否是對象。
var name = "Nicholas";
name.last = "Zakas";
console.log(name.last); // undefined;
複製代碼
下面是在 JavaScript 引擎中實際發生的事情:
var name = "Nicholas";
var temp = new String(name);
temp.last = "Zakas";
temp = null; // temporary object destroyed
var temp = new String(name);
console.log(temp.last);
temp = null;
複製代碼
新屬性 last
其實是在一個馬上就被銷燬的臨時對象上而不是字符串上添加。以後當你試圖訪問該屬性時,另外一個不一樣的臨時對象被建立,而新屬性並不存在。
雖然原始封裝類型會被自動建立,在這些值上進行 instanceof
檢查對應類型的返回值倒是 false
。 這是由於臨時對象僅在值被讀取時建立。instanceof
操做符並無真的讀取任何東西,也就沒有臨時對象的建立。
固然你也能夠手動建立原始封裝類型。
var str = new String("me");
str.age = 18;
console.log(typeof str); // object
console.log(str.age); // 18
複製代碼
如你所見,手動建立原始封裝類型實際會建立出一個 object
。這意味着 typeof
沒法鑑別出你實際保存的數據的類型。
另外,手動建立原始封裝類型和使用原始值是有必定區別的。因此儘可能避免使用。
var found = new Boolean(false);
if(found){
console.log("Found"); // 執行到了,儘管對象的值爲 false
}
複製代碼
這是由於一個對象(如 {}
)在條件判斷語句中總被認爲是 true
;
第一章的東西都是咱們一些比較熟悉的知識。可是也有一些須要注意的地方:
5
種原始類型均可以用 typeof 來鑑別,而空類型必須直接跟 null
進行全等比較。typeof
鑑別。其它引用類型,可用 instanceof
和一個構造函數來鑑別。(固然能夠用 Object.prototype.toString.call()
鑑別,它會返回 [object Array]之類的)。3
種封裝類型。JavaScript會在背後建立這些對象使得你可以像使用普通對象那樣使用原始值。但這些臨時對象在使用它們的語句結束時就馬上被銷燬。雖然可手動建立,但不建議。