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

資訊專欄INFORMATION COLUMN

JavaScript之對(duì)象創(chuàng)建

Michael_Lin / 2365人閱讀

摘要:在構(gòu)造函數(shù)的內(nèi)部,的指向是新創(chuàng)建的對(duì)象。如果構(gòu)造函數(shù)沒(méi)有顯式的表達(dá)式,則會(huì)隱式的返回新創(chuàng)建的對(duì)象對(duì)象。原型模式在構(gòu)造函數(shù)模式中提到每次之后創(chuàng)建的新的對(duì)象是互相獨(dú)立的,是獨(dú)享的。

1.構(gòu)造函數(shù)模式

JavaScript中的構(gòu)造函數(shù)是通過(guò)new調(diào)用的,也就是說(shuō),通過(guò)new關(guān)鍵字調(diào)用的函數(shù)都被認(rèn)為是構(gòu)造函數(shù)。

在構(gòu)造函數(shù)的內(nèi)部,this的指向是新創(chuàng)建的對(duì)象Object

如果構(gòu)造函數(shù)沒(méi)有顯式的return表達(dá)式,則會(huì)隱式的返回新創(chuàng)建的對(duì)象——this對(duì)象。

function Foo () {
  this.name = "rccoder";
}

Foo.prototype.test = function () {
  console.log (this.name);
}

var bar = new Foo();

bar.name;    // rccoder
bar.test();  // rccoder

在構(gòu)造函數(shù)中,顯式的return會(huì)影響返回的值,但是僅限于返回的是 一個(gè)對(duì)象。當(dāng)返回值不是一個(gè)對(duì)象的時(shí)候,實(shí)際上會(huì)返回一個(gè)新創(chuàng)建的對(duì)象;當(dāng)返回值就是一個(gè)對(duì)象的時(shí)候,返回的不是新創(chuàng)建的對(duì)象,而是本身就要返回的那個(gè)對(duì)象

function Foo () {
  return 2;
}

new Foo();    // Foo {} 返回的不是2,而是新創(chuàng)建了一個(gè)對(duì)象

function Bar () {
  this.name = "rccoder";
  return {
    foo: 1
  }
}

new Bar();   // Object {foo: 1}  返回要返回的那個(gè)對(duì)象
(new Bar()).name  // undefined
(new Bar()).foo   // 1

構(gòu)造函數(shù)模式主要有以下幾個(gè)特點(diǎn):

沒(méi)有顯式的返回對(duì)象

直接將屬性和方法賦值給this對(duì)象

沒(méi)有return語(yǔ)句

通過(guò)new關(guān)鍵字調(diào)用的函數(shù)都被認(rèn)為是構(gòu)造函數(shù)。

new之后產(chǎn)生的是一個(gè)新的對(duì)象,可以在new的時(shí)候傳遞參數(shù),并且把這個(gè)參數(shù)的值賦值給this 指針,這樣,傳遞進(jìn)去的內(nèi)容,就變成了新產(chǎn)生的對(duì)象的屬性或者方法。

為了讓代碼看起來(lái)更加的“優(yōu)雅”,構(gòu)造函數(shù)的首字母都是大寫。

除此之外,用構(gòu)造函數(shù)產(chǎn)生的實(shí)例中,他的原型都會(huì)默認(rèn)的包含一個(gè)constructor屬性,會(huì)指向構(gòu)造函數(shù)。這樣就能夠知道這個(gè)對(duì)象是從哪兒創(chuàng)建的,也就是說(shuō)能夠區(qū)分這個(gè)對(duì)象的類型了(下面的工廠模式就無(wú)法區(qū)分對(duì)象的類型)。

function Foo () {
  this.value = 1;
}

test = new Foo ();

test.constructor  == Foo ();

當(dāng)然,構(gòu)造函數(shù)也是可以直接執(zhí)行的,而不是一定要new,直接執(zhí)行的化“構(gòu)造函數(shù)”中的this指向的就不再是新產(chǎn)生的對(duì)象了(實(shí)際上這種情況下就和普通的函數(shù)一樣,并不會(huì)產(chǎn)生新的對(duì)象),往往在瀏覽器中是window.

構(gòu)造函數(shù)在每次new的時(shí)候產(chǎn)生的實(shí)例都是重新創(chuàng)建的,因此不同實(shí)例上的同名函數(shù)是不相等的。

function Foo () {
  this.test = function () {

  };
}

var a = new Foo();
var b = new Foo();

a.test === b.test    // false

所以說(shuō),構(gòu)造函數(shù)每次new都是產(chǎn)生一個(gè)新的實(shí)例,并且這個(gè)實(shí)例的屬性和方法是獨(dú)享的。這樣往往造成了一些浪費(fèi)(屬性是獨(dú)有的可以理解,但是就方法而言,大多數(shù)往往是一樣的,這和我們想要的可能有點(diǎn)差別)。

2.工廠模式

