1. 程式人生 > 其它 >js基礎之阮一峰的面向物件程式設計

js基礎之阮一峰的面向物件程式設計

一  原型

1.複用:面對物件

面向物件程式設計是class來實現物件(類-介面)的繼承,js則是通過“原型物件”.

public  class Person {
    int age;
    public Person(int a){
     age=a;
    }
    void speak(){
        System.out.println("今年我"+this.age+"歲");
    }
} 

很重要的一個方面,就是物件的繼承,這對於程式碼的複用是非常有用的。

function Person(name){
   this.name=name;
   this.sum=function(){
       alert("this.name")
   }

}

  

2.建構函式的缺點:無法共享

JavaScript 通過建構函式生成新物件,因此建構函式可以視為物件的模板

建構函式繼承的缺點:  

二個例項,擁有的方法也變成二個了,浪費系統資源。方法是共享的,應該也共享。

這個問題的解決方法,就是 JavaScript 的原型物件(prototype)。

js中繼承機制的思想:是所有的方法和變數都可以共享。定義在原型上就可以共享。

js中函式的原型屬性都指向一個物件。

function Dog(name, age) {
    this.name = name;
    this.age = age;
    this.log = function () {
        console.log(this.name + ":" + this.age);
    }
} let dog1 = new Dog("小黃", 5); let dog2=new Dog("小花",6);

 對普通的函式沒有作用,對建構函式有作用。在外面用上prototype,原型屬性和方法。原型物件的屬性不是例項物件的屬性。

二 原型鏈

所有物件都有自己的原型鏈,一個物件可充當的其他物件的原型; 原型物件也是物件,也有自己的原型。因此形成原型鏈“prototype Chain”

一層層追溯到最頂層就是Object.prototype,所有物件都繼承了Object.prototype的屬性。這就是所有物件都有valueOftoString方法的原因

Object.prototype的原型是null,沒有任何屬性和方法。

覆蓋”:讀取物件的某個屬性時,JavaScript 引擎先尋找物件本身的屬性,如果找不到,就到它的原型去找,如果還是找不到,就到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回undefined

                如果物件自身和它的原型,都定義了一個同名屬性,那麼優先讀取物件自身的屬性,這叫做“覆蓋”(overriding)。

缺點:一級級查詢,找不到,會遍歷整個原型鏈,那麼很影響屬性。

 

三 constructor屬性

prototype物件有一個constructor屬性,預設執行原型物件所在的建構函式。因在原型上,那麼構造可以被所有物件繼承。

 

function f(){}
var f=new f();
f.prototype.constructor===f f.hasOwnProperty(constructor)

 

f 是 建構函式f 的 例項物件, f 本身沒有construct。

修改原型的屬性或方法時,同時也要修改constructor,不然導致這個屬性不再指向Person。由於Person的新原型是一個普通物件,而普通物件的contructor屬性指向Object建構函式,導致Person.prototype.constructor變成了Object

下面程式碼中,要麼將constructor屬性重新指向原來的建構函式,要麼只在原型物件上新增方法,這樣可以保證instanceof運算子不會失真。

 

C.prototype = {
  constructor: C,
  method1: function (...) { ... },
  // ...
};

// 更好的寫法
C.prototype.method1 = function (...) { ... };

  

四 面試題

 1.原型繼承 

  B繼承A,先有A與B,(就是先生成function A(){});

 缺點:新例項無法向父類建構函式傳參

B.prototype=new A();
let newB=new B();

 2.call借用建構函式構成

在子元素的裡面寫上

fu.call(this,name),

 3.組合繼承

引用自:https://javascript.ruanyifeng.com/oop/prototype.html#toc1