JavaScript學習總結(二)陣列和物件部分

trigkit4發表於2016-09-16

物件部分

Object型別

Object 是一個無序的集合,可以存放任意型別物件,所有其他物件都繼承自這個物件。

建立Object型別有兩種,一種是使用new運算子,一種是字面量表示法。

1.使用new運算子建立Object

var obj = new Object();//注意大寫,也可以直接寫成Object()

注意,通過new Object() 的寫法生成新物件,與字面量的寫法 obj = {} 是等價的。

2. 使用字面量方式建立:

var obj = {
    name : 'trigkit4',
    age : 21
};//分號最好加上

在使用字面量宣告Object物件時,不會呼叫Object()建構函式(FF除外)

Object.prototype物件

所有建構函式都有一個prototype屬性,指向一個原型物件。

Object.prototype.print = function(){ console.log(this)};

var obj = new Object();

obj.print() // Object

例項obj直接繼承了Object.prototype的屬性和方法

1.物件只是一種特殊的資料。物件擁有屬性和方法。 JavaScript 是物件導向的語言,但 JavaScript 不使用類。 JavaScript 基於 [prototype][1],而不是基於類的。

2.屬性:是隸屬於某個特定物件的變數。方法:是隻有某個特定物件才能呼叫的函式。

3.js物件是屬性和方法的集合。一個方法就是一個函式,是物件的成員。屬性是一個值或一組值(以陣列或物件的形式),是物件的成員。

4.js物件是基於構造器函式的,使用構造器函式建立一個新物件時,就可以說是例項化了一個新物件。屬性是構造器函式內部的變數。

使用構造器函式例項化的物件:

cat = new Animal();

Javascript是一種基於物件(object-based)的語言,你遇到的所有東西幾乎都是物件。但是,它又不是一種真正的物件導向程式設計(OOP)語言,因為它的語法中沒有class(類)。

<script type="text/javascript">
    //物件是名/值對的集合
        var browser = {        //物件是由花括號括起來的
            name:"Firefox",
            kernel:"Gecko"
        };
</script>
 //通過點號(.)或“[]”來訪問物件的屬性
    browser.name         //"Firefox"
    browser["kernel"]    //"Gecko"

物件(objct)是屬性(property)的集合,每個屬性都由“名/值對”構成,js同樣定義了一個特殊的物件——陣列,它是帶有編號的值的有序集合。

js還定義了一個特殊的物件——函式,函式是具有與他相關聯的可執行程式碼的物件,通過呼叫函式來執行程式碼,並返回運算結果。

