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

資訊專欄INFORMATION COLUMN

JavaScript 工廠函數(shù) vs 構(gòu)造函數(shù)

RayKr / 2118人閱讀

摘要:當(dāng)談到語言與其他編程語言相比時,你可能會聽到一些令人困惑東西,其中之一是工廠函數(shù)和構(gòu)造函數(shù)。好的,讓我們用構(gòu)造函數(shù)做同樣的實(shí)驗(yàn)。當(dāng)我們使用工廠函數(shù)創(chuàng)建對象時,它的指向,而當(dāng)從構(gòu)造函數(shù)創(chuàng)建對象時,它指向它的構(gòu)造函數(shù)原型對象。

當(dāng)談到JavaScript語言與其他編程語言相比時,你可能會聽到一些令人困惑東西,其中之一是工廠函數(shù)和構(gòu)造函數(shù)。

想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

工廠函數(shù)

所謂工廠函數(shù),就是指這些內(nèi)建函數(shù)都是類對象,當(dāng)你調(diào)用他們時,實(shí)際上是創(chuàng)建了一個類實(shí)例”。意思就是當(dāng)我調(diào)用這個函數(shù),實(shí)際上是先利用類創(chuàng)建了一個對象,然后返回這個對象。由于 Javascript 本身不是嚴(yán)格的面向?qū)ο蟮恼Z言(不包含類),實(shí)際上來說,Javascript 并沒有嚴(yán)格的“工廠函數(shù)”,但是在 Javascript中,我們能利用函數(shù)模擬類。來看下面一個例子:

function person(firstName, lastName, age) {
  const person = {};
  person.firstName = firstName;
  person.lastName = lastName;
  person.age = age;
  return person;
}

上述代碼,創(chuàng)建一個新對象,并將傳遞參數(shù)作為屬性附加到該對象上并返回新對象。 這是一個簡單的 JavaScript 工廠函數(shù)。

實(shí)際上工廠函數(shù)也很好理解了:

它是一個函數(shù)。

它用來創(chuàng)建對象。

它像工廠一樣,“生產(chǎn)”出來的函數(shù)都是“標(biāo)準(zhǔn)件”(擁有同樣的屬性)

構(gòu)造函數(shù)

不同于其它的主流編程語言,JavaScript的構(gòu)造函數(shù)并不是作為類的一個特定方法存在的;當(dāng)任意一個普通函數(shù)用于創(chuàng)建一類對象時,它就被稱作構(gòu)造函數(shù),或構(gòu)造器。一個函數(shù)要作為一個真正意義上的構(gòu)造函數(shù),需要滿足下列條件:

在函數(shù)內(nèi)部對新對象(this)的屬性進(jìn)行設(shè)置,通常是添加屬性和方法。

構(gòu)造函數(shù)可以包含返回語句(不推薦),但返回值必須是this,或者其它非對象類型的值。

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}
使用 new 關(guān)鍵字創(chuàng)建對象

正如上面所說的,我們可以使用 new 來類或者對象,那么你可能會有以下幾個問題:

我們可以在工廠函數(shù)中使用 new 關(guān)鍵字嗎?

如果我們在工廠和構(gòu)造函數(shù)中使用new關(guān)鍵字會發(fā)生什么

如果在使用構(gòu)造函數(shù)創(chuàng)建對象實(shí)例時不使用new關(guān)鍵字會發(fā)生什么

好的,試著找出以上問題的答案之前,我們先做一個小練習(xí)來理解這里面發(fā)生了什么。

使用new關(guān)鍵字同時使用工廠和構(gòu)造函數(shù)創(chuàng)建兩個對象,接著在控制臺打印這兩個對象。

使用工廠函數(shù)
function person(firstName, lastName, age){
  const person = {}
  person.firstName = firstName;
  person.lastName = lastName;
  person.age = age;
  return person;
}

const mike = new person("mike", "grand", 23);



正如我們在上述所看到的,這里的__proto__ 指向其原型對象的指針,讓我們試著找出原型對象是什么。為了找出上面mike對象的指向原型對象,讓我們做簡單的===等式檢查。

嗯,有趣的是,它指向 Object.prototype。好的,讓我們用構(gòu)造函數(shù)做同樣的實(shí)驗(yàn)。

理解 JavaScript 的原型

理解原型之前,需要記住以下幾點(diǎn)知識:

所有的引用類型(數(shù)組、對象、函數(shù)),都具有對象特性,即可自由擴(kuò)展屬性(null除外)

