成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

js面向?qū)ο鬁\談(一)

lastSeries / 2060人閱讀

摘要:引言對于面向?qū)ο?,相信大家一定不陌生。?chuàng)建對象面向?qū)ο蟮谝徊绞鞘裁创饎?chuàng)建對象。構(gòu)造函數(shù)優(yōu)于工廠模式也是在于它可以通過辨識出一類的對象。

引言

對于面向?qū)ο?,相信大家一定不陌生。最近看了一些關(guān)于es6面向?qū)ο蟮闹R,正好通過這篇文章把關(guān)于面向?qū)ο蟮臇|西給串起來分享給大家。

什么是對象

很多人會鄙視我,說你這篇文章是騙騙剛?cè)胄械男∨笥训陌桑裁词菍ο笪疫€能不知道?罵我的吃瓜群眾先冷靜一下,你可能對對象一無所知。

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

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

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

屬性類型

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

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

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

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

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

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

現(xiàn)在有一個對象通過字面量創(chuàng)建

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

[[Configurable]]、[[Enumerable]]、[[Writable]]屬性都會被設(shè)置為true,[[Value]]被設(shè)置為了‘張全蛋’。如果想修改這幾個屬性任意一個值,必須使用大名鼎鼎的Object.defineProperty()方法,為啥說它大名鼎鼎,因?yàn)槿绻憬佑|過vue,就知道他核型就是通過這個方法實(shí)現(xiàn)的。

var person = {};

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

現(xiàn)在的name屬性是只讀的,如果是嚴(yán)格模式的話,

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

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

訪問器屬性

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

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

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

[[Get]]:在讀取屬性時調(diào)用的函數(shù)。默認(rèn)值為 undefined。

[[Set]]:在寫入屬性時調(diào)用的函數(shù)。默認(rèn)值為 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 函數(shù)和一個 setter 函數(shù)。getter 函數(shù)返回 _year 的值,setter 函數(shù)通過計(jì)算來確定正確的版本。因此,把 year 屬性修改為 2005 會導(dǎo)致 _year 變成 2005,而 edition 變?yōu)?2。這是使用訪問器屬性的常見方式,即設(shè)置一個屬性的值會導(dǎo)致其他屬性發(fā)生變化。

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

創(chuàng)建對象

js面向?qū)ο蟮谝徊绞鞘裁矗看穑簞?chuàng)建對象。創(chuàng)建對象有很多中方式,我們最常用的是對象字面量來創(chuàng)建對象,var obj = {},你看我這不就創(chuàng)建了一個對象了嗎,我還干嘛要繼續(xù)了解那些奇葩的方法呢?這么想的人活該單身,多掌握些找對象只有好處沒有壞處哈。正經(jīng)的,高階上有這么一句話,使用對象字面量創(chuàng)建單個對象,有個明顯的缺點(diǎn),使用同一個接口創(chuàng)建很多對象,會產(chǎn)生大量重復(fù)的代碼。為了解決這個問題,我們需要了解下面?這些方式。

工廠模式

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

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, "挖掘機(jī)駕駛員")

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

構(gòu)造函數(shù)模式
 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, "挖掘機(jī)駕駛員")

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

創(chuàng)建對象 將this指向這個新對象 為這個對象添加屬性 返回這個對象

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

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

構(gòu)造函數(shù)優(yōu)于工廠模式也是在于它可以通過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() // 報(bào)錯

我們首先要確定一個概念,構(gòu)造函數(shù)也是函數(shù),如果不用new 的方式來調(diào)用它,它跟普通函數(shù)沒有半毛錢的區(qū)別,我們知道在函數(shù)的作用域是window,所以this指向的是window,所以這段代碼person2對象this就是window,window沒有sayName屬性,所以會報(bào)錯。如果通過的是new方式調(diào)用的話,我們上面也講了,為將this賦值給這個對象,所以this就是person1這個實(shí)例。那么構(gòu)造函數(shù)是不是沒有缺點(diǎn)呢?顯然是不對的,因?yàn)槲乙呀?jīng)這么問了。構(gòu)造函數(shù)的缺點(diǎn),每個方法都要在實(shí)例上重新創(chuàng)建一遍,js中函數(shù)也是對象,定義函數(shù)就是實(shí)例化對象

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

每次new一個function就會多一次標(biāo)識符解析,標(biāo)識符(通常指命名)的解析是有代價的,實(shí)際上沒有那種計(jì)算機(jī)操作可以不產(chǎn)生性能開銷。在執(zhí)行環(huán)境的作用域鏈(扯到作用域鏈就一定會扯到閉包問題,以后有空再仔細(xì)聊聊閉包)中,一個標(biāo)識符所在的位置越深,它的讀寫速度也就越慢。也就是說函數(shù)中讀寫局部變量總是最快的,而讀寫全局變量總是最慢的。因?yàn)槿肿兞靠偸窃趫?zhí)行環(huán)境作用域的末端。其實(shí)我們可以將函數(shù)移出來當(dāng)全局函數(shù)來處理,但那樣會造成全局函數(shù)污染,這里就不多做介紹。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83013.html

相關(guān)文章

  • js面向對象淺談(三)

    摘要:還有一個問題,就是不能在創(chuàng)建子類性時,像父類型的構(gòu)造函數(shù)傳遞參數(shù)。組合繼承將原型鏈和借用構(gòu)造函數(shù)組合到一起,發(fā)揮兩者之長的一張繼承模式,下面來看個例子。組合繼承最大的問題是無論在什么情況下,都會調(diào)用兩次父類型構(gòu)造函數(shù)。 繼承 繼承是面向?qū)ο笳Z言中特別重要的概念,js的繼承主要是靠原型鏈實(shí)現(xiàn)的。 原型鏈?。?! 看到我給標(biāo)題打了三個嘆號嗎,這里真的很重要!這里真的很重要!這里真的很重要!j...

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

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

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

    摘要:會造成內(nèi)存浪費(fèi)的問題構(gòu)造函數(shù)繼承聲明父類聲明子類生成實(shí)例組合式繼承組合式繼承是汲取了兩者的優(yōu)點(diǎn),既避免了內(nèi)存浪費(fèi),又使得每個實(shí)例化的子類互不影響。 寫在前面 既然是淺談,就不會從原理上深度分析,只是幫助我們更好地理解... 面向?qū)ο笈c面向過程 面向?qū)ο蠛兔嫦蜻^程是兩種不同的編程思想,剛開始接觸編程的時候,我們大都是從面向過程起步的,畢竟像我一樣,大家接觸的第一門計(jì)算機(jī)語言大概率都是C語...

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

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

    cyixlq 評論0 收藏0

發(fā)表評論

0條評論

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