国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js面向對象淺談(一)

lastSeries / 2055人閱讀

摘要:引言對于面向對象,相信大家一定不陌生。創建對象面向對象第一步是什么答創建對象。構造函數優于工廠模式也是在于它可以通過辨識出一類的對象。

引言

對于面向對象,相信大家一定不陌生。最近看了一些關于es6面向對象的知識,正好通過這篇文章把關于面向對象的東西給串起來分享給大家。

什么是對象

很多人會鄙視我,說你這篇文章是騙騙剛入行的小朋友的吧,什么是對象我還能不知道?罵我的吃瓜群眾先冷靜一下,你可能對對象一無所知。

{
    name: "李小花",
    sayname () {
        console.log(this.name)
    }
}

這是我們最常見的對象,這個對象是通過對象字面量形式創建的。

對象的含義是無序的集合,其屬性可以包含基本值、對象或者函數。

屬性類型

js中有兩種內置的屬性,數據屬性和訪問器屬性,這兩個屬性是只有內部才能訪問的屬性,所以這些屬性都放在了兩對方括號中,如[[enumerable]],大家在vue中經常

數據屬性
數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有 4 個描述其行為的特性。

[[Configurable]]:表示能否通過 delete
刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。

[[Enumerable]]:表示能否通過 for-in 循環返回屬性。

[[Writable]]:表示能否修改屬性的值。

[[Value]]:包含這個屬性的值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為
undefined。

現在有一個對象通過字面量創建

     var person =  {
         name: "張全蛋"
     }
     

[[Configurable]]、[[Enumerable]]、[[Writable]]屬性都會被設置為true,[[Value]]被設置為了‘張全蛋’。如果想修改這幾個屬性任意一個值,必須使用大名鼎鼎的Object.defineProperty()方法,為啥說它大名鼎鼎,因為如果你接觸過vue,就知道他核型就是通過這個方法實現的。

var person = {};

Object.defineProperty(person, "name", {
    writable: false,
    value: "張全蛋"
})
Object {name: "張全蛋"}

現在的name屬性是只讀的,如果是嚴格模式的話,

這樣做還會報錯。同樣的也適用于其他屬性,我這里就不一一演示了。

注意??,Object.defineProperty()方法只有現代瀏覽器才支持,IE8只是部分實現。

訪問器屬性

訪問器屬性不包含數據值,它們包含一對 getter 和 setter 函數(這兩個函數都不是必須的)。在讀取訪問器屬性時,會調用
getter 函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用 setter
并傳入新值,這個函數負責決定如何處理數據。訪問器屬性有如下 4 個特性。

[[Configurable]]:表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。

[[Enumerable]]:表示能否通過 for-in 循環返回屬性。

[[Get]]:在讀取屬性時調用的函數。默認值為 undefined。

[[Set]]:在寫入屬性時調用的函數。默認值為 undefined。

訪問只能通過bject.defineProperty()方法來定義。

var book = {
  _year: 2004,
  edition: 1
};

Object.defineProperty(book, "year", {
  get: function() {
    return this._year;
  },
  set: function(newValue) {
    if (newValue > 2004) {
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
});

book.year = 2005;
alert(book.edition);  // 2
alert(book.year); // 2005

訪問器屬性 year 則包含一個 getter 函數和一個 setter 函數。getter 函數返回 _year 的值,setter 函數通過計算來確定正確的版本。因此,把 year 屬性修改為 2005 會導致 _year 變成 2005,而 edition 變為 2。這是使用訪問器屬性的常見方式,即設置一個屬性的值會導致其他屬性發生變化。

注意??,訪問器屬性只有IE9以上才支持,這就是為什么VUE只能支持到IE9的原因。

創建對象

js面向對象第一步是什么?答:創建對象。創建對象有很多中方式,我們最常用的是對象字面量來創建對象,var obj = {},你看我這不就創建了一個對象了嗎,我還干嘛要繼續了解那些奇葩的方法呢?這么想的人活該單身,多掌握些找對象只有好處沒有壞處哈。正經的,高階上有這么一句話,使用對象字面量創建單個對象,有個明顯的缺點,使用同一個接口創建很多對象,會產生大量重復的代碼。為了解決這個問題,我們需要了解下面?這些方式。

工廠模式

工廠模式很簡單,貼上一段代碼。

function createPerson (name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function () {
        alert(this.name)
    }
    return o;
}
var person1 = createPerson("鐵蛋", 20, "工頭")

var person2 = createPerson("李四", 30, "挖掘機駕駛員")

工廠模式的優點不必多說,如果我想創建兩個對象,上面同樣有name、age、job屬性,這樣就省去了創建包含同樣屬性多個對象的麻煩,但是卻沒有解決對象識別的問題。
有人會問,對象識別是什么鬼。我們創建對象是為了模仿類的概念,這里的person1,person2應該都屬于“人”一類,但是顯然我們現在沒辦法將他們歸為一類,所以這個時候逼格更高的方法出現了。

構造函數模式
 function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        alert(this.name)
    }
}
var person1 = new Person("鐵蛋", 20, "工頭")
var person2 = new Person("李四", 30, "挖掘機駕駛員")