為了不去使用new關(guān)鍵字,上面提到的構(gòu)造函數(shù)必須顯式的返回。當(dāng)前這個(gè)時(shí)候就可以理解為不是構(gòu)造函數(shù)了。

function Foo () {
  var value = 1;

  return {
    method: function () {
      return value;
    }
  };

};

Foo.prototype = {
  foo: function () {

  }
};

new Foo();
Foo();

上面加不加new的返回結(jié)果是完全一樣的,都是一個(gè)新創(chuàng)建的,擁有method屬性的對(duì)象。嗯。如果對(duì)閉包有所理解的話,他返回的就是一個(gè)閉包!

需要注意的是,上面返回的是一個(gè)包含method屬性的自定義對(duì)象,所以他并不返回Foo.prototype.

(new Foo()).foo    // undefined
(Foo()).foo        // undefined

按照正常人的思路,一般選擇用new來(lái)調(diào)用函數(shù)總是顯得很奇怪,這也估計(jì)就是大多人說(shuō)不要使用new關(guān)鍵字來(lái)調(diào)用函數(shù)的原因了,因?yàn)槿绻?b>new就會(huì)產(chǎn)生難以察覺(jué)的錯(cuò)誤。

嗯,是時(shí)候引出工廠模式了:

function Foo () {
  var obj = {};
  obj.value = "rccoder";

  var privateValue = 2;

  obj.method = function (value) {
    this.value = value;
  };

  obj.getPrivate = function () {
    return privateValue;
  };
  
  return obj;
}

就像上面的代碼一樣,有個(gè)工廠,就這樣生產(chǎn)出了一個(gè)個(gè)的工人。工廠模式解決了多個(gè)比較相似的對(duì)象重復(fù)創(chuàng)建的問(wèn)題。但是這個(gè)創(chuàng)建只單純的一個(gè)創(chuàng)建,但并不知道這個(gè)對(duì)象是從哪里創(chuàng)建的,也就是說(shuō)無(wú)法去區(qū)分這個(gè)對(duì)象的類型。

當(dāng)然還有一些其他的缺點(diǎn),比如由于新創(chuàng)建的對(duì)象只是簡(jiǎn)單的創(chuàng)建,所以不能共享原型上的方法,如果要實(shí)現(xiàn)所謂的繼承,就要從另外的一個(gè)對(duì)象去拷貝所有的屬性...嗯,他放棄了原型,為了去防止new帶來(lái)的問(wèn)題。

3.原型模式

在構(gòu)造函數(shù)模式中提到每次new之后創(chuàng)建的新的對(duì)象是互相獨(dú)立的,是獨(dú)享的。

構(gòu)造函數(shù)每次new都是產(chǎn)生一個(gè)新的實(shí)例,并且這個(gè)實(shí)例的屬性和方法是獨(dú)享的。這樣往往造成了一些浪費(fèi)(屬性是獨(dú)有的可以理解,但是就方法而言,大多數(shù)往往是一樣的,這和我們想要的可能有點(diǎn)差別)

就最后一句而言,我們或許可以這樣寫:

function Foo (value) {
  this.value = value;
  this.method = method;
}

function method () {
  console.log (this.value);
}

這樣把方法去放在外面,在構(gòu)造函數(shù)里面去調(diào)用這個(gè)函數(shù),好像就hack的解決了上面的問(wèn)題。但是這個(gè)函數(shù)好像就是全局函數(shù)了,并且和Foo()看上去并不怎么愉快的是一家人,談封裝也就有些牽強(qiáng)。

這種去共享方法的問(wèn)題用prototype看似就可以解決,畢竟他產(chǎn)生的屬性和方法是所有產(chǎn)生的實(shí)例所共享的。

function Foo () {
  ...
};

Foo.prototype.value = "rccoder";
Foo.prototype.method = function () {
  console.log (this.value);
};

var test = new Foo ();
test.method();    // rccoder

這樣看起來(lái)好像是可行的,當(dāng)需要找某個(gè)對(duì)象的屬性的時(shí)候,往往直接看有沒(méi)有這個(gè)屬性,沒(méi)有的話再按照原型鏈向上尋找,而不是去尋找構(gòu)造函數(shù)。

原型是動(dòng)態(tài)的,所以不要隨便的去修改原型。這個(gè)修改后會(huì)立即影響實(shí)例的結(jié)果。

如果我們有Foo.prototype = Bar.prototype?的寫法,改變這兩個(gè)對(duì)象任何一個(gè)的原型都會(huì)影響另外一個(gè),這在大多的情況下是不可取的。

一般情況下不建議對(duì)原型做修改,因?yàn)楹芸赡苡捎诖a量太多導(dǎo)致維護(hù)太困難。

另外,還記得用原型模式的初衷嗎?是要公用方法,而不是公用屬性。純粹的用原型會(huì)同樣的公用屬性,這在很多情況下看起來(lái)是很郁悶的。所以可能需要我們把原型和構(gòu)造函數(shù)結(jié)合起來(lái)使用。

4.優(yōu)雅混合使用構(gòu)造函數(shù)與原型