所有的引用類型(數(shù)組、對象、函數(shù)),都有一個__proto__屬性,屬性值是一個普通的對象

所有的函數(shù),都有一個prototype屬性,屬性值也是一個普通的對象

所有的引用類型(數(shù)組、對象、函數(shù)),__proto__屬性值指向它的構(gòu)造函數(shù)的prototype屬性值

通過代碼解釋一下:

// 要點(diǎn)一:自由擴(kuò)展屬性
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;

// 要點(diǎn)二:__proto__
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);

// 要點(diǎn)三:函數(shù)有 prototype
console.log(fn.prototype)

// 要點(diǎn)四:引用類型的 __proto__ 屬性值指向它的構(gòu)造函數(shù)的 prototype 屬性值
console.log(obj.__proto__ === Object.prototype)
使用構(gòu)造函數(shù)
注意:在JavaScript中,這些構(gòu)造函數(shù)也被稱為 constructor,因?yàn)樗鼈冇糜趧?chuàng)建對象。
function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}
const mike = new Person("mike", "grand", 23);

當(dāng)我們展開第一層的的__proto__時,它內(nèi)部還有另一個__proto__,我們再次擴(kuò)展它。

現(xiàn)在讓我們試著弄清楚原型對象是否像上面一樣。

他們是不同的。 當(dāng)我們使用工廠函數(shù)創(chuàng)建對象時,它的__proto__指向Object.prototype,而當(dāng)從構(gòu)造函數(shù)創(chuàng)建對象時,它指向它的構(gòu)造函數(shù)原型對象。 那么這里發(fā)生了什么?

new 背后所做的事

當(dāng)我們在創(chuàng)建對象時使用帶有構(gòu)造函數(shù)的new關(guān)鍵字時,new 背后所做的事不多。

new 運(yùn)算符創(chuàng)建一個用戶自定義的對象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對象的實(shí)例。 new 關(guān)鍵字會進(jìn)行如下操作:

創(chuàng)建一個空的簡單 JavaScript 對象 (即 {})

鏈接該對象(即設(shè)置該對象的構(gòu)造函數(shù))到另一個對象

將步驟1新創(chuàng)建的對象作為 this 的上下文

如果該函數(shù)沒有返回對象,則返回 this

注釋行是偽代碼,表示在 new 關(guān)鍵字,JS 背后幫我們做的事情。

function Person(firstName, lastName, age) {
    // this = {};
    // this.__proto__ = Person.prototype;

    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    
    // return this;
}

另外,讓我們看看如果將上面的隱式代碼添加到工廠函數(shù)中會發(fā)生什么。

function person(firstName, lastName, age) {
    // this = {};
    // this.__proto__ = Person.prototype; 
 
  
    const person = {};
    person.firstName = firstName;
    person.lastName = lastName;
    person.age = age;
    return person;
    
    // return this;
}

即使使用new關(guān)鍵字調(diào)用時將隱式代碼添加到工廠函數(shù)中,也不會對結(jié)果產(chǎn)生任何影響。這是因?yàn)椋捎谖覀儧]有在函數(shù)中使用 this 關(guān)鍵字,而且我們顯式地返回了一個除this之外的自定義對象,因此沒有必要使用隱式代碼。無論我們是否對工廠函數(shù)使用new關(guān)鍵字,對輸出都沒有影響。

如果忘記了 new 關(guān)鍵字怎么辦

JavaScript 中有許多概念,有時難以掌握。 new 操作符就是其中之一。 如果你不能正確理解它,那么在運(yùn)行 JavaScript 應(yīng)用程序時會產(chǎn)生令人討厭的后果。 在像 Java這 樣的語言中,嚴(yán)格限制了如何使用 new 關(guān)鍵字。 但是在 javascript 中,并不是那么嚴(yán)格,如果你不能正確理解它們可能會導(dǎo)致很多問題。

在 JavaScript 中:

可以對任何函數(shù)使用 new 運(yùn)算符

可以使用或不使用 new 關(guān)鍵字將函數(shù)作為構(gòu)造函數(shù)調(diào)用

讓我們看看上面的例子,使用和不使用 new 關(guān)鍵情況

