淺解析js中的對象

前面的話:

說到對象,我首先想到的是每到過年過節見長輩的時候長輩們老是開玩笑的問我“你找了對象沒?”。不說大家都知道,這裏的“對象”指的是“女朋友”,但是今天我想要說的js中的“對象”和我們生活中談到的“對象”不是同一回事,但是其中也有着很多相似之處。

在講js中的對象之前,我想先拋出幾個疑問:

什麼是對象?

對象有哪些?

對象能做什麼?

如何創建對象?

如何對對象進行操作?

對象有特性麼?有的話有哪些特性?

對象有屬性麼?有的話有哪些?對屬性如何操作?

……

什麼是javascript中的對象?

在ECMA-262中把對象定義爲:“無序屬性的集合,其屬性可以包含基本值、對象、或者函數。”嚴格來說,這就是相當於說對象是一組沒有特定序列的值。對象的每一個屬性或方法都有一個名字,而每一個名字都映射到一個值。(如:“女朋友”[對象]喜歡運動[對象的屬性或方法]–打籃球[屬性對應的值],我門可以試着這樣去理解,但實際可能有所區別)

在經典的面嚮對象語言中,對象是指數據和在這些數據上進行的操作的集合。與 C++ 和 Java 不同,JavaScript 是一種基於原型的編程語言,並沒有 class 語句,而是把函數用作類。

我理解的javascript對象:

第一:Javascript對象是 基本數據類型 之一,是複合類型;

第二:Javascript中 幾乎所有事物都是做對象 ;

第三:Javascript的對象是 擁有屬性和方法 的 數據 ;

第四:JavaScript 中的對象可以簡單理解成 “名稱:值”對 (name:value)。名稱(name):”名稱”部分是一個 JavaScript 字符串

在javascript語句中這三種形式是一樣的

        var obj={prop:1}
        var obj={"prop":1}
        var obj={'prop':1}

在這裏看起來屬性名既可以加引號也可以不加引號,但是在實際中有這麼幾種情況你必須將屬性名放到引號中間

如果屬性名是Javascript的保留字之一

如果屬性名種包含特殊字符(除字母、數字、下劃線以外的字符)

如果屬性名以數字開頭

在ECMAScript5中,保留字可以用作不帶引號的屬性名,但對於ECMAScript3中必須用引號括起來

在ECMAScript5中對象直接量中的最後一個屬性後的逗號將被忽略,在ECMAScript 3的大部分實現中也可以忽略這個逗號,但在IE中報錯

值(value):”值”部分可以是任何 JavaScript 的數據類型——包括對象

對象有哪些呢?

學過java的都知道,在java中有一句很經典的描述對象的話“萬物皆對象”,是的,在javascript中也是一樣。在javascript中我們可以把對象分爲兩大類,一類是內建對象(數據封裝對象,工具類對象,錯誤對象,後面會有專門針對內建對象的博客),一類是自定義對象(這篇文章裏面講的主要就是自定義對象)

對象能做什麼?

在這裏我要先賣個關子,到後面的時候告訴大家。

如何創建對象?

既然瞭解了對象和基本的對象分類,我們是否應該要知道如何去創建一個自定義的對象呢?

1、通過對象字面量的方式創建對象 (對象字面量是一個表達式,這個表達式的每次運算都創建並初始化一個新對象。每次計算對象字面量的時候,也都會計算他的每個屬性的值。也就是說,如果在一個重複調用的函數中的循環體內使用了對象直接量,它將創建很多新對象,並且每次創建的對象的屬性值也有可能不同。)

語法:var obj = {};

實例:

首先,我們創建一個空的對象,裏面沒有任何屬性,我們來獲取它的類型

var obj1 = {};//沒有任何屬性的對象
console.log(typeof obj);        //object

它返回的結果是object,說明我們創建的是一個object對象,當然,我們還可以用下面的方法來創建

  var obj2={x:1,y:2,z:3};
                var obj3={
                'x':1,
                "y":2,
                username:'king',
                'for':'javascript關鍵字必須放到引號中間',    //for是javascript關鍵字,必須放到引號中間
                'first-name':'foodoir',                //-是特殊字符,也需要放在引號中間
                married:true,
                test:null,
                test1:undefined,
                salary:12.3,
                person:{                            //在對象中"值"部分可以是任何 JavaScript的數據類型——包括對象
                    username:'king',
                    age:21,
                    addr:'北京',
                },                                    //最後一個對象屬性的後面的逗號可以寫可以不寫,在ECMAScript 5中自動被忽略,在ECMAScript 3的大部分實現中也可以忽略這個逗號,但在IE中報錯
            }

2、通過new object創建對象

語法:var obj = new Object();

實例:

            var obj4 = new Object();//創建一個空對象
            var arr = new Array();//創建一個空數組對象
            var date = new Date();//創建一個空時間對象   

3、通過構造函數的形式創建對象

語法:function Person(){};或者var Person=function(){};

實例:

            var obj5=new Test1();
            function Test1(num1,num2){
                this.n1=num1;
                this.n2=num2;
            }
            var obj6=new Test1(5,6);
            console.log(typeof obj6);                //object
            console.log(obj6 instanceof Object);    //true

在使用通過構造函數的形式創建對象時應注意:

a.使用的時候通過new操作符得到對象var person1=new Person()

b.用構造器創建對象的時候可以接收參數

c.構造器函數的首字母最好大寫,區別其他的一般函數

注意:構造器屬性(constructor property),當我們創建對象的時候,實際上同時也賦予了該對象一種特殊的屬性,就是構造器屬性,這個構造器屬性實際上是一個指向用於創建該對象的構造器函數的引用

補充:

typeof 和 instanceof 常用來判斷一個變量是否爲空,或者是什麼類型的。但它們之間還是有區別的:

