1. 程式人生 > >javascript引用類型

javascript引用類型

eof rop array類 參數傳遞 等於 第一次 em1 indexof .com

對象的創立:
1.new構造法 var person = new object(); person.name = "qi";
2.對象字面量(首選) var person={name:"qi",age:22} //也可以 "name":"qi" 這裏的name會自動轉換為字符串
或者 var person={}; //等同於構造

.表示法與[]表示法
person.name person["name"] 除非必須使用變量訪問,否則通常使用.來訪問屬性

Array類型
ECMAScrip的數組與其他語言不同,其可以動態的改變長度,並且每個數組元素所存放的數據類型也可以互不相同
數組的創建:
var arr = new Array();
var arr = new Array(20);
var arr = new Array(‘red‘,‘green‘,‘blue‘);
也可以省略new
var arr = Array(‘red‘,‘green‘,‘blue‘);
當參數傳入數值時,則會構建指定項數的數組
當傳入的是非數值時,則會創建只包含這個值的的一項數組

數組字面量法,該方法不會調用構造函數 (最好是復數)
var colors = ["red","green","blue"];
var names = [];
使用索引來訪問數組
註意:
1.數組長度是可以變化的,允許在賦值時增加數組的長度
colors[3] = "brown"; //新增第四項
2.數組長度length不是只讀的,可以通過設置length來設定數組的長度(移除或者新增)
colors.length=2; //該colors[2] = undefined
或者 colors.length = 4; //多出來的項都是 undefined
或者 colors[colors.length] = "block"; //在末尾新增一項

Array.isArray(value) //檢測是不是數組
轉換方法:
所有對象都會有 toLocaleString()、toString()和valueOf()方法。
具體轉換如下(生成以,分割的字符串)
alert(colors.toString()); //red,green,blue,會調用每一項的toString方法
alert(colors.valueOf()); //red,green,blue 本身就返回一個數組
alert(colors); //red,green,blue

colors.toLocaleString(); 會調用每一項的toLocaleString() 方法。

 1 var
person1 = { 2 toLocaleString:function(){ 3 return "zhd" 4 } 5 toString:function(){ 6 return "qi"; 7 } 8 } 9 var person2 = { 10 toLocaleString:function(){ 11 return "zhd2" 12 } 13 toString:function(){ 14 return "qi2"; 15 } 16 } 17 var people = [person1,person2]; 18 alert(people.toString()); //qi,qi2 19 alert(people.toLocaleString()); //zhd,zhd2

join()方法, 默認會使用,進行隔開,join可以指定以某種分隔符分隔開
alert(colors.join("||")); // red||green||blue

使用數組模仿棧的特性
棧:線性數據結構,只在棧頂進行數據的進棧出棧操作,先進後出
var colors = new Array();
colors.push("red","green"); //推出兩項

var items = colors.pop(); // 取棧頂元素。而後出棧,對於傳統語言來講,
//數據出棧後,長度減1,javascript會自動將長度減少
//,同理,進棧也是
隊列:1.在尾部插入push元素,在頂部移除shift元素,與棧部分基本相同
2.使用unshift(在末尾移除)與pop(在頂部插入元素)組合,
可以將隊列反過來處理
數組排序:
默認的數組排序在對字符串排序時,容易出現混亂。例如:在升序排序中,
它會把"10"排在"5"的前面,因為 1 < 5,因此,必要時需要指定一個排序規則
例:

 1 var arr = [0,3,5,10,9];
 2 alert(arr.sort()); //錯亂的輸出 0,10,3,5,9
 3 function compare(value1,value2){
 4   if (value1 > value2) {
 5     return -1;
 6   } else if(value1 <value2){
 7     return 1;
 8   }else{
 9     return 0;
10   }  
11 }
12 alert(arr.sort(compare)); //正確的排序:0,3,5,9,10

在chrome v8引擎中,sort底層實現中,有一個參數可以指定需要調用的回調函數,
可以在該函數中指明規則,v8給出了兩種底層排序 InsertionSort 和 QuickSort
源碼地址:https://github.com/v8/v8/blob/master/src/js/array.js#L726
不同的js引擎,具體的sort算法也不會相同

數組的反轉函數 reverse();

數組的"拼接":concat
在使用concat方法中,它會將原來的數組進行復制,並將concat中的參數拼接在數組
的後面。如果參數為數組,那麽就會將參數數組的每一項“拼接”上數組上,如果參數
不是數組,那麽就會簡單的添加到數組的末尾
註意:原數組不變,拼接的只是一個復制出來的新數組
var colors = ["red","green","blue"];
var colors2 = colors.concat("yellow",["black","brown"]);

alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,brown

數組的截取:1.slice(start,end) 該方法可以在原有基礎的數組上,截取一部分成為一個新數組
slice只有一個參數時:截取從當前位置到數組末尾的所有項
兩個參數時,截取從第一個參數位置,
到第二個參數位置(不包括結束位置的項)的所有項
參數可以為負數,為負數時,基本等於從數組的末尾向前數參數所表示的位置
既:若數組有5項,slice(-2,-1)與slice(3,4)時一樣的

2.splice方法的使用:刪除 插入 替換
splice (start, deleteCount, [item1[, item2[, . . . [,itemN]]]])
刪除:只有前兩個參數時,數組從 start下標開始,刪除deleteCount 個元素
當參數只有start參數時,就是刪除 從start下標起至最後 的元素
插入:當deleteCount 均為0 的時候,在數組的start位置插入新的item元素。
替換:當deleteCount 不均為0 的時候,在數組的start位置開始,刪除deleteCount 個元素,
在從start位置插入新的item元素。

當參數 為負的時 則該參數規定的是從數組元素的尾部開始算起的位置 (-1 指的是 數組中倒數第一個元素, -2 指的是,數組中倒數第二個元素。)

splice(0,2); //原數組刪除數組的前兩項,返回前兩項
splice(2,0,"red")//原數組在第二項位置上添加新項red,返回0,沒有刪除將返回空數組
splice(2,1,"red")//原數組將第2項後面的1項替換為red,返回被替換的數據組成的數組

splice操作的原始數組,對原始數組進行splice將會改變原始數組的長度以及數據變化,相應的
splice方法返回的是被操作的數據組成的數組。

位置方法 indexOf()和lastIndexOf()
兩個參數:搜索項與查找起點的索引位置(可選)
返回搜索項的索引位置(未搜索到返回-1)
叠代方法:5個,每個叠代方法都已傳入一個方法(一套規則),使得數組中的每一項都執行一邊,返
回數組每一項執行方法後的邏輯值;
暫時省略 原書98頁
縮小方法:縮小範圍 省略 原書98頁

Date類型: var now = new Date();如果有參數,要根據參數創建對象,則參數只接受毫秒值
Date.parse() 將日期字符串轉化為毫秒,可以省略不寫,系統默認調用
Date.UTC();將日期字符串轉化為毫秒,例子:
//GMT 2000年1月1日 3時 0 分0秒0毫秒 (年月必須提供參數,其他默認為0,月從0開始)
var d = new Date(Data.UTC(2000,0,3,0));

如果構造函數第一個參數為數值,構造函數也可以這麽寫
var d = new Date(2000,0,3,0);

Date.now(); 返回調用這個方法的日期和時間的毫秒數
var start = Date.now();
doSomething();
var stop = Date.new();
return stop - start;

在不支持Date.new方法的瀏覽器中,可以使用“+”轉化為字符串也可以實現同樣的效果
var start = +Date.now();
doSomething();
var stop = +Date.new();
return stop - start;

日期可以直接比較大小,會默認比較毫秒數
日期的若幹getter/setter(可獲取/設置毫秒,年,月,日....) 原書102頁

正則表達式:原書103頁

function函數:實際上也是對象,每個函數都是function的實例,每個函數名實際上也是指向函數對象的指針
function sum(num1,num2){return num1+num2;};

var sum = function(num1,num2){return num1+num2;};
等價,調用時直接使用sum即可

由於函數名是一個指向函數對象的指針,因此一個函數可能會有很多函數名
var autosum = sum; //不帶(),是指函數指針而不是指這個函數對象
alert(autosum(10,10)); //20,即使將sum = null,autosum同樣起作用

沒有重載!!!因為沒有具體的方法簽名,而實際上,第二次聲明的函數會被看作第一次函數
聲明的引用
函數聲明與函數表達式:函數聲明即 function sum(){} 會被提前加載到執行環境中
而 var sum = function(){};則不會提前加載,在使用sum時,應該在該表達式的後面使用,否則會
出現 unexpecter identifier(意外的標識符)錯誤

作為值傳遞:函數名稱也可以作為值傳遞,因為本身就是一個變量。
即可以吧一個函數作為參數傳遞,也可以把函數的返回結果作為參數傳遞

