JavaScript對象-原型
在 JavaScript 中,對象是一種非常重要的數據類型,它是一組包含鍵值對的數據集合。愛掏網 - it200.com對象可以存儲數據,也可以存儲方法,我們可以通過對象的屬性和方法來操作對象。愛掏網 - it200.com
但是,這些屬性和方法來自何處?這就要涉及到 JavaScript 中的原型。愛掏網 - it200.com
對象在 JavaScript 中是通過構造函數創建的,每個構造函數都有一個原型對象,我們可以通過 __proto__
屬性獲取它的原型對象。愛掏網 - it200.com
例如,我們可以用以下代碼創建一個構造函數:
function Person(name) {
this.name = name;
}
let person = new Person('小明');
console.log(person.__proto__); // 輸出 Person {}
這里,Person
就是一個構造函數,我們用 new
關鍵字創建了一個 Person
類型的實例 person
。愛掏網 - it200.com可以看到,person.__proto__
輸出了一個空的 Person
構造函數的原型對象。愛掏網 - it200.com
原型可以被看作是一個模板,包含了構造函數可以使用的屬性和方法。愛掏網 - it200.com當我們訪問一個對象屬性或方法時,如果它不存在于自身屬性上,那 JavaScript 就會在原型鏈上繼續尋找該屬性或方法。愛掏網 - it200.com
原型鏈
原型對象之間形成一個鏈式結構,也就是原型鏈。愛掏網 - it200.com在原型鏈中,每個對象都有一個指向其原型對象的 __proto__
屬性。愛掏網 - it200.com
JavaScript 沿著原型鏈向上搜索,直到找到請求的成員或方法。愛掏網 - it200.com如果它找不到指定的成員或方法,則返回 undefined
。愛掏網 - it200.com
以下是一個簡單的原型鏈示例:
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`Hi, my name is {this.name}.`);
};
function Student(name, grade) {
this.grade = grade;
Person.call(this, name);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayGrade = function() {
console.log(`I'm in grade{this.grade}.`);
};
let student = new Student('小明', 6);
student.sayHi(); // 輸出 "Hi, my name is 小明。愛掏網 - it200.com"
student.sayGrade(); // 輸出 "I'm in grade 6。愛掏網 - it200.com"
console.log(student.__proto__); // 輸出 Student.prototype
console.log(student.__proto__.__proto__); // 輸出 Person.prototype
在這個例子中,我們定義了一個 Person
構造函數,它有一個 sayHi
方法,在 Student
構造函數中調用 Person
構造函數,然后通過 Object.create()
方法創建了一個 Student
原型對象,并將其指向 Person
的原型對象,最后,我們定義了 Student
自身的方法 sayGrade
。愛掏網 - it200.com
在 person
實例中,我們可以看到 __proto__
屬性指向了 Student.prototype
對象,這是因為 student
的構造函數是 Student
。愛掏網 - it200.com而 Student.prototype
的 __proto__
屬性又指向了 Person.prototype
,因為我們采用了繼承關系。愛掏網 - it200.com
prototype 和 __proto__ 的區別
JavaScript 中的每個對象都有一個原型,它都有一個指向原型的 __proto__
屬性。愛掏網 - it200.com每個構造函數也都有一個 prototype
屬性,它所有的實例對象的原型引用了它。愛掏網 - it200.com prototype
屬性是每個 JavaScript 函數中特有的屬性。愛掏網 - it200.com
先來看 prototype
對象。愛掏網 - it200.com
- 函數的
prototype
是一個對象。愛掏網 - it200.com - 但是普通對象沒有
prototype
屬性,因為 prototype 只屬于構造函數。愛掏網 - it200.com
在 JavaScript 中,每個構造函數都有一個 prototype
對象。愛掏網 - it200.com這個對象包含添加到該類型所有實例的屬性和方法。愛掏網 - it200.com例如,在以下代碼中:
function Person() {}
Person.prototype.name = '小明';
這個 name
屬性是 Person
構造函數的所有實例共享的。愛掏網 - it200.com
接下來,我們來看 __proto__
屬性。愛掏網 - it200.com
__proto__
是每個 JavaScript 對象都有的屬性,它指向該對象的原型對象。愛掏網 - it200.com__proto__
屬性在 JavaScript 中是一個非標準屬性,它被大多數現代瀏覽器支持。愛掏網 - it200.com
在以上提到的例子中,person.__proto__
返回了一個對象,這個對象是 Person
構造函數的原型對象。愛掏網 - it200.com
使用原型的好處
使用原型有以下幾個好處:
- 原型可以減少內存消耗。愛掏網 - it200.com當我們創建對象的時候,所有對象都實現了該對象類型的方法和屬性。愛掏網 - it200.com如果使用原型,方法和屬性將統一存儲在原型對象中,而不會分別存儲于每個對象。愛掏網 - it200.com
- 當我們需要修改對象類型的方法時,只需要在原型對象中修改一次即可,而不用每一個實例對象中都修改一次。愛掏網 - it200.com
- 代碼的可讀性會更好。愛掏網 - it200.com將所有與類型相關的信息統一存儲在原型對象中,可以使代碼更加直觀。愛掏網 - it200.com
總結
原型和原型鏈是 JavaScript 中非常重要的概念,理解它們對于寫出高效、可維護的代碼來說至關重要。愛掏網 - it200.com在代碼編寫過程中,我們可以使用原型繼承我們所需要的方法和屬性,從而簡化代碼。愛掏網 - it200.com同時,原型也是 JavaScript 最強大的特性之一,它可以提供很多想象力。愛掏網 - it200.com
謹記:對象的屬性和方法可以從原型繼承而來,同時也可以在實際擁有這些屬性和方法的對象上定義。愛掏網 - it200.com如果這個對象上定義了這個屬性或方法,則 JavaScript 不會去遍歷原型鏈。愛掏網 - it200.com