JavaScript 學習筆記 02 (引用資料型別)
一、基本資料型別和引用數型別
基本資料型別:Undefined、Null、Boolean、Number和String
引用資料型別:Object
基本型別指的是簡單的資料段、引用型別值的是可能由多個值構成的物件。
1、複製變數值
一個變數複製另一個變數的值,如果被複制的變數是基本型別的值,則會建立一個新的基本型別,然後把該值分配到新變數上。此時改變其中一個變數,不會影響另外一個變數。例如:
var num1 = 5 var num2 = num1
num1 = 6
alert(num2) // 5
一個變數複製另一個變數的值,如果被複制的變數是引用型別的值,則會把儲存在變數物件中的值複製一份放到新分配的變數中。不同的是複製的其實是一個指標,指標指向的是儲存在堆中的一個物件。複製結束後兩個變數將指向同一個物件。因此改變其中一個變數,會影響另外一個變數。例如:
var obj1 = new Object() var obj2 = obj1 obj1.name = "Hi" alert(obj2.name) // 'Hi'
2、傳遞引數
ECMAScript 中所有函式的引數都是按照值傳遞的。也就是說,把函式外部的值複製給函式內部的引數,就和把值從一個變數複製到另外一個變數一樣。基本型別會複製一份值賦值給函式的引數,引用型別會複製一份指標地址賦值給函式的引數。
基本型別:
function addTen( num ) { num += 10 return num } var count = 20 var result = addTen(count) alert(count)// 20 沒有變化 alert(result) //30
引用型別:
function setName( obj ) { obj.name = "Hi" } var person = new Object() setName(person) alert(person.name) // "Hi"
二、引用型別
引用型別具體有哪些。
1、Object 型別
建立有兩種基本方法
一是使用 new 操作符後跟 Object 建構函式
var person = new Object() person.name = "Hi" person.age = 29
二是使用物件字面量表示法。物件字面量是物件定義的一種簡化形式,目的在於簡化建立包含大量屬性的物件的過程,更常用的是這種方法。
var person = { name : "Hi", age: 29 }
2、Array 型別
除了 Object 型別之外,最常用的就是 Array 型別。
建立有兩種基本方法
一是使用 new 操作符後跟 Array 建構函式
var colors = new Array() var colors = new Array(20) // 建立一個長度為20的陣列 var colors = new Array("red","blue","green") // 建立包含三個字串值的陣列
二是使用陣列字面量表示法
var colors = [] var colors = ["red","blue","green"]
1、檢測陣列
使用 Array.isArray() 方法檢測某個值到底是不是陣列。
if ( Array.isArray( value) ){ // 對陣列執行某些操作 }
2、常用方法
var colors = ["red","green","blue"] alert(colors.toSring()) // "red,green,blue" 轉換成字串輸出 alert(colors.join("||") // "red||green||blue" 轉換成字串輸出,並且指定分隔符 ,如果不傳預設是逗號 // push() 方法可以接收任意數量的引數,把它們逐個新增到陣列末尾,並且返回修改後的陣列長度 var count = colors.push("a","b") alert(count) // 5 因為現在colors陣列是 ["red","green","blue","a","b"] // pop() 方法移除陣列最後一項,並且返回該項 var item = colors.pop() alert(item) // "b" alert(colors.length) // 4 // shift() 方法移除陣列的第一項,並且返回該項 var item2 = colors.shift() alert(item2) // "red" alert(colors.length) //3 // unshift() 方法可以從陣列第一項新增值,並且返回陣列的長度 var count2 = colors.unshift("red") alert(count2) // 4 alert(colors) // ["red","green","blue","a"]
var values = [1,2,3,4,5] // reverse() 方法可以翻轉陣列 values.reverse() // [5,4,3,2,1] var values = [0,1,5,10,15] // sort() 方法會根據字串比較排序,字串中“10”在“5”之前 values.sort() // [0, 1, 10, 15, 5] // sort() 方法會接收一個比較函式作為引數,方便自己定義某種排序方式。 // 比較函式接收兩個引數,如果第一個引數應該位於第二個之前則應該返回一個負數,如果兩個引數相等則返回0,如果第一個引數應該位於第二個之後則返回一個整數。 function compare(value1, value2 ) { if ( value1 < value2 ) { return -1 } else if ( value1 > value2 ) { return 1 } else { return 0 } } values.sort(compare) // [0,1,5,10,15]
var colors = ["a","b","c","d","e"] // slice() 方法可以基於當前陣列建立一個新的陣列。該方法接收一個或者兩個引數。如果只有一個引數表示從指定的位置到陣列末尾。如果有兩個引數表示從起始和結束的位置。 var colors2 = colors.slice(1) // ["b","c","d","e"] var colors3 = colors.slice(1,3) // ["b","c"] var colors4 = colors.slice(2,-1) // ["c", "d"] // splice() 方法可以刪除、插入、替換,第一個引數為開始變化的位置,第二個引數表示刪除到某個位置,如果為0則表示不刪除。之後的引數表示要新增的引數 var colors = ["a","b","c"] var removed = colors.splice(0,1) // 刪除第一項 ["a"] 此時colors為 ["b","c"] var removed = colors.splice(1,0,"d","e") // 從位置1開始插入兩項,此時colors為 ["b", "d", "e", "c"] var removed = colors.splice(1,1,"f","g") // 從位置1刪除一項,插入兩項 此時 colors 為 ["b", "f", "g", "e", "c"]
var numbers = [1,2,3,4,5,4,3,2,1] // indexOf() 方法接收兩個引數:要查詢的項和表示查詢起點位置的索引(如果省略了則表示從頭開始),如果未找到返回-1 // lastIndexOf() 和indexOf() 方法類似,但是是從末尾開始向前找。 numbers.indexOf(4) // 3 numbers.indexOf(4,4) // 5 numbers.lastIndexOf(4) //5 numbers.lastIndexOf(4,4) //3
幾個迭代方法
// every():對陣列中的每一項執行給定的函式,如果該函式對每一項都返回true,則返回 true // some():對陣列中的每一項執行給定的函式,如果該函式對任一項返回true,則返回true // filter():對陣列中的每一項執行給定的函式,返回該函式返回true的項組成的陣列。 // forEach(): 對陣列中的每一項執行給定的函式,這個方法沒有返回值。 // map():對陣列中的每一項執行給定的函式,返回每次函式呼叫的結果組成的陣列。 // 每個方法都接受兩個引數:要在每一項上執行的函式和執行該函式的作用域物件(影響this的值,可省略) var numbers = [1,2,3,4,5,4,3,2,1] var everyResult = numbers.every(function( item, index, array ){ return item > 2 }) alert(everyResult) // false var someResult = numbers.some(function( item, index, array ){ return item > 2 }) alert(someResult) // true var filterResult = numbers.filter(function( item, index, array ){ return item > 2 }) alter(filterResult) // [3,4,5,4,3] var mapResult = numbers.map(function( item, index, array ){ return item * 2 }) alter(mapResult) // [2,4,6,8,10,8,6,4,2] numbers.forEach(function( item, index, array ){ // 執行某些操作 })
縮小方法
// reduce() 方法會迭代陣列的所有項,然後構建一個最終的返回值 var values = [1,2,3,4,5] var sum = values.reduce(function(prev, cur, index, array){ return prev + cur }) alert(sum) // 15
3、Date 型別
Date 型別的數其實是毫秒級的時間戳
// 取得開始時間 var start = Date.now() // 呼叫函式做事情 doSomething() // 取得結束時間 var stop = Date.now() // 花費的時間 result = stop - start
4、Function 型別
每個函式都是 Function 型別的例項,而且都與其他引用型別一樣具有屬性和方法。由於函式是物件,因此函式名實際上也是一個指向函式物件的指標,不會與某個函式繫結。
函式通常是使用函式宣告語法定義的,和函式表示式定義函式的方式一樣。
// 函式宣告語法 function sum ( num1, num2 ) { return num1 + num2 } // 函式表示式 var sum = function ( num1, num2 ) { return num1 + num2 }
1、沒有過載
宣告兩個同名函式,其實是後面的函式覆蓋了前面的函式。
function addSomeNumber(num){ return num + 100 } function addSomeNumber(num){ return num + 200 } var result = addSomeNumber(100) // 300
2、函式宣告與函式表示式
在定義一個函式的時候,使用函式宣告和函式表示式還是會有細微的差別。
alert(sum(10,10)) function sum(num1, num2) { return num1 + num2 }
上面例子中的程式碼可以正常執行,因為在程式碼執行之前,已經通過一個名為函式宣告提升的過程,讀取並且將函式宣告新增到執行環境中。下面函式表示式的寫法就會報錯。
alert(sum(10,10)) var sum = function (num1, num2) { return num1 + num2 }