typeof 是一個一元運算,放在一個運算數之前,運算數可以是任意類型。

它返回值是一個字符串,該字符串說明運算數的類型。typeof 一般只能返回這幾個結果:number,boolean,string,function,object,undefined。

我們可以使用 typeof 來獲取一個變量是否存在,如 if(typeof a!=”undefined”){alert(“ok”)},而不要去使用 if(a) 因爲如果 a 不存在(未聲明)則會出錯,對於 Array,Null 等特殊對象使用 typeof 一律返回 object,這正是 typeof 的侷限性。

instanceof 用於判斷一個變量是否某個對象的實例

在上面的例子中,obj6 instanceof Object判斷的爲true,則說明創建的obj6也是Object類型

4、通過Object.create()創建對象

        var obj7 = Object.create({x:1});
        //創建一個普通的空對象
        var obj8 = Object.create(null);
        //創建一個對象的原型屬性
        var obj9 = Object.create(Object.prototype);    //prototype對象的原型屬性
        console.log(typeof obj7);                //object
        console.log(typeof obj8);                //object
        console.log(typeof obj9);                //object
        //通過instanceof 操作符檢測對象是否由某個指定的構造器函數創建的
        console.log(obj7 instanceof Object);    //true
        console.log(obj8 instanceof Object);    //false,注意:空對象用instanceof判斷時,結果爲false
        console.log(obj9 instanceof Object);    //true

如何對對象進行操作?

學過數據庫的我們都知道,數據庫最基本的四個操作分別是“增、刪、查、改”,那麼在對對象的操作中是否也存在類似的操做呢?是的,在對對象的操作中也有查詢,添加,修改,刪除操作,都是基於對象的屬性的操作。下面我們來介紹對象的幾個基本操作。

首先,我們先要通過查詢方法,來獲取對象中的屬性,訪問屬性有三種方法:對象名.屬性名;對象名[屬性名];當處於某個對象方法內部的時候,可以通過this來訪問同一對象的屬性

var person = {
    username: "foodoir",
    age: 21,
    sex: "男",
    addr: "湖南",
    salary: 123456,
};
console.log("姓名:" + person.username + "\n" + "性別:" + person.sex); //姓名:foodoir    性別:男
console.log("年齡:" + person['age'] + "\n" + "薪水:" + person["salary"]); //年齡:21    薪水:123456
//如果屬性不確定,需要使用[]
var key = 'username';
console.log(person.key); //undefined   此種方法不能得到key的值,通過[]方法可以得到
console.log(person[key]); //foodoir     當屬性不確定時,用該方法
console.log(person['key']); //undefined

看到這裏,你肯定會有有疑問,爲什麼第9行代碼中person[‘age’]中的age和person[“salary”]中的salary都加了引號,且都可以顯示出結果,而在第13行代碼中person[‘key’]中的key加了引號,反而返回值是undefined 原因究竟是什麼呢?

age爲person對象中的屬性名,而該對象只對person進行了定義,沒對person裏面的屬性進行定義,故在調用的時候,在[]中間應該加上引號,也就是說,person[‘age’]和person.age是等價的

而key是在對象外定義的(var key = ‘username’;),在對象裏面它是不存在key這個屬性的(即屬性不確定),此時直接用person[key]方法就好了,person.key和person[‘key’]返回的必須是person對象裏面確定的屬性,key沒在person屬性裏面,故這兩種方法返回的值都是undefined

學會了如何 獲取對象的屬性 ,然後我們該繼續學習對象中的屬性進行添加,修改和查詢操作

function personInfo(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}
var person1 = new personInfo('foodoir', 20, '男');
console.log(person1.name + person1.sex); //foodoir男

屬性的添加 有兩種方式:對象名.屬性名=值;對象名[屬性名]=值

//添加屬性
var obj = {};
obj.username = 'foodoir';
obj.age = 21;
obj.sex = '男';
obj.addr = '湖南';
obj['test'] = 'hello world';
console.log(obj.username + " " + obj.age + " " + obj.sex + " " + obj.addr + " " + obj['test']); //foodoir 21 男 湖南 hello world

屬性的修改 也有兩種方式:對象名.屬性名=值;對象名[屬性名]=值

//修改指定屬性
obj.username = 'chenwu';
console.log("修改之後的名字:" + obj.username); //修改之後的名字:chenwu
obj['test'] = 'hello javascript';
console.log("修改之後的test:" + obj['test']); //修改之後的test:hello javascript

屬性的刪除 也有兩種方式:delete 對象名.屬性名;delete 對象名[屬性名] 。在delete刪除指定的屬性時應該注意:(後面講對象的結構的時候會詳細介紹)

delete只能刪除自身屬性,不能刪除繼承屬性

要刪除繼承屬性,只能從定義它屬性的原型對象上刪除它,而且這會影響到所有繼承自這個原型的對象

delete只是斷開屬性和宿主對象的聯繫,而不會去操作屬性的屬性

delete不能刪除哪些可配製性爲false的屬性

//通過delete刪除指定的屬性
delete obj.sex;
console.log(obj.sex); //undefined
delete obj['test'];
console.log(obj['test']); //undefined

除了“增、刪、改、查”我們還要學會對象中的遍歷,對象中的遍歷有兩種, 一種是for/in遍歷 , 一種是通過Object.keys(obj)函數進行遍歷

var obj = {
    x: 1,
    y: 2,
    test: "helloworld",
    edu: "javascript",
};
//通過for/in遍歷屬性
for(var i in obj) {
    console.log(i); //x y test edu(換行輸出)
    console.log(obj[i]); //輸出的是屬性名對應的屬性值
}
//通過Object.keys(obj)遍歷屬性
console.log(Object.keys(obj)); //["x", "y", "test", "edu"]
發佈了39 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章