JS中沒有類][3,但是它取了一個新的名字叫“原型物件”,因此"類==原型物件",詳情見:JavaScript類的寫法(一)

二:類(原型物件)和物件(例項)的區別與聯絡

1.類(原型物件)是抽象,是概念的,代表一類事物。
2.物件是具體的,實際的,代表一個具體的事物。
3.類(原型物件)是物件例項的模板,物件例項是類的一個個體。

一個常見的誤解是數字的字面值(literal)不是物件。這是因為 JavaScript 解析器的一個錯誤,它試圖將點操作符解析為浮點數字面值的一部分。

有很多變通方法可以讓數字的字面值看起來像物件。

2..toString(); // 第二個點號可以正常解析
2 .toString(); // 注意點號前面的空格
(2).toString(); // 2先被計算

刪除屬性

刪除屬性的唯一方法是使用 delete 操作符;設定屬性為 undefined 或者 null 並不能真正的刪除屬性,而僅僅是移除了屬性和值的關聯。

JavaScript物件導向三大特徵

封裝:不考慮內部實現,只考慮功能使用
繼承:從已有物件上,繼承出新的物件
多型:所謂多型,就是指一個引用在不同情況下的多種狀態,

1.封裝

封裝就是要把屬於同一類事物的共性(包括屬性與行為)歸到一個類中,以方便使用.比如人這個東東,可用下面的方式封裝:

人{

年齡(屬性一)
身高(屬性二)
性別(屬性三)

做事(行為之一)
走路(行為之二)
說話(行為之三)

}

封裝的好處:

封裝保護了內部資料的完整性;
封裝使物件的重構更輕鬆;
弱化模組間的耦合,提高物件的可重用性;
有助於避免名稱空間衝突;

看下面一個例子:

 <script type="text/javascript">  
            var boy = {}; //建立一個空物件
                    boy.name = "小明";//按照原型物件的屬性賦值
                    boy.age = 12;

            var girl = {};
                    girl.name = "小紅";
                    girl.age = 10;
    </script>

這就是最簡單的封裝了,把兩個屬性封裝在一個物件裡面。但是,這樣的寫法有兩個缺點,一是如果多生成幾個例項,寫起來就非常麻煩;二是例項與原型之間,沒有任何辦法,可以看出有什麼聯絡。

建構函式模式

為了解決從原型物件生成例項的問題,Javascript提供了一個建構函式(Constructor)模式。

所謂"建構函式",其實就是一個普通函式,但是內部使用了this變數。對建構函式使用new運算子,就能生成例項,並且this變數會繫結在例項物件上。

比如boygirl的原型物件現在就可以這樣寫:

<script type="text/javascript">  
        function Person(name,age){
                this.name = name;
                this.age = age;
        }
</script>

我們現在就可以生成例項物件了。

<script type="text/javascript">  
        var boy = new Person("小明",12);
        var girl = new Person("小紅",10);

        alert(boy.name);  //小明
        alert(boy.age);   //12
</script>

這時boygirl會自動含有一個constructor屬性,指向它們的建構函式。

alert(boy.constructor == Person); //true

alert(girl.constructor); //輸出整串建構函式程式碼,自己試試吧

Prototype模式 Javascript規定,每一個建構函式都有一個prototype屬性,指向另一個物件。這個物件的所有屬性和方法,都會被建構函式的例項繼承。

這意味著,我們可以把那些不變的屬性和方法,直接定義在prototype物件上。

<script type="text/javascript">
function Person(name,age){
        this.name = name;
        this.age = age;
}

Person.protype.type = "人類";

Person.protype.eat = function(){
        alert("吃米飯");
}
</script>

然後,生成例項:

<script type="text/javascript">
var boy = new Person("小明","12");
var girl = new Person("小紅","10");

alert(boy.type);//人類
boy.eat();//吃飯
</script>

這時所有例項的type屬性和eat()方法,其實都是同一個記憶體地址,指向prototype物件,因此就提高了執行效率。

alert(boy.eat == girl.eat); //true

原型屬性是一個內建屬性,它指定了物件所擴充套件的構造器函式。
下面的程式碼為Animal構造器函式新增一個新的屬性size,這個新屬性是cat物件的原型屬性。通過使用原型屬性,所有擴充套件Animal構造器函式的物件就可以訪問size屬性

cat = new Animal("feline","meow", "walk/run");
cat.prototype.size = "fat";

在這種情況下,所有的Animal物件的size屬性都是“fat”。原型預設為Object的新例項, 由於仍是物件, 故可以給該物件新增新的屬性。就好像stylejavascript的一個物件一樣,也可以往style後繼續新增屬性。

  <script type="text/javascript">
        /*定義一個Person類*/
        function Person(_name,_age,_salary){
            //Person類的公開屬性,類的公開屬性的定義方式是:”this.屬性名“
            this.Name=_name;
            //Person類的私有屬性,類的私有屬性的定義方式是:”var 屬性名“
            var Age=_age;
            var Salary=_salary;

            //定義Person類的公開方法(特權方法),類的公開方法的定義方式
是:”this.functionName=function(){.....}“
            this.Show=function(){
   alert("Age="+Age+"\t"+"Salary="+Salary);//在公開方法裡面訪問類的私有屬性是允許的
            }
</script>

物件在查詢某個屬性的時候,會首先遍歷自身的屬性,如果沒有則會繼續查詢[[Prototype]]引用的物件,如果再沒有則繼續查詢[[Prototype]].[[Prototype]]引用的物件,依次類推,直到[[Prototype]].….[[Prototype]]undefinedObject[[Prototype]]就是undefined

簡單說就是通過物件的[[Prototype]]儲存對另一個物件的引用,通過這個引用往上進行屬性的查詢,這就是原型鏈。

null 物件

js給變數賦null值的作用在於:
賦值一個空指標,容易讓人理解這個變數是準備用來存放物件的。也方便調錯

全域性的window物件

JavaScript中的任何一個全域性函式或變數都是window的屬性。
self物件與window物件完全相同,self通常用於確認就是在當前的窗體內。

window的主物件主要有如下幾個:

JavaScript document 物件
JavaScript frames 物件
JavaScript history 物件
JavaScript location 物件
JavaScript navigator 物件
JavaScript screen 物件

幾個常用方法

valueof()方法:返回指定物件的原始值
split() 方法將字串分割為字串陣列,並返回此陣列。
indexOf() 方法可返回某個指定的字串值在字串中首次出現的位置。    
substring() 方法用於提取字串中介於兩個指定下標之間的字元。
substr() 方法從字串中提取從 startPos位置開始的指定數目的字串。    
join()方法用於把陣列中的所有元素放入一個字串。
arrayObject.join(分隔符)
reverse() 方法用於顛倒陣列中元素的順序。    
slice() 方法可從已有的陣列中返回選定的元素。

物件字面量

物件字面量是用於建立包含大量屬性的過程,如下所示:

<script type="text/javascript">
    var company = {
        name : "Microsoft",
        ages : 39,
        employees : 99000,
        CEO : "Nadella"
    };     
</script>

這裡需要注意的是屬性和屬性值以冒號(:)隔開;多個屬性用逗號(,)隔開。物件字面量亦可以定義方法,只需在這個物件的屬性上寫上function就行,這是一個匿名函式,呼叫它只需要寫上他的方法名()即可。

<script type="text/javascript">
var dog = {
   name:"husky",
   age:2,
   run:function(){
              return "123";
}
}
alert(dog.run());//如果輸入dog.run,那麼會彈出它後面的function部分的程式碼
</script>

基本值型別包裝器

js有五種基本的值型別:number、string、Boolean、null和undefined。除了null和undefined外,其他三個都具有所謂的基本包裝物件。可以使用內建建構函式Number()String()Boolean()建立包裝物件。

var num = new Number(10);
console.log(typeof num);//object

Object()方法

Object() // 返回一個空物件
Object(undefined) // 返回一個空物件
Object(null) // 返回一個空物件

Object(1) // 等同於 new Number(1)
Object('foo') // 等同於 new String('foo')
Object(true) // 等同於 new Boolean(true)

Object([]) // 返回原陣列
Object({}) // 返回原物件
Object(function(){}) // 返回原函式

陣列部分

1.Array 物件

Array 物件:提供對建立任何資料型別的陣列的支援。

arrayObj = new Array()
arrayObj = new Array([size])
arrayObj = new Array([element0[, element1[, ...[, elementN]]]])

定義:var arr = [2,3,45,6]; var arr = new Array(2,4,5,7)

兩者是定義沒有任何差別,[]的效能高,因為程式碼短。

使用陣列和物件字面量:var aTest = [];建立陣列時,使用陣列字面量是個好選擇;類似的,物件字面量也可用於節省空間。以下兩行是相等的,但是使用物件字面量的更加簡短:

 var oTest = new Object;  //儘量不用
 var oTest = { };    //最好的選擇,或者var 0Test = [ ];

遍歷為了達到遍歷陣列的最佳效能,推薦使用經典的 for 迴圈。

var list = [1, 2, 3, 4, 5, ...... 100000000];
for(var i = 0, l = list.length; i < l; i++) {
    console.log(list[i]);
}

上面程式碼有一個處理,就是通過 l = list.length 來快取陣列的長度。

Array 建構函式

由於 Array 的建構函式在如何處理引數時有點模稜兩可,因此總是推薦使用陣列的字面語法 - [] - 來建立陣列。

因此下面的程式碼將會使人很迷惑:

new Array(3, 4, 5); // 結果: [3, 4, 5] 
new Array(3) // 結果: [],此陣列長度為 3

應該儘量避免使用陣列建構函式建立新陣列。推薦使用陣列的字面語法。它們更加短小和簡潔,因此增加了程式碼的可讀性。

Array陣列的屬性

Array陣列的3個屬性:length屬性、prototype屬性、constructor屬性

1.length屬性

Length屬性表示陣列的長度,即其中元素的個數。因為陣列的索引總是由0開始,所以一個陣列的上下限分別是:0和length-1。和其他大多數語言不同的是,JavaScript陣列的length屬性是可變的,這一點需要特別注意。

2.prototype屬性

返回物件型別原型的引用。prototype屬性是object共有的。

對於Array陣列物件,以以下例子說明prototype屬性的用途。
給陣列物件新增返回陣列中最大元素值的方法。要完成這一點,宣告一個函式,將它加入Array.prototype,並使用它。

function array_max()  
{  
var i,max=this[0];  
for(i=1;i<this.length;i++)  
{  
if(max<this[i])  
max=this[i];  
}  
return max;  
}  

Array.prototype.max=array_max;  
var x=new Array(1,2,3,4,5,6);  
var y=x.max();

該程式碼執行後,y儲存陣列x中的最大值,或說6。

3.constructor屬性

表示建立物件的函式。說明:constructor屬性是所有具有prototype的物件的成員。它們包括除GlobalMath物件以外的所有JScript固有物件。constructor屬性儲存了對構造特定物件例項的函式的引用。

例如:

x = new String("Hi");  
if(x.constructor==String) //進行處理(條件為真)。  
//或  
function MyFunc{  
//函式體。  
}  

y=new MyFunc;  
if(y.constructor==MyFunc)//進行處理(條件為真)。

對於陣列來說:

y = new Array();

Array 物件方法

方法 描述
concat() 連線兩個或更多的陣列,並返回結果。
join() 把陣列的所有元素放入一個字串。元素通過指定的分隔符進行分隔。
pop() 刪除並返回陣列的最後一個元素
push() 向陣列的末尾新增一個或更多元素,並返回新的長度。
reverse() 顛倒陣列中元素的順序。
shift() 刪除並返回陣列的第一個元素
slice() 從某個已有的陣列返回選定的元素
sort() 對陣列的元素進行排序
splice() 刪除元素,並向陣列新增新元素。
toSource() 返回該物件的原始碼。
toString() 把陣列轉換為字串,並返回結果。
toLocaleString() 把陣列轉換為本地陣列,並返回結果。
unshift() 向陣列的開頭新增一個或更多元素,並返回新的長度。
valueOf() 返回陣列物件的原始值

sort()方法

語法

arrayObject.sort(sortby)

sortby可選。規定排序順序。必須是函式。

var arr = [11,2,28,4,5,1];
console.log(arr.sort());//return  [1, 11, 2, 28, 4, 5]

為毛這裡的11、28沒有按照順序來排列呢?這是因為不帶引數的sort是按照字元編碼的順序進行排序的。

那麼,如果要讓陣列元素按照從小到大排序呢?看下面程式碼:

var arr = [11,2,28,4,5,1];
    console.log(arr.sort(function(a,b){
        return a-b;//return  [1, 2, 4, 5, 11, 28]
    }));

如果想按照其他標準進行排序,就需要提供比較函式,該函式要比較兩個值,然後返回一個用於說明這兩個值的相對順序的數字。比較函式應該具有兩個引數 a 和 b,其返回值如下:

若 a 小於 b,在排序後的陣列中 a 應該出現在 b 之前,則返回一個小於 0 的值。
若 a 等於 b,則返回 0。
若 a 大於 b,則返回一個大於 0 的值。

附上一張陣列的思維導圖:

JavaScript學習系列文章目錄

相關文章