第1章 原始類(lèi)型和引用類(lèi)型1.1 對(duì)象的兩種類(lèi)型:JavaScript使用一個(gè)變量對(duì)象追蹤變量的生存期,。原始類(lèi)型保存為簡(jiǎn)單的值,引用類(lèi)型則保存為對(duì)象,,其本質(zhì)是指向內(nèi)存位置的引用,。 1.2 原始類(lèi)型1..2.1 五種原始類(lèi)型:Boolean Number String Null Undefined 1.2.2 鑒別原始類(lèi)型使用typeof 操作符 console.log(typeof 10); //'number' console.log(typeof “123”); //“string” console.log(typeof true); //'boolean' console.log(typeof undefined); //'undefined' //null為特例,可通過(guò)和null值進(jìn)行比較判斷 console.log(typeof null); //'object' console.log(value===null); //true or false 1.3 引用類(lèi)型:1.3.1創(chuàng)建對(duì)象(實(shí)例化對(duì)象)使用new操作符 var object = new Object(); 該代碼實(shí)例化了一個(gè)通用對(duì)象,,并將它的引用保存在object中,。object變量實(shí)際上并不保存對(duì)象的實(shí)例,而是一個(gè)指向內(nèi)存中實(shí)際對(duì)象所在位置的指針(或者說(shuō)引用),。 1.3.2 引用對(duì)象解除解除引用的最佳手段是將對(duì)象變量置為null,。在不使用對(duì)象時(shí)將其引用解除,會(huì)讓垃圾收集器對(duì)那塊內(nèi)存進(jìn)行釋放,。 var object1 = new Object(); //doing something object = null; 1.3.3 六種內(nèi)建類(lèi)型:Object Array Function Date RegExp Error 內(nèi)建類(lèi)型實(shí)例化 使用new操作符來(lái)實(shí)例化每一個(gè)內(nèi)建引用類(lèi)型: var object = new Object(); var items = new Array(); var func = new Function('console.log('hi');'); //稱(chēng)為構(gòu)造函數(shù) var now = new Date(); var re = new RegExp('\\d+'); var error = new Error('something bad happened.'); 字面形式,,字面形式允許不使用new操作符和構(gòu)造函數(shù)顯示創(chuàng)建對(duì)象的情況下生成引用值。 //對(duì)象字面形式 var person = { name:'liang', sayName:function(){ return this.name; } }; person.year = 1992; //添加對(duì)象的屬性 var items = ['item1','item2','item3']; //函數(shù)字面形式,,函數(shù)聲明 function func(value){ return value; } //函數(shù)字面形式,,函數(shù)表達(dá)式(匿名函數(shù)) var func = function(){ statement; }; //正則表達(dá)式字面形式 var numbers = /\d+/g; 1.3.4 訪問(wèn)屬性var array = []; array.push(123); //使用點(diǎn)號(hào) array['push'](456); //使用中括號(hào) //中括號(hào)允許使用動(dòng)態(tài)訪問(wèn)方法 var method = 'push'; array[method](789); 點(diǎn)號(hào)更易讀,但使用中括號(hào)可允許你在屬性名字上使用特殊字符,。 1.3.5 鑒別引用類(lèi)型對(duì)于函數(shù),,typeof 操作符返回“function”; 其他非函數(shù)的引用類(lèi)型,,typeof 操作符都返回“object”,。因此,使用instanceof 操作符來(lái)區(qū)分其他引用類(lèi)型,。 instanceof 操作符以一個(gè)對(duì)象和一個(gè)構(gòu)造函數(shù)為參數(shù),。如果對(duì)象是構(gòu)造函數(shù)所指定的類(lèi)型的一個(gè)實(shí)例,,instanceof 返回true;否則返回false,。 var items = []; var object = {}; function reflect(){ return value; } console.log(typeof reflect); //'function' console.log(items instanceof Array); //true console.log(object instanceof Object); //true console.log(reflect instanceof Function); //true //這些引用類(lèi)型也都是Object的實(shí)例,,instanceof 操作符可鑒別繼承類(lèi)型。 console.log(items instanceof Object); //true console.log(reflect instanceof Object); //true 1.3.6 鑒別數(shù)組instanceof 可以鑒別數(shù)組,,但有一個(gè)例外,,當(dāng)你把一個(gè)數(shù)組從一個(gè)框架傳到另一個(gè)框架時(shí),instanceof 就無(wú)法識(shí)別,,因?yàn)檫@個(gè)數(shù)組是來(lái)自不同框架的Array的實(shí)例,。 使用Array.isArray()鑒別數(shù)組,IE8及更早版本不支持,。 var items = []; console.log(Aray.isArray(items)); //true 1.4 原始封裝類(lèi)型原始封裝類(lèi)型共有3種(String, Number 和 Boolean),。 當(dāng)讀取字符串、數(shù)字或布爾值時(shí),,原始封裝類(lèi)型將被自動(dòng)創(chuàng)建,。這種特殊引用類(lèi)型的存在使得原始類(lèi)型用起來(lái)和對(duì)象一樣方便。 //第二行代碼把name當(dāng)成一個(gè)對(duì)象,,調(diào)用了charAt方法 var name = 'liang'; var firstChar = name.charAt(0); console.log(firstChar); //'l' /* 背后的工作原理:創(chuàng)建了一個(gè)臨時(shí)對(duì)象,,隨后被銷(xiāo)毀 var name = 'liang'; var temp = new String(name); var firstChar = temp.charAt(0); temp = null; console.log(firstChar); //'l' */ //臨時(shí)對(duì)象僅在值被讀取時(shí)創(chuàng)建,instanceof并沒(méi)有真的讀取任何東西,,因此為false console.log(typeof name); //string console.log(name instanceof String); //false 第2章 函數(shù)函數(shù)其實(shí)就是對(duì)象,。使函數(shù)不同于其他對(duì)象的決定性特點(diǎn)是函數(shù)存在一個(gè)被稱(chēng)為[[call]]的內(nèi)部屬性。 內(nèi)部屬性無(wú)法通過(guò)代碼訪問(wèn),,它定義了代碼執(zhí)行時(shí)的行為,。 [[call]]是函數(shù)獨(dú)有的,表明該對(duì)象可以被執(zhí)行,。 2.1 聲明還是表達(dá)式函數(shù)有兩種字面形式,。第一種以function關(guān)鍵字開(kāi)頭,后面跟著函數(shù)的名字,。第二種是函數(shù)表達(dá)式,,function后面不需要跟著函數(shù)名,這種函數(shù)被稱(chēng)為匿名函數(shù),。 //函數(shù)聲明 function add(num1,num2){ return num1 + num2; } //函數(shù)表達(dá)式 var push = function(num1,num2){ return num1 + num2; }; 兩者中最重要的區(qū)別是,,函數(shù)聲明會(huì)被提升至上下文的頂部。意味著可以先使用函數(shù),,后聲明,。 而函數(shù)表達(dá)式是通過(guò)變量引用,因此無(wú)法提升。 var sum = add(3,5); function add(num1,num2){ return num1 + num2; } 2.2 函數(shù)就是值記住函數(shù)就是對(duì)象,,可以將函數(shù)當(dāng)成參數(shù)傳遞給其他的函數(shù),。 比如數(shù)組的sort()方法,接受一個(gè)比較函數(shù)作為可選參數(shù),。 在默認(rèn)情況下,,sort()將數(shù)組中每個(gè)對(duì)象轉(zhuǎn)換成字符串然后進(jìn)行比較。 var numbers = [1,6,3,7,2,10]; numbers.sort(function(num1,num2){ return num1 - num2; }); console.log(numbers); //[1, 2, 3, 6, 7, 10] numbers.sort(); console.log(numbers); //[1, 10, 2, 3, 6, 7] 2.3 參數(shù)函數(shù)參數(shù)實(shí)際上被保存在一個(gè)被稱(chēng)為arguments類(lèi)似于數(shù)組的對(duì)象中,。 var reflect = function(){ return arguments[1]; }; console.log(reflect('first','second')); //second console.log(reflect.length); //'0' 應(yīng)盡量避免使用argument。不過(guò),,在某些情況下使用arguments比名稱(chēng)參數(shù)有效,。例如,創(chuàng)建一個(gè)函數(shù),,可以接受任意數(shù)量的參數(shù),,并返回它們的和。 function sum(){ var i = 0, result = 0, len = arguments.length; while (i < len){ result += arguments[i]; i++; } return result; } console.log(sum(3,5,1)); //9 console.log(sum(1,2,3,4)); //10 console.log(sum()); //0 //由于result的初始值為0,,改函數(shù)就算沒(méi)有參數(shù)也能正常工作 2.4 重載大多數(shù)面向?qū)ο笳Z(yǔ)言支持函數(shù)重載,,它能讓一個(gè)函數(shù)具有多個(gè)簽名。 函數(shù)簽名由函數(shù)的名字,、參數(shù)的個(gè)數(shù)及其類(lèi)型組成,。 JavaScript并沒(méi)有簽名,但可以模仿函數(shù)重載,。用arguments對(duì)象獲取傳入的參數(shù)個(gè)數(shù)并決定怎么處理,。 function sayMessage(message){ if (arguments.length === 0){ message = 'Default message'; } console.log(message); } sayMessage('Hello'); //Hello sayMessage(); //Default message 2.5 對(duì)象方法對(duì)象的屬性的值是函數(shù),則該屬性被稱(chēng)為方法,。 2.5.1 this對(duì)象JavaScript所有函數(shù)作用域內(nèi)都有一個(gè)this對(duì)象代表調(diào)用該函數(shù)的對(duì)象,。在全局作用域中,代表全局對(duì)象,。 function sayNameForAll(){ console.log(this.name); } var person1 = { name: 'liang', sayName: sayNameForAll }; var person2= { name: 'zhu', sayName: sayNameForAll }; person1.sayName(); //liang person2.sayName(); //zhu 2.5.2 改變thiscall() 方法 call() 的第一個(gè)參數(shù)指定了函數(shù)執(zhí)行時(shí)this的值,,其后的所有參數(shù)(可選)都是需要被傳入函數(shù)的參數(shù)。 function sayNameForAll(){ console.log(this.name); } function sayName(a){ console.log(a + ': '+this.name); } var person1= { name: 'liang' }; var person2= { name: 'zhu' } sayNameForAll.call(person1); //liang sayName.call(person1,'name'); //name: liang apply() 方法 apply() 方法的工作方式和call()完全一樣,,但它只接受兩個(gè)參數(shù):this的值,、一個(gè)數(shù)組(或者類(lèi)似數(shù)組的對(duì)象,內(nèi)含需要被傳入函數(shù)的參數(shù)),。 function sayNameForAll(a){ console.log(a + ': ' + this.name); } var person1 = { name: 'liang' }; var person2 = { name: 'zhu' }; sayNameForAll.apply(person1,['person']); //person: liang var array = [1,2,3,4]; sayNameForAll.apply(person2,array); //1: zhu sayNameForAll.apply(person2,array[2]); //error bind() 方法 bind() 的第一個(gè)參數(shù)是要傳給新函數(shù)的this的值,。其他所有參數(shù)代表需要被永久設(shè)置在新函數(shù)中的命名參數(shù)??梢栽谥罄^續(xù)設(shè)置任何非永久參數(shù),。 function sayName(a){ console.log(a + ': ' + this.name); } var person1 = { name: 'liang' }; var person2= { name: 'zhu' }; //綁定this,并傳入?yún)?shù) var sayPerson1 = sayName.bind(person1,'person'); sayPerson1(); //person: liang //僅綁定this var sayPerson2 = sayName.bind(person2); sayPerson2(); //undefined: zhu sayPerson2('person'); //person: zhu |
|
來(lái)自: 佬總圖書(shū)館 > 《編程》