[寫做中...]Js面向對象(2): 建立對象

目標

  • 理解對象
  • 建立對象實例
  • 理解Js中的繼承

前言

理解對象中瞭解到了兩種最簡單的建立對象的方式,本篇詳細討論Js中各類建立對象的方法。javascript

建立對象

重點須要搞清楚構造函數模式原型模式組合使用兩種模式的建立對象實例方法。(明白前兩個其實大概就明白瞭如何組合使用)html

一、工廠模式

工廠模式是一種普遍使用的設計模式, 建立對象的工廠模式,簡單地理解就是new Object()建立對象的具體過程封裝爲一個函數前端

function CreatSomething(){
    const o = new object();
    o.propertyName1='value1';
    o.propertyName2='value2';
    ...
    o.functionName=function (){
        console.log(this.propertyName1);
    }
}
複製代碼

工廠模式存在的問題是,沒有解決對象識別的問題(沒法判斷一個對象是由哪一個函數實例化的),所以用的也很少,做爲一個瞭解。java

二、構造函數模式

2.一、普通構造函數模式

經過Js的一些內置對象能夠建立對象實例,如ObjectArray等,也能夠自定義構造函數,如:設計模式

funtion Something(val,num){
    this.propertyName1=val;
    this.propertyName2=num;
    ...
    this.functionName=function (){
        console.log(this.propertyName1);
    }
}
const something1=new Something('val1',21);
const something2=new Something('val2',20);
複製代碼

與工廠模式的區別在於:瀏覽器

  • 能夠不用顯式地建立對象(緣由是被new承包了) ...=new Object()
  • 屬性方法賦給了this對象
  • 能夠不return新對象

因此相比工廠模式,使用構造函數建立對象實例更簡潔,高效。bash

那麼,構造函數是如何將屬性和方法賦給實例對象的呢?
關鍵在於:app

2.二、new操做符

對於new操做符,我以爲理解下其執行步驟,應該就清楚了函數

  • (1) 建立一個新對象
  • (2) 將構造函數的做用域賦給新對象(將this綁定到這個新建立的對象)
  • (3) 執行構造函數中的代碼(將屬性和方法添加到這個新對象)
  • (4) 返回該對象

補充:模擬一個new操做符的實現(建議瞭解清楚原型以後再回過頭來看)oop

function myNew(func){
    const objNull={};  //新對象
    if (func.prototype !== null){
        obj.__proto__=func.prototype; 
    }
    const obj=func.apply(res,Array.prototype.slice.call(arguments,1));  //綁定this
    if ((typeof obj === "object" || typeof obj === "function") && obj !==null){
        return obj;
    }
    return objNull;
    
}

複製代碼

在StackOverflow查閱new的時候看到一個評論戳中笑點...

2.三、思考:構造函數建立對象實例存在的問題?

簡單來講,構造函數的問題在其對象的方法上。

三、原型模式

3.一、理解原型對象

咱們建立的每個函數都有一個prototype指針,指向一個對象(即原型對象),包含由當前函數派生出的全部實例共享的屬性和方法

當調用構造函數建立實例後,實例內部將會包含一個[[prototype]]指針(瀏覽器中的實現是__proto__),指向其構造函數的原型對象prototype

因此簡單總結下,

  • 實例.__proto__=構造函數.prototype
  • 另外ES5中封裝了一個方法,MDN建議使用這種方式來操做
    • Object.getPrototypeOf(實例)==構造函數.prototype
function Person(){...}
const someone=new Person();

someone.__proto__===Person.prototype                            //true
Object.getPrototypeOf(someone)===Person.prototype               //true
複製代碼

3.二、普通原型模式

function Person(){
    
}
Person.prototype.property1=val1;
Person.prototype.property2=val2;
Person.prototype.funcName=function (){
    console.log(this.property1)
};

const someone = new Person();
someone.fucName()  // 輸出val1

複製代碼

3.三、內置對象的原型

Object Array Date RegExp FUnction 

基本包裝類型
Boolean Number String

單體內置對象
Global Math
複製代碼

3.四、思考:原型模式建立對象實例存在的問題?

對象中值爲引用類型的屬性會被各實例共享,也就是說在原型模式下,改變一個實例對象的 引用類型屬性值會影響到其餘全部實例對象。

四、組合使用構造韓式和原型模式

更多建立對象實例的方式

動態原型模式

寄生構造函數模式

穩妥構造函數模式

小結

此處應該有個小結,不過還沒想好該寫些什麼。

水平有限,不許確的地方,歡迎指正。

參考:

相關文章
相關標籤/搜索