1 function callSomeFunction(SomeFunction,SomeArgument){
2     return SomeFunction(SomeArgument);//傳入的函數可以在函數體裏面執行
3 }//要訪問函數的指針而不執行函數的話,就必須去掉函數的"()"

//同時也可以把一個函數寫在另一個函數裏面 例子

function createComparisonFunction(propertyName){
    return function(object1,object2){
        var value1 = object1[propertyName];
        var value1 = object2[propertyName];

        if(value1 < value2){
            return -1;
        }else if(value1 > value2){
            return 1;
        }else{
            return 0;
        }
    }; //不要忘了這個分號  作為return一條語句看待
}
var data = [{"Name":"zhd"},{"Name":"qi"}];
data.sort(createComparisonFunction("Name"));
alert(data[0].Name);  //zhd

函數內部屬性:兩個特殊對象 this,arguments
arguments包含所有傳入函數的參數,其中還有一個 callee的屬性,這是一個指針,指向擁有
這個arguments的函數。 目的:可以實現函數與代碼的解耦和關系
階乘例子解析:

function factorial(num){
    if(num < 1){
        return num;
    }else{
        //return num * factorial(num-1)  //第一種寫法
        return num * arguments.callee(num-1)  //第二種寫法
    }
}
//註意
var trueFactorial = factorial;//trueFactorial與factorial指向同一個function對象
factorial = function{
    return 0;    //factorial指向的函數被更改,那麽在階乘原階乘函數裏,如果使用
                //第一種寫法,那麽在調用trueFactorial時,它將不會返回正確的結果
                //因為在函數體階乘遞歸計算時調用了被更改的factorial而返回結果0
}
alert(trueFactorial(5)); //返回120  第一種寫法  返回 0

this:引用函數據以執行的環境對象 誰引用的,指向誰,如果沒有任何對象引用該函數(
即在全局環境中)那麽它會指向window對象

caller:保留調用當前函數的函數的引用,不能為該屬性賦值,如果是全局環境,則為null

1 function outer(){
2     inner();
3 }
4 funcion inner(){
5     alert(inner.caller);
6     alert(arguments.callee.caller); //解耦合
7 }
8 outer(); //返回outer的源碼,因為inner.caller指向了outer函數

函數的屬性與方法: 記住::::函數是對象!!!
每個函數都包含兩個屬性 length(函數的參數個數)和prototype(第六章細講)
包含兩個非繼承而來的方法 apply()和call(),都用在特殊特定作用域中調用函數,實際上等於
設置函數體this的值

apply() 接受兩個參數,第一個參數其中運行函數的作用域,
另一個參數是參數數組(可以是Array的實例,也可以是arguments對象)

 1 function sum(num1,num2){
 2     return num1+num2;
 3 }
 4 function callSum1(num1,num2){
 5     return sum.apply(this,arguments); //這個this指callSum1,指向最外面的函數    
 6 }
 7 function callSum2(num1,num2){
 8     return sum.apply(this,[num1,num2]);    
 9 }
10 alert(callSum1(10,10)); // 20
11 alert(callSum2(10,10)); // 

關於this的指向 http://www.cnblogs.com/pssp/p/5216085.html
call() 與apply作用相同,區別在於,第二個參數要一次列舉出來

1 functio callSum3(num1,num2){
2   return sum.call(this,num1,num2);
3 }



!!!apply和call最強大的地方 是擴充了函數賴以生存的作用域!!!

 1 window.color = "red";
 2 var o = {color:"blue"};
 3 function sayColor(){
 4     alert(this.color);
 5 }
 6 sayColor.call(this); // red this在這裏指window 在全局環境下執行
 7 sayColor.call(window); // red  同理
 8 sayColor.call(o); // blue  此時函數體內的this對象指向了o,實現了函數對象與o對象的解耦和
 9 
10 // var o = {
11 //     color:‘blue‘;
12 //     function sayColor(){
13 //         alert(this.color);
14 //     }
15 // }
16 //o.sayColor = sayColor;
17 //o.sayColor();
18 
19 //或者:
20 var o = {
21     color:‘blue‘,
22     sayColor:function (){
23         alert(this.color);
24     }
25  }
26 o.sayColor();


bind(); 將函數本身綁定在被傳入的參數上
var objectSayColor = sayColor.bind(o); //此時函數體內 this指向 參數 o
objectSayColor(); // blue 即使在全局環境中運行,也會返回blue

每個函數繼承的toString(),toLocaleString(),valueOf 都會返回函數代碼

  

javascript引用類型