這里有個顯然很突出的地方,就是這個Person的P是大寫的,其實大寫不是必須的,據說這種習慣是很多后端程序員轉前端帶過來的。構造函數模式跟工廠模式不一樣的地方還在于,沒有用new Object顯式地創建對象,同樣沒有return語句。
那我們在new完一個構造函數,實則產生一個實例,我們new一個構造函數,會經歷以下神奇的四步。

創建對象 將this指向這個新對象 為這個對象添加屬性 返回這個對象

person1、person2 是我們通過 new Person這個構造函數得到的,所以這兩個的構造函數都是Person,constructor(構造函數)屬性就都是Person,我以前一直都不能理解constructor是什么東西,現在才理解原來constructor的中文翻譯就是構造函數?,也難怪我英文最熟的一句就是"hello kugou"了。我們可以通過使用instanceof操作符來檢測對象的類型。

 let arr = new Array(2)
 arr instanceof Array  // true
 arr instanceof Object // true

構造函數優于工廠模式也是在于它可以通過instanceof辨識出一類的對象。

接下來大家看一段一般沒品的面試官會考的問題

this.name = "張全蛋"
function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        alert(this.name)
    }
}
var person1 = new Person("鐵蛋", 20, "工頭")
var person2 = Person("李小花", 30, "廠花")

person1.sayName()  // 鐵蛋
person2.sayName() // 報錯

我們首先要確定一個概念,構造函數也是函數,如果不用new 的方式來調用它,它跟普通函數沒有半毛錢的區別,我們知道在函數的作用域是window,所以this指向的是window,所以這段代碼person2對象this就是window,window沒有sayName屬性,所以會報錯。如果通過的是new方式調用的話,我們上面也講了,為將this賦值給這個對象,所以this就是person1這個實例。那么構造函數是不是沒有缺點呢?顯然是不對的,因為我已經這么問了。構造函數的缺點,每個方法都要在實例上重新創建一遍,js中函數也是對象,定義函數就是實例化對象

function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function () {
        alert(this.name)
    }
}

每次new一個function就會多一次標識符解析,標識符(通常指命名)的解析是有代價的,實際上沒有那種計算機操作可以不產生性能開銷。在執行環境的作用域鏈(扯到作用域鏈就一定會扯到閉包問題,以后有空再仔細聊聊閉包)中,一個標識符所在的位置越深,它的讀寫速度也就越慢。也就是說函數中讀寫局部變量總是最快的,而讀寫全局變量總是最慢的。因為全局變量總是在執行環境作用域的末端。其實我們可以將函數移出來當全局函數來處理,但那樣會造成全局函數污染,這里就不多做介紹。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83013.html

相關文章

  • js面向對象淺談(三)

    摘要:還有一個問題,就是不能在創建子類性時,像父類型的構造函數傳遞參數。組合繼承將原型鏈和借用構造函數組合到一起,發揮兩者之長的一張繼承模式,下面來看個例子。組合繼承最大的問題是無論在什么情況下,都會調用兩次父類型構造函數。 繼承 繼承是面向對象語言中特別重要的概念,js的繼承主要是靠原型鏈實現的。 原型鏈!!! 看到我給標題打了三個嘆號嗎,這里真的很重要!這里真的很重要!這里真的很重要!j...

    awkj 評論0 收藏0
  • js面向對象淺談(二)

    摘要:我們通過這個構造函數為原型對象添加其他方法和屬性。這個屬性存在與實例與構造函數的原型對象上直接,而不存在于實例與構造函數之間。李小花班花張全蛋張全蛋李小花李小花我們在遍歷對象的的屬性的時候,經常需要判斷屬性是否來自于對象的原型還是屬性。 引言 上面說了創建對象有字面量方式和工廠模式還有構造函數模式,結果發現他們都各自有缺點,所以下面再給大家介紹幾種創建對象的方式,爭取能找到一種無痛的模...

    Yuanf 評論0 收藏0
  • 淺談JavaScript的面向對象和它的封裝、繼承、多態

    摘要:會造成內存浪費的問題構造函數繼承聲明父類聲明子類生成實例組合式繼承組合式繼承是汲取了兩者的優點,既避免了內存浪費,又使得每個實例化的子類互不影響。 寫在前面 既然是淺談,就不會從原理上深度分析,只是幫助我們更好地理解... 面向對象與面向過程 面向對象和面向過程是兩種不同的編程思想,剛開始接觸編程的時候,我們大都是從面向過程起步的,畢竟像我一樣,大家接觸的第一門計算機語言大概率都是C語...

    MAX_zuo 評論0 收藏0
  • 淺談JavaScript面向對象

    摘要:不必在構造函數中定義對象實例的信息。其次,按照一切事物皆對象的這餓極本的面向對象的法則來說,類本身并不是一個對象,然而原型方式的構造函數和原型本身也是個對象。第二個問題就是在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。 前言 對象(Object)應該算是js中最為重要的部分,也是js中非常難懂晦澀的一部分。更是面試以及框架設計中各出沒。寫這篇文章,主要參考與JavaScrip...

    cyixlq 評論0 收藏0

發表評論

0條評論

lastSeries

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<