這或許是比較理想話的使用方法了,用構(gòu)造函數(shù)來(lái)區(qū)分獨(dú)享的屬性,用原型來(lái)共享大家都用的方法。

function Foo (value1, value2) {
  this.value1 = value1;
  this.value2 = value2;
}

Foo.prototype.method = function () {
  console.log (this.value1)
};

test1 = new Foo (2, 3);
test1.method();  // 2

test2 = new Foo (4, 5);
test2.method()   // 4

哦,對(duì)了,你可能會(huì)看見(jiàn)這樣寫上面的代碼

function Foo (value1, value2) {
  this.value1 = value1;
  this.value2 = value2;
}

Foo.prototype = {
  constructor: Foo,
  method: function () {
    console.log (this.value1);
  }
}

test = new Foo (2, 3);
test.method();

別怕,這只是覆蓋了Foo的原型而已,是真的覆蓋到連constructor是誰(shuí)都不認(rèn)識(shí)了,所以需要手動(dòng)的是想一下,指向誰(shuí)呢?正常人的話指向的應(yīng)該是構(gòu)造函數(shù)吧。

參考資料:

JavaScript密碼花園

JavaScript 原型理解與創(chuàng)建對(duì)象應(yīng)用-于江水的博客

原文鏈接:http://life.rccoder.net/javascript/1216.html

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

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

相關(guān)文章

  • JavaScript深入作用域鏈

    摘要:下面,讓我們以一個(gè)函數(shù)的創(chuàng)建和激活兩個(gè)時(shí)期來(lái)講解作用域鏈?zhǔn)侨绾蝿?chuàng)建和變化的。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過(guò)程,最后結(jié)合著變量對(duì)象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過(guò)程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文?!分兄v到,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代...

    waltr 評(píng)論0 收藏0
  • JavaScript深入執(zhí)行上下文

    摘要:深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧變量對(duì)象作用域鏈?zhǔn)侨绾巫兓?。前言在深入之?zhí)行上下文棧中講到,當(dāng)代碼執(zhí)行一段可執(zhí)行代碼時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文。 JavaScript深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的demo為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧、變量對(duì)象、作用域鏈?zhǔn)侨绾巫兓摹?前言 在《Jav...

    gougoujiang 評(píng)論0 收藏0
  • JavaScriptnew運(yùn)算符

    摘要:之運(yùn)算符運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例。使用指定的參數(shù)調(diào)用構(gòu)造函數(shù),并將綁定到新創(chuàng)建的對(duì)象。 JavaScript之new運(yùn)算符 new運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例。new關(guān)鍵字會(huì)進(jìn)行如下的操作: 1. 創(chuàng)建一個(gè)空的簡(jiǎn)單JavaScript對(duì)象(即{}); 2. 鏈接該對(duì)象(即設(shè)置該對(duì)象的構(gòu)造函數(shù))到另一個(gè)對(duì)...

    wwq0327 評(píng)論0 收藏0
  • JavaScript深入變量對(duì)象

    摘要:深入系列第四篇,具體講解執(zhí)行上下文中的變量對(duì)象與活動(dòng)對(duì)象。下一篇文章深入之作用域鏈本文相關(guān)鏈接深入之執(zhí)行上下文棧深入系列深入系列目錄地址。 JavaScript深入系列第四篇,具體講解執(zhí)行上下文中的變量對(duì)象與活動(dòng)對(duì)象。全局上下文下的變量對(duì)象是什么?函數(shù)上下文下的活動(dòng)對(duì)象是如何分析和執(zhí)行的?還有兩個(gè)思考題幫你加深印象,快來(lái)看看吧! 前言 在上篇《JavaScript深入之執(zhí)行上下文?!分?..

    Zachary 評(píng)論0 收藏0
  • JavaScript基礎(chǔ)創(chuàng)建對(duì)象、原型、原型對(duì)象、原型鏈

    摘要:在最開(kāi)始的時(shí)候,原型對(duì)象的設(shè)計(jì)主要是為了獲取對(duì)象的構(gòu)造函數(shù)。同理數(shù)組通過(guò)調(diào)用函數(shù)通過(guò)調(diào)用原型鏈中描述了原型鏈的概念,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法。 對(duì)象的創(chuàng)建 在JavaScript中創(chuàng)建一個(gè)對(duì)象有三種方式??梢酝ㄟ^(guò)對(duì)象直接量、關(guān)鍵字new和Object.create()函數(shù)來(lái)創(chuàng)建對(duì)象。 1. 對(duì)象直接量 創(chuàng)建對(duì)象最直接的方式就是在JavaScript代碼中使用對(duì)象直接量。在ES5...

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

    摘要:深入系列第十四篇,講解創(chuàng)建對(duì)象的各種方式,以及優(yōu)缺點(diǎn)。也就是說(shuō)打著構(gòu)造函數(shù)的幌子掛羊頭賣狗肉,你看創(chuàng)建的實(shí)例使用都無(wú)法指向構(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元查看
<