function Person(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
const mike = new Person("mike", "grand", 23);
const bob = Person("bob", "grand", 23);

然后,如果查看創(chuàng)建的對象實(shí)例,你希望看到什么?

發(fā)生了什么? 使用 new 運(yùn)算符,正如我們所期待的一樣輸出正確的對象,但沒有new運(yùn)算符,結(jié)果是undefined 怎么可能呢?

如果你對 JavaScript 作用域 this 關(guān)鍵字的工作原理有所了解,那么你可以猜到這里發(fā)生了什么? 讓我們來看看。

看起來我們傳遞給沒有new關(guān)鍵字的函數(shù)的所有屬性都已設(shè)置為window對象。 那是因?yàn)榈侥莻€時候函數(shù)內(nèi)部的這個變量引用了globalwindow 對象,基本上我們在這里做的就是污染了全局對象。

這是你可以對你的JavaScript程序做的非常討厭的事情。 因此,使用new運(yùn)算符,JavaScript引擎將this 變量設(shè)置為引用新創(chuàng)建的對象實(shí)例,這就是為什么我們可以看到傳遞給構(gòu)造函數(shù)的所有屬性都已設(shè)置為 mike

但是在沒有new運(yùn)算符的情況下調(diào)用構(gòu)造函數(shù)的情況下,JavaScript 引擎會將 this 解釋為常規(guī)函數(shù)調(diào)用,而沒有顯式返回語句時返回undefined。 這就是理解new 運(yùn)算符在JavaScript中的工作原理非常關(guān)鍵的原因。

你的點(diǎn)贊是我持續(xù)分享好東西的動力,歡迎點(diǎn)贊!

歡迎加入前端大家庭,里面會經(jīng)常分享一些技術(shù)資源。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/104115.html

相關(guān)文章

  • 前端進(jìn)擊的巨人(七):走進(jìn)面向?qū)ο螅团c原型鏈,繼承方式

    摘要:除了以上介紹的幾種對象創(chuàng)建方式,此外還有寄生構(gòu)造函數(shù)模式穩(wěn)妥構(gòu)造函數(shù)模式。 showImg(https://segmentfault.com/img/remote/1460000018196128); 面向?qū)ο?是以 對象 為中心的編程思想,它的思維方式是構(gòu)造。 面向?qū)ο?編程的三大特點(diǎn):封裝、繼承、多態(tài): 封裝:屬性方法的抽象 繼承:一個類繼承(復(fù)制)另一個類的屬性/方法 多態(tài):方...

    wums 評論0 收藏0
  • JS程序

    摘要:設(shè)計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計模式必須要先搞懂面向?qū)ο缶幊蹋駝t只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評論0 收藏0
  • 第6章:可維護(hù)性軟件構(gòu)建方法 6.2可維護(hù)性設(shè)計模式

    摘要:抽象工廠模式將具有共同主題的對象工廠分組。對可重用性和可維護(hù)性設(shè)計模式的高層考慮創(chuàng)造性模式工廠方法模式也稱為虛擬構(gòu)造器意圖定義一個用于創(chuàng)建對象的接口,但讓子類決定實(shí)例化哪個類。 大綱 創(chuàng)造性模式 工廠方法模式創(chuàng)建對象而不指定要創(chuàng)建的確切類。 抽象工廠模式將具有共同主題的對象工廠分組。 Builder模式通過分離構(gòu)造和表示來構(gòu)造復(fù)雜的對象。 結(jié)構(gòu)模式 Bridge將抽象從其實(shí)現(xiàn)中分...

    VioletJack 評論0 收藏0
  • JavaScript面向?qū)ο驩OM 2(JavaScript 創(chuàng)建對象的工廠模式和構(gòu)造函數(shù)模式)

    摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對象經(jīng)歷了以下四個過程創(chuàng)建一個新對象構(gòu)造函數(shù)的作用域交給新對象。 ??在創(chuàng)建對象的時候,使用對象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,...

    you_De 評論0 收藏0
  • JavaScript面向?qū)ο驩OM 2(JavaScript 創(chuàng)建對象的工廠模式和構(gòu)造函數(shù)模式)

    摘要:都是構(gòu)造函數(shù)模式創(chuàng)建的原生構(gòu)造函數(shù)。使用構(gòu)造函數(shù)創(chuàng)建對象經(jīng)歷了以下四個過程創(chuàng)建一個新對象構(gòu)造函數(shù)的作用域交給新對象。 ??在創(chuàng)建對象的時候,使用對象字面量和 new Object() 構(gòu)造函數(shù)的方式創(chuàng)建一個對象是最簡單最方便的方式。但是凡是處于初級階段的事物都會不可避免的存在一個問題,沒有普適性,意思就是說我要為世界上(程序中)的所有使用到的對象都使用一遍 var xxx = {} ,...

    liuchengxu 評論0 收藏0

發(fā)表評論

0條評論

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