11-原型對象
- 2022 年 1 月 9 日
- 筆記
- javascript
11-原型對象
我們在學習構造函數那一節的時候遇到了一個問題。
1 <script type="text/javascript"> 2 function Person(age, name, sex){ 3 this.name = name; 4 this.sex = sex; 5 this.age = age; 6 this.sayName = SayName; 7 } 8 function SayName(){ 9 alert("大家好!" + "我是" + this.name + ",我" + this.age + "歲," + "我是" + this.sex + "生"); 10 } 11 12 p1 = new Person(18, "沙僧", "男"); 13 p2 = new Person(18, "孫悟空", "男"); 14 p3 = new Person(18, "白骨精", "女"); 15 p1.sayName(); 16 p2.sayName(); 17 p3.sayName(); 18 </script>
View Code
大家看這個,咱們可以發現雖然可以達到創建多個對象,只調用一次函數的效果,但是也有許多弊端。
將函數定義在全局作用域,污染全局作用域的命名空間,而且定義在全局作用域中也很不安全。因為一個程序一般都是多個人參與開發的,另外一個開發人員可能會用到和你一樣的函數名,這樣就會污染變量。
下面就為大家介紹另外一種方法:原型對象法
首先為大家解釋什麼是原型對象?
在每一個構造函數對象中都有一個隱藏的屬性prototype,而這個屬性是一個對象,我們把這個對象稱作原型對象。
大家可以看下面這段代碼:
1 function Dog(){ 2 console.log("一隻小狗"); 3 } 4 console.log(Dog.prototype);
這段代碼運行效果如下:
既然prototype是一個對象那他就可以擁有自己的屬性和方法,大家可以看下面這張圖:
另外,這個屬性在同一個構造函數中創建的對象中是一樣的:
1 function Dog(){ 2 console.log("一隻小狗"); 3 } 4 // console.log(Dog.prototype); 5 d1 = new Dog(); 6 d2 = new Dog(); 7 console.log(d1.__proto__ === d2.__proto__); 8 console.log(d1.__proto__ === Dog.prototype);
這段代碼運行效果如下:
基於以上特性我們可以將需要在構造函數中使用的屬性、方法,全部放到原型屬性裏面:
(原型對象就像是一個公共的區域,所有同一類的實例都可以訪問到這個原型對象。)
1 function Person(name, age, sex){ 2 this.name = name; 3 this.age = age; 4 this.sex = sex; 5 } 6 Person.prototype.sayName = function(){ 7 console.log(`大家好,我是${this.name},我是${this.sex}生,我${this.age}歲`); 8 } 9 obj1 = new Person("孫悟空", 10000, "男"); 10 obj1.sayName();
下圖是上面代碼執行效果:
在JS中當我們訪問對象的一個屬性或者方法時,他會現在對象自身中尋找,如果有則直接使用,如果沒有就向原型對象中找。
另外原型對象也是一個對象,是一個對象就有原型對象,那麼是不是沒有盡頭呢?我們來看下面的代碼:
1 console.log(d1.__proto__); 2 console.log(d1.__proto__.__proto__); 3 console.log(d1.__proto__.__proto__.__proto__); // 返回空
下圖是代碼執行效果:
通過上面代碼我們發現並不是所有對象都有原型對象,那麼哪一類對象沒有原型對象呢?
Object對象沒有原型對象,如果在Object中依然沒有找到,則返回null或undefined