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

資訊專欄INFORMATION COLUMN

JavaScript深入之new的模擬實(shí)現(xiàn)

tianlai / 1614人閱讀

摘要:深入系列第十二篇,通過的模擬實(shí)現(xiàn),帶大家揭開使用獲得構(gòu)造函數(shù)實(shí)例的真相一句話介紹運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象類型之一也許有點(diǎn)難懂,我們?cè)谀M之前,先看看實(shí)現(xiàn)了哪些功能。

JavaScript深入系列第十二篇,通過new的模擬實(shí)現(xiàn),帶大家揭開使用new獲得構(gòu)造函數(shù)實(shí)例的真相

new

一句話介紹 new:

new 運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象類型之一

也許有點(diǎn)難懂,我們?cè)谀M new 之前,先看看 new 實(shí)現(xiàn)了哪些功能。

舉個(gè)例子:

// Otaku 御宅族,簡(jiǎn)稱宅
function Otaku (name, age) {
    this.name = name;
    this.age = age;

    this.habit = "Games";
}

// 因?yàn)槿狈﹀憻挼木壒?,身體強(qiáng)度讓人擔(dān)憂
Otaku.prototype.strength = 60;

Otaku.prototype.sayYourName = function () {
    console.log("I am " + this.name);
}

var person = new Otaku("Kevin", "18");

console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60

person.sayYourName(); // I am Kevin

從這個(gè)例子中,我們可以看到,實(shí)例 person 可以:

訪問到 Otaku 構(gòu)造函數(shù)里的屬性

訪問到 Otaku.prototype 中的屬性

接下來,我們可以嘗試著模擬一下了。

因?yàn)?new 是關(guān)鍵字,所以無法像 bind 函數(shù)一樣直接覆蓋,所以我們寫一個(gè)函數(shù),命名為 objectFactory,來模擬 new 的效果。用的時(shí)候是這樣的:

function Otaku () {
    ……
}

// 使用 new
var person = new Otaku(……);
// 使用 objectFactory
var person = objectFactory(Otaku, ……)
初步實(shí)現(xiàn)

分析:

因?yàn)?new 的結(jié)果是一個(gè)新對(duì)象,所以在模擬實(shí)現(xiàn)的時(shí)候,我們也要建立一個(gè)新對(duì)象,假設(shè)這個(gè)對(duì)象叫 obj,因?yàn)?obj 會(huì)具有 Otaku 構(gòu)造函數(shù)里的屬性,想想經(jīng)典繼承的例子,我們可以使用 Otaku.apply(obj, arguments)來給 obj 添加新的屬性。

在 JavaScript 深入系列第一篇中,我們便講了原型與原型鏈,我們知道實(shí)例的 __proto__ 屬性會(huì)指向構(gòu)造函數(shù)的 prototype,也正是因?yàn)榻⑵疬@樣的關(guān)系,實(shí)例可以訪問原型上的屬性。

現(xiàn)在,我們可以嘗試著寫第一版了:

// 第一版代碼
function objectFactory() {

    var obj = new Object(),

    Constructor = [].shift.call(arguments);

    obj.__proto__ = Constructor.prototype;

    Constructor.apply(obj, arguments);

    return obj;

};

在這一版中,我們:

用new Object() 的方式新建了一個(gè)對(duì)象 obj

取出第一個(gè)參數(shù),就是我們要傳入的構(gòu)造函數(shù)。此外因?yàn)?shift 會(huì)修改原數(shù)組,所以 arguments 會(huì)被去除第一個(gè)參數(shù)

將 obj 的原型指向構(gòu)造函數(shù),這樣 obj 就可以訪問到構(gòu)造函數(shù)原型中的屬性

使用 apply,改變構(gòu)造函數(shù) this 的指向到新建的對(duì)象,這樣 obj 就可以訪問到構(gòu)造函數(shù)中的屬性

返回 obj

更多關(guān)于:

原型與原型鏈,可以看《JavaScript深入之從原型到原型鏈》

apply,可以看《JavaScript深入之call和apply的模擬實(shí)現(xiàn)》

經(jīng)典繼承,可以看《JavaScript深入之繼承》

復(fù)制以下的代碼,到瀏覽器中,我們可以做一下測(cè)試:

function Otaku (name, age) {
    this.name = name;
    this.age = age;

    this.habit = "Games";
}

Otaku.prototype.strength = 60;

Otaku.prototype.sayYourName = function () {
    console.log("I am " + this.name);
}

function objectFactory() {
    var obj = new Object(),
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    return obj;
};

var person = objectFactory(Otaku, "Kevin", "18")

console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60

person.sayYourName(); // I am Kevin

[]~( ̄▽ ̄)~**

返回值效果實(shí)現(xiàn)

接下來我們?cè)賮砜匆环N情況,假如構(gòu)造函數(shù)有返回值,舉個(gè)例子:

function Otaku (name, age) {
    this.strength = 60;
    this.age = age;

    return {
        name: name,
        habit: "Games"
    }
}

var person = new Otaku("Kevin", "18");

console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // undefined
console.log(person.age) // undefined

在這個(gè)例子中,構(gòu)造函數(shù)返回了一個(gè)對(duì)象,在實(shí)例 person 中只能訪問返回的對(duì)象中的屬性。

而且還要注意一點(diǎn),在這里我們是返回了一個(gè)對(duì)象,假如我們只是返回一個(gè)基本類型的值呢?

