目錄
1. 對象的相關概念
對象是 JavaScript
中的數據類型之一,是一種複合的數據類型,它將多種數據類型集中在一個數據單元中,並允許通過對象來存取這些數據的值。
對象的概念首先來自於對客觀世界的認識,它用於描述客觀世界存在的特定實體。比如,手機
就是一個典型的對象,手機
包括大小、顏色、屏幕尺寸等特性,同時又包含打電話、發短信、玩遊戲等動作。手機
對象示意圖如下圖所示。
在計算機的世界裏,不僅存在來自於客觀世界的對象,也包含爲解決問題而引入的比較抽象的對象。例如,一個用戶
可以被看作一個對象,它包含用戶名、用戶密碼等特性,也包含註冊、登錄等動作。其中,用戶名和用戶密碼等特性,可以用 變量
來描述。而註冊、登錄等動作,可以用 函數(方法)
來定義。因此,對象是一組 無序的相關屬性和方法的集合
。用戶
對象示意圖如下圖所示。
在 JavaScript
中,對象包含兩個要素:屬性
和 方法
。通過訪問或設置對象的屬性,並且調用對象的方法,就可以對對象進行各種操作,從而獲得需要的功能。
1.1 爲什麼需要對象?
保存一個值時,可以使用變量,保存多個值(一組值)時,可以使用 數組
。如果要保存一個人的完整信息呢? 例如,將 Amo
的個人的信息保存在數組中的方式爲:
let arr = ['Amo', '男', 18, 183];
上述例子中用數組保存數據的缺點是:數據只能通過索引值訪問,開發者需要清晰的清楚所有的數據的排列才能準確地獲取數據,而當數據量龐大時,不可能做到記憶所有數據的索引值。爲了讓更好地存儲一組數據,對象應運而生:對象中爲每項數據設置了屬性名稱,可以訪問 數據更語義化
,數據結構清晰
,表意明顯
,方便開發者使用。使用對象記錄上組數據爲:
1.2 對象的屬性名
將包含在對象內部的變量稱爲對象的屬性,它是用來描述對象特性的一組數據。在程序中使用對象的一個屬性類似於使用一個變量,就是在屬性名前加上對象名和一個句點 .
。獲取或設置對象的屬性值的語法格式如下:
對象名.屬性名
以 手機
對象爲例,該對象有品牌和顏色兩個屬性,以下代碼可以分別獲取該對象的這兩個屬性值:
let brand = 手機.品牌; // 或者 let brand = 手機[品牌];
let color = 手機.顏色; // 或者 let color = 手機[顏色];
也可以通過以下代碼來設置 手機
對象的這兩個屬性值。
手機.品牌 = "iphone";
手機.顏色 = "silvery";
1.3 對象的方法
將包含在對象內部的函數稱爲對象的方法,它可以用來實現某個功能。在程序中調用對象的一個方法類似於調用一個函數,就是在方法名前加上對象名和一個句點 .
語法格式如下:
對象名.方法名(參數)
與函數一樣,在對象的方法中有可能使用一個或多個參數,也可能不需要使用參數,同樣以 手機
對象爲例,該對象有 打電話
和 發短信
兩個方法,以下代碼可以分別調用該對象的這兩個方法:
手機.打電話();
手機.發短信(); //一定要記得加括號
在 JavaScript
中,對象就是屬性和方法的集合,這些屬性和方法也叫作對象的成員。方法是作爲對象成員的函數,表明對象所具有的行爲。而屬性是作爲對象成員的變量,表明對象的狀態。
在 JavaScript
中可以使用 3
種對象,即自定義對象/內置對象/瀏覽器對象
。內置對象
和 瀏覽器對象
又稱爲預定義對象。
- 在
JS
中將一些常用的功能預先定義成對象,這些對象用戶可以直接使用,這種對象就是內置對象。這些內置對象可以幫助用戶在編寫程序時實現一些最常用、最基本的功能,如Math/Date/String/Array/Number/Boolean/RegExp/Object
對象等。 - 瀏覽器對象是瀏覽器根據系統當前的配置和所裝載的頁面爲
JavaScript
提供的一些對象。例如document/window
對象等。 - 自定義對象就是指用戶根據需要自己定義的新對象。
2. 創建對象的三種方式
2.1 直接創建自定義對象
直接創建自定義對象的語法格式如下:
let 對象名 = {屬性名1:屬性值1,屬性名2:屬性值2,屬性名3:屬性值3......}
由語法格式可以看出,直接創建自定義對象時,所有屬性都放在大括號中,屬性之間用逗號分隔,每個屬性都由屬性名和屬性值兩部分組成,屬性名和屬性值之間用冒號隔開。
例如,創建一個手機對象 phone
,並設置3個屬性,分別爲brand
、color
和 price
,然後輸出這 3個
屬性的值,代碼如下:
2.2 通過自定義構造函數創建對象
雖然直接創建自定義對象很方便也很直觀,但是如果要創建多個相同的對象,使用這種方法就顯得很繁瑣了。在 JavaScript
中可以自定義構造函數,通過調用自定義的構造函數可以創建並初始化一個新的對象。與普通函數不同,調用構造函數必須要使用 new
運算符。構造函數也可以和普通函數一樣使用參數,其參數通常用於初始化新對象。在構造函數的函數體內通過 this
關鍵字初始化對象的屬性與方法。注意事項如下:
- 構造函數約定
首字母大寫
。 - 函數內的屬性和方法前面需要添加
this
,表示當前對象的屬性和方法。 - 構造函數中不需要
return
返回結果。 - 當我們創建對象的時候,必須用
new
來調用構造函數。
例如,要創建一個手機對象 phone
,可以定義一個名稱爲 Phone
的構造函數,代碼如下:
function Phone(brand,color,price){ //定義構造函數
this.brand = brand; //初始化對象的brand屬性
this.color = color; //初始化對象的color屬性
this.price = price; //初始化對象的price屬性
};
上述代碼中,在構造函數內部對 3個
屬性 brand
、color
和 price
進行了初始化,其中,this
關鍵字表示對對象自己屬性、方法的引用。利用該函數,可以用 new
運算符創建一個新對象,代碼如下:
let phone1 = new Phone("iphone", "紅色", 6888); //創建對象實例
上述代碼創建了一個名爲 phone1
的新對象,新對象 phone1
稱爲對象 phone
的實例。使用 new
運算符創建一個對象實例後,JavaScript
會接着自動調用所使用的構造函數,執行構造函數中的程序。另外,還可以創建多個 phone
對象的實例,每個實例都是獨立的。代碼如下:
let phone2 = new Phone("小米10 Pro", "珍珠白", 5999); //創建其它對象實例
let phone3 = new Phone("華爲Mate Xs 5G摺疊屏手機", "星際藍", 21888); //創建其它對象實例
new
關鍵字的作用:
- 在構造函數代碼開始執行之前,創建一個空對象
- 修改
this
的指向,把this指向創建出來的空對象 - 執行函數的代碼
- 在函數完成之後,返回
this
即創建出來的對象
應用構造函數創建一個教師對象,定義構造函數Teacher(),在函數中應用 this
關鍵字初始化對象中的屬性,然後創建一個對象實例,最後輸出對象中的屬性值,即輸出教師的姓名、年齡、身高、所屬學校和所教專業。程序代碼如下:
<script type="text/javascript">
function Teacher(name,age,height,school,lesson){ //定義構造函數
this.name = name; //對象的name屬性
this.age = age; //對象的age屬性
this.height = height; //對象的height屬性
this.school = school; //對象的school屬性
this.lesson = lesson; //對象的major屬性
};
//創建一個新對象teacher1
let teacher1 = new Teacher("Amo", 18,183,"重慶師範大學","Vue框架技術");
//輸出屬性
document.write(`老師的姓名是: ${teacher1.name}<br/>`);
document.write(`老師的年齡是: ${teacher1.age}<br/>`);
document.write(`老師的身高是: ${teacher1.height}<br/>`);
document.write(`老師所屬院校是: ${teacher1.school}<br/>`);
document.write(`老師所教課程是: ${teacher1.lesson}<br/>`);
</script>
對象不但可以擁有屬性,還可以擁有方法。在定義構造函數時,也可以定義對象的方法。與對象的屬性一樣,在構造函數裏也需要使用 this
關鍵字來初始化對象的方法。例如,在 teacher
對象中定義3個方法showName()
、showAge()
和 showSchool()
,代碼如下:
<script type="text/javascript">
function Teacher(name,age,height,school,lesson){ //定義構造函數
this.name = name; //對象的name屬性
this.age = age; //對象的age屬性
this.height = height; //對象的height屬性
this.school = school; //對象的school屬性
this.lesson = lesson; //對象的major屬性
this.showName = showName;
this.showAge = showAge;
this.showSchool = showSchool;
};
function showName(){ //定義showName()方法
alert(this.name); //輸出name屬性值
}
function showAge(){ //定義showAge()方法
alert(this.age); //輸出age屬性值
}
function showSchool(){ //showSchool()方法
alert(this.school); //輸出school屬性值
}
//創建一個新對象teacher1
let teacher1 = new Teacher("Amo", 18,183,"重慶師範大學","Vue框架技術");
teacher1.showName();
</script>
另外,也可以在構造函數中直接使用表達式來定義方法,代碼如下:
<script>
function Teacher(name,age,height,school,lesson){ //定義構造函數
this.name = name; //對象的name屬性
this.age = age; //對象的age屬性
this.height = height; //對象的height屬性
this.school = school; //對象的school屬性
this.lesson = lesson; //對象的major屬性
this.showName = function(){ //應用表達式定於showName()方法
alert(this.name); //輸出name屬性值
};
this.showAge = function(){ //應用表達式定於showAge()方法
alert(this.age); //輸出age的屬性值
};
this.showSchool = function(){
alert(this.school);
};
};
//創建一個新對象teacher1
let teacher1 = new Teacher("Amo", 18,183,"重慶師範大學","Vue框架技術");
teacher1.showSchool();
</script>
調用構造函數創建對象需要注意一個問題。如果構造函數中定義了多個屬性和方法,那麼在每次創建對象實例時都會爲該對象分配相同的屬性和方法,這樣會增加對內存的需求,這時可以通過 prototype
屬性來解決這個問題。prototype
屬性是 JavaScript
中所有函數都有的一個屬性。該屬性可以向對象中添加屬性或方法。語法格式如下:
object.prototype.name = value
參數說明:
object
:構造函數名。name
:要添加的屬性名或方法名。value
:添加屬性的值或執行方法的函數。
例如,在 student
對象中應用 prototype
屬性向對象中添加一個 show()
方法,通過調用 show()
方法輸出對象中3個屬性的值。代碼如下:
<script type="text/javascript">
function Student(name, sex, age) { //1.定義構造函數
this.name = name; //初始化對象的屬性
this.sex = sex; //初始化對象的屬性
this.age = age; //初始化對象的屬性
};
Student.prototype.show = function() {
alert(`姓名: ${this.name} ---- 性別: ${this.sex} ---- 年齡: ${this.age}`);
}
// 創建實例對象
let student1 = new Student("向巍", "男", 18); //創建對象實例
student1.show(); //調用對象的show()方法
</script>
2.3 通過Object對象創建自定義對象
Object
對象是 JavaScript
中的內部對象,它提供了對象的最基本功能,這些功能構成了所有其他對象的基礎。Object
對象提供了創建自定義對象的簡單方式,使用這種方式不需要再定義構造函數。可以在程序運行時爲 JavaScript
對象隨意添加屬性,因此使用 Object
對象能很容易地創建自定義對象。創建 Object
對象的語法如下:
obj = new Object([value])
參數說明:
- obj:必選項。要賦值爲
Object
對象的變量名。 - value:可選項。任意一種
JS
基本數據類型(Number/Boolean/或String)
。如果value
爲一個對象,返回不做改動的該對象。如果value
爲null/undefined
,或者沒有給出,則產生沒有內容的對象。
使用 Object
對象可以創建一個沒有任何屬性的空對象。如果要設置對象的屬性,只需要將一個值賦給對象的新屬性即可。例如,使用Object
對象創建一個自定義對象 student
,並設置對象的屬性,然後對屬性值進行輸出,代碼如下:
<script>
let student = new Object(); //創建一個空對象
student.name = "Amo"; //設置對象的name屬性
student.sex = "男"; //設置對象的sex屬性
student.age = 18; //設置對象的age屬性
document.write(`一個可愛的學生姓名是: ${student.name} 性別是: ${student.sex} 年齡是: ${student.age}`);
</script>
一旦通過給屬性賦值創建了該屬性,就可以在任何時候修改這個屬性的值,只需要賦給它新值即可。在使用 Object
對象創建自定義對象時,也可以定義對象的方法。例如,在 student
對象中定義方法 show()
,然後對方法進行調用,代碼如下:
<script>
let student = new Object(); //創建一個空對象
student.name = "Amo"; //設置對象的name屬性
student.sex = "男"; //設置對象的sex屬性
student.age = 18; //設置對象的age屬性
student.show = function() {
alert(`一個可愛的學生姓名是: ${student.name} 性別是: ${student.sex} 年齡是: ${student.age}`);
}
student.show();
</script>
如果在創建 Object
對象時沒有指定參數,JavaScript
將會創建一個 Object
實例,但該實例並沒有具體指定爲哪種對象類型,這種方法多用於創建一個自定義對象。如果在創建 Object
對象時指定了參數,可以直接將 value
參數的值轉換爲相應的對象。如以下代碼就是通過 Object
對象創建了一個字符串對象。
let myObj = new Object("你好JavaScript"); //創建一個字符串對象
3. 對象訪問語句
在JavaScript
中,for…in
語句和 with
語句都是專門應用於對象的語句。下面對這兩個語句分別進行介紹。for…in
語句和 for
語句十分相似,for…in
語句用來遍歷對象的每一個屬性。每次都將屬性名作爲字符串保存在變量裏。語法格式如下:
for (變量 in 對象) {
語句
}
參數說明:
- 變量:用於存儲某個對象的所有屬性名。
- 對象:用於指定要遍歷屬性的對象。
- 語句:用於指定循環體。
for…in
語句用於對某個對象的所有屬性進行循環操作。將某個對象的所有屬性名稱依次賦值給同一個變量,而不需要事先知道對象屬性的個數。
注意:應用 for…in
語句遍歷對象的屬性,在輸出屬性值時一定要使用數組的形式 (對象名[屬性名])
進行輸出,而不能使用 對象名.屬性名
這種形式。
下面應用 for…in
循環語句輸出對象中的屬性名和值。首先創建一個對象,並且指定對象的屬性,然後應用 for…in
循環語句輸出對象的所有屬性和值。程序代碼如下:
<script>
let obj = { //創建自定義對象
"name": "Amo",
"sex": "男",
"age": 18,
"hobby": "唱歌跳舞"
};
for (let key in obj) { //使用for...in語句
console.log(obj[key]);
}
</script>
with
語句被用於在訪問一個對象的屬性或方法時避免重複引用指定對象名。使用 with
語句可以簡化對象屬性調用的層次。語法格式如下:
with(對象名稱){
語句
}
- 對象名稱:用於指定要操作的對象名稱。
- 語句:要執行的語句,可直接引用對象的屬性名或方法名。
在一個連續的程序代碼中,如果多次使用某個對象的多個屬性或方法,那麼只要在 with
關鍵字後的括號 ()
中寫出該對象實例的名稱,就可以在隨後的大括號 {}
中的程序語句中直接引用該對象的屬性名或方法名,不必再在每個屬性名或方法名前都加上 對象實例名和.
。 例如,應用 with
語句實現 student
對象的多次引用,代碼如下:
<script>
function Student(name, sex, age) {
this.name = name; //設置對象的name屬性
this.sex = sex; //設置對象的sex屬性
this.age = age; //設置對象的age屬性
}
let student = new Student("向巍", "男", 18); //創建對象
with(student) {
alert(`姓名:${name} 性別:${sex} 年齡:${age}`);
}
</script>
4. ES6擴展的對象和功能
4.1 屬性的簡潔表示法
ES6
允許在大括號裏面,直接寫入變量和函數,作爲對象的屬性和方法。這樣的書寫更加簡潔。示例代碼如下:
<script>
const name = "Amo";
const obj = {
name //相當於name: name
};
console.log(obj);
</script>
上面代碼中,變量 name
直接寫在大括號裏面。這時,屬性名就是變量名,屬性值就是變量值。下面是另一個例子。
<script>
//如果一個函數返回值爲對象 這可以向下面這樣書寫
function f(x, y) {
return {
x,
y
}; //相當於return {x:x,y:y}
}
console.log(f(1, 2));
</script>
除了屬性簡寫,方法也可以簡寫。示例代碼如下:
<script>
const obj = {
method() {
return "Hello!"; //等同於 method: function(){return "Hello!";}
}
};
</script>
下面是一個實際的例子。
<script>
let birth = "2000/05/20";
const Person = {
name: "Amo",
birth, // birth: birth
hello() { //等同於 hello: function(){....}
alert(`我的名字是: ${this.name}`);
}
}
Person.hello();
</script>
這種寫法用於函數的返回值,將會非常方便。示例代碼如下:
<script>
function f() {
const x = 1;
const y = 2;
return {
x,
y
};
}
console.log(f());
</script>
屬性的賦值器 (setter)
和取值器 (getter)
,事實上也是採用這種寫法。示例代碼如下:
<script>
const cart = {
_wheels: 4,
get_wheels() {
return this._wheels;
},
set_wheels(value) {
if (value < this._wheels) {
throw new Error('數值太小了!');
}
this._wheels = value;
}
}
console.log(cart.get_wheels());
cart.set_wheels(10);
console.log(cart.get_wheels());
</script>
4.2 屬性名表達式
JavaScript
定義對象的屬性,有兩種方法。示例代碼如下:
<script>
const obj = {};
//方法1
obj.isFlag = true;
//方法2
obj["a" + "bc"] = 123;
console.log(obj);
</script>
上述代碼執行結果爲:
上面代碼的方法一是直接用標識符作爲屬性名,方法二是用表達式作爲屬性名,這時要將表達式放在方括號之內。但是,如果使用字面量方式定義對象(使用大括號),在 ES5
中只能使用方法一(標識符)
定義屬性。
<script>
const obj = {
foo: true,
abc: 123
};
</script>
ES6
允許字面量定義對象時,用方法二 (表達式)
作爲對象的屬性名,即把表達式放在方括號內。示例代碼如下:
<script>
let propKey = "isFlag";
const obj = {
[propKey]: true,
["a" + "bc"]: 123
};
console.log(obj);
</script>
上述代碼執行結果爲:
表達式還可以用於定義方法名。示例代碼如下:
<script>
let obj = {
["say" + 'Hello']() {
return 'hi';
}
};
console.log(obj.sayHello()); // hi
</script>
注意,屬性名表達式與簡潔表示法,不能同時使用,會報錯。如下圖所示:
注意,屬性名表達式如果是一個對象,默認情況下會自動將對象轉爲字符串 [object Object]
,這一點要特別小心。
上面代碼中,[keyA]
和 [keyB]
得到的都是 [object Object]
,所以 [keyB]
會把 [keyA]
覆蓋掉,而 myObject
最後只有一個 [object Object]
屬性。其它更多擴展功能 點擊 此處 進行系統學習.