av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JavaScript中變量的存儲(chǔ)方式

瀏覽:6日期:2023-11-23 15:35:13
基本原理

前面文章提到過(guò),在js中變量包括5中基本類(lèi)型以及一個(gè)復(fù)雜數(shù)據(jù)類(lèi)型Object,當(dāng)然常用的函數(shù)和數(shù)組都是對(duì)象。對(duì)于基本類(lèi)型和復(fù)雜類(lèi)型,對(duì)應(yīng)著兩種不同的存儲(chǔ)方式–棧存儲(chǔ)和堆存儲(chǔ)。為什么要實(shí)現(xiàn)兩種存儲(chǔ)方式的理由很簡(jiǎn)單,就是基本類(lèi)型一旦初始化則內(nèi)存大小固定,訪(fǎng)問(wèn)變量就是訪(fǎng)問(wèn)變量的內(nèi)存上實(shí)際的數(shù)據(jù),稱(chēng)之為按值訪(fǎng)問(wèn)。而對(duì)象類(lèi)型說(shuō)不定什么時(shí)候就會(huì)增加自身的大小,內(nèi)存大小不固定。比如動(dòng)態(tài)添加對(duì)象的屬性、動(dòng)態(tài)增加數(shù)組的大小等等都會(huì)使變量大小增加,無(wú)法在棧中維護(hù)。所以js就把對(duì)象類(lèi)型的變量放到堆中,讓解釋器為其按需分配內(nèi)存,而通過(guò)對(duì)象的引用指針對(duì)其進(jìn)行訪(fǎng)問(wèn),因?yàn)閷?duì)象在堆中的內(nèi)存地址大小是固定的,因此可以將內(nèi)存地址保存在棧內(nèi)存的引用中。這種方式稱(chēng)之為按引用訪(fǎng)問(wèn)。 嗯,理解這一點(diǎn)很重要,在以后的編程中可以避免很多問(wèn)題。 我們來(lái)看下如下的代碼:

var a = ’I am a string.’; //a,b,c的變量中保存的都是實(shí)際的值,因?yàn)樗麄兪腔绢?lèi)型的變量var b = 1010;var c = false;var d = a; //d中保存著和“a值一樣的副本,它們互不影響”a = ’I am different from d’;alert(d); //輸出’I am a string’

以上代碼很好理解,就是說(shuō)按值訪(fǎng)問(wèn)的變量復(fù)制“你的就是你的,我的就是我的,咱們都有副本,互不影響。”而對(duì)于按引用訪(fǎng)問(wèn)則稍有不同:

var e = {name : ’I am an object’,setName : function(name){this.name = name;}};var f = e; //賦值操作,實(shí)際上的結(jié)果是e,f都是指向那個(gè)對(duì)象的引用指針f.setName(’I am different from e,I am object f.’);alert(e.name); //對(duì)f進(jìn)行操作,e的值也改變了!

對(duì)于引用類(lèi)型的賦值,說(shuō)白了,就是把那個(gè)對(duì)象的指針復(fù)制了過(guò)去,兩個(gè)指針指向的都是同一個(gè)實(shí)體對(duì)象,不存在副本,原本的對(duì)象還是只有一個(gè)!好。以上就是基本類(lèi)型和引用類(lèi)型的最大最根本的差別!我用一張圖來(lái)形象的表示下:

JavaScript中變量的存儲(chǔ)方式

*棧內(nèi)存中存放基本類(lèi)型變量,以及對(duì)象的指針;堆中存放對(duì)象實(shí)體

JavaScript中變量的存儲(chǔ)方式

*復(fù)制前后棧和堆中的情況

引用類(lèi)型引發(fā)的問(wèn)題1.使用原型模型創(chuàng)建對(duì)象的問(wèn)題

我們都知道,在JavaScript OO(Object Oriented)中,使用原型模式創(chuàng)建對(duì)象的最大的好處就是可以讓對(duì)象實(shí)例共享原型(prototype)所包含的屬性和方法。這樣就避免了構(gòu)造函數(shù)模式的缺陷,即每個(gè)對(duì)象都會(huì)有每個(gè)方法的副本,每個(gè)方法都會(huì)在每個(gè)實(shí)例上重新創(chuàng)建一遍,方法重用無(wú)意義的問(wèn)題。

嗯,使用原型模式是為所有實(shí)例共享了方法,但是當(dāng)原型中有引用類(lèi)型值的屬性的時(shí)候,問(wèn)題就來(lái)了:

var Person = function(){};Person.prototype = {constructor : Person,name : ’Hanzongze’,hobby : [’basketable’, ’swiming’, ’running’], //注意,這里包含著一個(gè)引用類(lèi)型的屬性sayName : function(){alert(this.name);}};var person1 = new Person();var person2 = new Person();person1.hobby.push(’music’);alert(person2.hobby); //輸出為’basketable’, ’swiming’, ’running’,’music’alert(person1.hobby === person2.hobby); //true

由于hobby屬性是引用類(lèi)型的值,所以由Person構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例的hobby屬性,都會(huì)指向這一個(gè)引用實(shí)體,實(shí)例對(duì)象間的屬性互相干擾。這不是我們想要的結(jié)果,為避免這類(lèi)問(wèn)題,解決方案就是組合使用構(gòu)造函數(shù)模型和原型模型:

var Person = function(){this.name = ’Hanzongze’;this.hobby = [’basketable’, ’swiming’, ’running’]; //對(duì)引用類(lèi)型的值使用構(gòu)造函數(shù)模式};Person.prototype = {constructor : Person,sayName : function(){alert(this.name);}};var person1 = new Person();var person2 = new Person();person1.hobby.push(’music’);alert(person2.hobby); //輸出 ’basketable’, ’swiming’, ’running’,說(shuō)明對(duì)person1的修改沒(méi)有影響到person2alert(person1.hobby === person2.hobby); //false2.原型繼承中的問(wèn)題

這個(gè)問(wèn)題與上一個(gè)的本質(zhì)其實(shí)是一樣的,只不過(guò)是發(fā)生在了原型繼承的背景中。看一個(gè)原型鏈繼承的問(wèn)題:

var Person = function(){this.name = ’Hanzongze’;this.hobby = [’basketable’, ’swiming’, ’running’];};Person.prototype = {constructor : Person,sayName : function(){alert(this.name);}};//子類(lèi)型Studentfunction Student(){}Student.prototype = new Person(); //Student繼承了Personvar student1 = new Student();var student2 = new Student();student1.hobby.push(’music’); //對(duì)子類(lèi)實(shí)例student1的引用屬性做了改動(dòng)var student3 = new Student();alert(student2.hobby); //輸出’basketable’, ’swiming’, ’running’, ’music’alert(student3.hobby); //輸出’basketable’, ’swiming’, ’running’, ’music’

在這段代碼中,可以看到,子類(lèi)Student繼承自父類(lèi)Person。但由于使用的是原型繼承,也就是說(shuō)父類(lèi)的實(shí)例作為了子類(lèi)的原型,那么實(shí)例中的引用類(lèi)型屬性也就繼承在了子類(lèi)的原型prototype中去了。則子類(lèi)的實(shí)例共享該引用屬性,相互影響。

解決方案,那就是使用借用構(gòu)造函數(shù)方案(但是也不是理想的方案,理想的方案是組合使用原型鏈和借用構(gòu)造函數(shù)。涉及到了比較多的繼承模式,這里簡(jiǎn)單描述,以后會(huì)寫(xiě)一篇詳細(xì)的文章):

var Person = function(){this.name = ’Hanzongze’;this.hobby = [’basketable’, ’swiming’, ’running’];};Person.prototype = {constructor : Person,sayName : function(){alert(this.name);}};function Student(){//借用構(gòu)造函數(shù),繼承了PersonPerson.call(this);}var student1 = new Student();var student2 = new Student();student1.hobby.push(’music’);alert(student2.hobby); //輸出’basketable’, ’swiming’, ’running’, ’music’

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 一区二区中文字幕 | 欧美一级片| www.99re| 国产中文在线 | 在线观看中文字幕 | 高清一区二区三区 | 亚洲一区二区 | 国产一级片免费视频 | 正在播放一区二区 | 免费看一区二区三区 | 国产日韩欧美中文 | 中文字幕日韩一区 | 亚洲精品视频三区 | 精品欧美一区二区三区久久久 | 国产偷自视频区视频 | 欧美精品久久久久久久久老牛影院 | www中文字幕 | 中文字幕一区在线 | 国产一级在线 | 婷婷午夜天 | 成人免费淫片aa视频免费 | 在线国产一区 | 99视频在线免费观看 | www国产成人免费观看视频,深夜成人网 | 久草新在线 | 先锋资源网站 | 亚洲网站在线观看 | 久久久久久高潮国产精品视 | 色视频在线免费观看 | 成人日批视频 | 国产高清免费 | 欧美一级二级在线观看 | 中文字幕av在线 | 国产精品成人一区二区三区夜夜夜 | 久久激情视频 | 久久久久黑人 | 国产在线精品一区二区 | 免费一级片| 欧美日韩久久精品 | 国产一区二区激情视频 | 亚洲+变态+欧美+另类+精品 |