再舉個(gè)例子:

function Otaku (name, age) {
    this.strength = 60;
    this.age = age;

    return "handsome boy";
}

var person = new Otaku("Kevin", "18");

console.log(person.name) // undefined
console.log(person.habit) // undefined
console.log(person.strength) // 60
console.log(person.age) // 18

結(jié)果完全顛倒過來,這次盡管有返回值,但是相當(dāng)于沒有返回值進(jìn)行處理。

所以我們還需要判斷返回的值是不是一個(gè)對(duì)象,如果是一個(gè)對(duì)象,我們就返回這個(gè)對(duì)象,如果沒有,我們?cè)摲祷厥裁淳头祷厥裁础?/p>

再來看第二版的代碼,也是最后一版的代碼:

// 第二版的代碼
function objectFactory() {

    var obj = new Object(),

    Constructor = [].shift.call(arguments);

    obj.__proto__ = Constructor.prototype;

    var ret = Constructor.apply(obj, arguments);

    return typeof ret === "object" ? ret : obj;

};
下一篇文章

JavaScript深入之類數(shù)組對(duì)象與arguments

相關(guān)鏈接

《JavaScript深入之從原型到原型鏈》

《JavaScript深入之call和apply的模擬實(shí)現(xiàn)》

《JavaScript深入之繼承》

深入系列

JavaScript深入系列目錄地址:https://github.com/mqyqingfeng/Blog。

JavaScript深入系列預(yù)計(jì)寫十五篇左右,旨在幫大家捋順JavaScript底層知識(shí),重點(diǎn)講解如原型、作用域、執(zhí)行上下文、變量對(duì)象、this、閉包、按值傳遞、call、apply、bind、new、繼承等難點(diǎn)概念。

如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,?qǐng)務(wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎star,對(duì)作者也是一種鼓勵(lì)。

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

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

相關(guān)文章

  • JavaScript深入bind模擬實(shí)現(xiàn)

    摘要:也就是說當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)的時(shí)候,時(shí)指定的值會(huì)失效,但傳入的參數(shù)依然生效。構(gòu)造函數(shù)效果的優(yōu)化實(shí)現(xiàn)但是在這個(gè)寫法中,我們直接將,我們直接修改的時(shí)候,也會(huì)直接修改函數(shù)的。 JavaScript深入系列第十一篇,通過bind函數(shù)的模擬實(shí)現(xiàn),帶大家真正了解bind的特性 bind 一句話介紹 bind: bind() 方法會(huì)創(chuàng)建一個(gè)新函數(shù)。當(dāng)這個(gè)新函數(shù)被調(diào)用時(shí),bind() 的第一個(gè)參數(shù)...

    FingerLiu 評(píng)論0 收藏0
  • JavaScript深入系列15篇正式完結(jié)!

    摘要:寫在前面深入系列共計(jì)篇已經(jīng)正式完結(jié),這是一個(gè)旨在幫助大家,其實(shí)也是幫助自己捋順底層知識(shí)的系列。深入系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵(lì)指正。 寫在前面 JavaScript 深入系列共計(jì) 15 篇已經(jīng)正式完結(jié),這是一個(gè)旨在幫助大家,其實(shí)也是幫助自己捋順 JavaScript 底層知識(shí)的系列。重點(diǎn)講解了如原型、作用域、執(zhí)行上下文、變量對(duì)象、this、...

    fxp 評(píng)論0 收藏0
  • JavaScript深入繼承多種方式和優(yōu)缺點(diǎn)

    摘要:深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。優(yōu)點(diǎn)融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是中最常用的繼承模式。寄生組合式繼承為了方便大家閱讀,在這里重復(fù)一下組合繼承的代碼組合繼承最大的缺點(diǎn)是會(huì)調(diào)用兩次父構(gòu)造函數(shù)。 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎...

    JackJiang 評(píng)論0 收藏0
  • JavaScript深入call和apply模擬實(shí)現(xiàn)

    摘要:深入系列第十篇,通過和的模擬實(shí)現(xiàn),帶你揭開和改變的真相一句話介紹方法在使用一個(gè)指定的值和若干個(gè)指定的參數(shù)值的前提下調(diào)用某個(gè)函數(shù)或方法。如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤剑?qǐng)務(wù)必給予指正,十分感謝。 JavaScript深入系列第十篇,通過call和apply的模擬實(shí)現(xiàn),帶你揭開call和apply改變this的真相 call 一句話介紹 call: call() 方法在使用一個(gè)指定的 this...

    miya 評(píng)論0 收藏0
  • JavaScript深入創(chuàng)建對(duì)象多種方式以及優(yōu)缺點(diǎn)

    摘要:深入系列第十四篇,講解創(chuàng)建對(duì)象的各種方式,以及優(yōu)缺點(diǎn)。也就是說打著構(gòu)造函數(shù)的幌子掛羊頭賣狗肉,你看創(chuàng)建的實(shí)例使用都無法指向構(gòu)造函數(shù)這樣方法可以在特殊情況下使用。 JavaScript深入系列第十四篇,講解創(chuàng)建對(duì)象的各種方式,以及優(yōu)缺點(diǎn)。 寫在前面 這篇文章講解創(chuàng)建對(duì)象的各種方式,以及優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,因?yàn)椤禞avaScript高級(jí)程序設(shè)計(jì)》寫得真是太好了! 1....

    Terry_Tai 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<