1. 程式人生 > >談一談JavaScript面向物件

談一談JavaScript面向物件

面向物件概念理解

面嚮物件語言有個標誌=>它們都具有類的概念,通過類可以建立任意多個具有相同屬性和方法的物件。
面向物件有三大特性

   封裝
   繼承
   多型

但JS中物件與純面嚮物件語言中的物件是不同的
JS中的物件:
無序屬性的集合,其屬性可以包含基本值、物件或者函式。
可以簡單理解為JS的物件是一組無序的值,其中的屬性或方法都有一個名字,根據這個名字可以訪問相對映的值(值可以是基本值/物件/方法)。

建立物件的基本方法

建立物件的方式,我們前面在講原型鏈的時候說過
物件字面量

  const person = {
    name: "姓名"
, nickName: "暱稱", doSth() { console.log("做什麼事情") } } person.doSth()

建立物件的屬性名並不強制使用引號包裹,除了以下幾種情況
1.屬性名中包含空格
2.屬性名中包含連字元(中劃線)
3.屬性名中包含保留字

const obj={
    "hello world":"包含了空格",
    "hello-world":"包含了連字元",
    "if":"這是保留字"
}

new 例項化一個物件

通過new運算子建立並例項化一個新物件,new後面是一個建構函式

const
person= new Object() person.name = "姓名" person.nickname = "暱稱" person.doSth = function () { console.log("做什麼事情"); }

兩種建立方法是一樣的
建立物件通過以上兩種方式似乎足夠了,但是當場景稍微複雜一點,問題就顯現出來了
當我門建立很多結構相同的物件時,會產生大量的重複程式碼,為了解決這個問題,出現了一個解決方案

工廠模式

工廠模式抽象了建立具體物件的過程,因為javascript無法建立類,開發人員就發明了一種函式,用函式來封裝以特定介面建立物件

function
createPerson(name,nickname,doSth) { const obj = new Object() obj.name = name obj.nickname = nickname obj.doSth = function () { console.log(doSth); } return obj } const LJJ = createPerson("劉家軍","大神仙","陪小仙女") const YH = createPerson("袁姮","小仙女","陪大神仙") console.log(LJJ) console.log(YH)

看下輸出:
在這裡插入圖片描述
LJJ和YH都直接繼承自Object例項,工廠模式就是像工廠一樣來建立物件,建立的每一個物件都是通過new Object()來建立的
後來,開發人員有發現了更好的模式

建構函式模式

我們之前討論過,通過使用自定義建構函式來例項化物件

function Person(name, nickname, doSth) {
    this.name = name
    this.nickname = nickname
    this.doSth = function () {
        console.log(doSth);
    }
}
const LJJ = new Person("劉家軍","大神仙","陪小仙女")
const YH = new Person("袁姮","小仙女","陪大神仙")
console.log(LJJ);
console.log(YH)

注意⚠️:建立自定義建構函式,函式名首字母大寫,用來和非建構函式進行區分
我們繼續看下輸出:
在這裡插入圖片描述
LJJ和YH 都是通過Person例項化出來的,所以LJJ與YH先繼承自Person
要建立Person的新例項,必須使用new操作符,以這種方式呼叫建構函式實際上會經歷以下四個步驟:
1.建立一個新物件
2.將建構函式的作用域賦給新物件(因此this就指向了這個新物件)
3.執行建構函式中的程式碼(為這個新物件新增屬性)
4.返回新物件

LJJ和YH都是Person的例項,同時也是Object的例項
instanceof用於判斷一個變數是否某個物件的例項

console.log(LJJ instanceof Person) // => true
console.log(LJJ instanceof Object) // => true
console.log(YH instanceof Person) // => true
console.log(YH instanceof Object) // => true

屬性和方法(公有 && 私有)

我們將屬性和方法繫結在了建構函式Person中的this上,LJJ和YH都可以訪問這些屬性
繫結在this上的屬性我們稱之為公有屬性
繫結在this上的方法我們稱之為公有方法
也就是說通過建構函式Person例項化出來的物件是可以方位公有屬性和公有方法的
既然有公有屬性和公有方法,就一定會有私有屬性和私有方法
我們做一下調整

function Person(name, nickname, doSth) {
// 私有屬性 只能在物件建構函式內部使用
   let privateProperty = "私有屬性"   
   function privateMethod() { console.log("私有方法") }
   
 //公有屬性 例項化物件後使用  
    this.name = name
    this.nickname = nickname
    this.doSth = function () {
        console.log(doSth);
    }
}

// 新增靜態公有屬性
Person.staticProperty = "靜態屬性"
Person.staticMethod = function() { console.log('靜態方法') }

 // 新增原型屬性    
 Person.prototype.proProperty = "原型屬性"
 Person.prototype.proMethod = function() { console.log('原型方法') }
 
const LJJ = new Person("劉家軍","公有屬性","陪小仙女")

    console.log(LJJ);
    console.log('staticProperty靜態屬性:',LJJ.staticProperty);
    console.log("staticMethod靜態方法:",LJJ.staticMethod);
    console.log("proProperty原型屬性:",LJJ.proProperty);
    console.log("proMethod原型方法:",LJJ.proMethod);

輸出:
在這裡插入圖片描述
靜態公有屬性與靜態公有方法(例項化的物件無法訪問)
通過原型鏈新增的(屬性/方法)是公有(屬性/方法)(例項化的物件可以訪問)

預知後事如何 且看下次分解