最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js變量、作用域及內(nèi)存詳解

 更新時(shí)間:2014年09月23日 08:57:52   投稿:hebedich  
本文主要詳細(xì)分析了JS變量,作用域以及內(nèi)存問(wèn)題,同時(shí)附上非常多的實(shí)例,方便大家理解這3個(gè)概念,是篇不可多得的文章,希望對(duì)大家有所幫助

基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在內(nèi)存中占有固定的大小空間,他們的值保存在??臻g,我們通過(guò)按值來(lái)訪問(wèn)的。

(1)值類型:數(shù)值、布爾值、null、undefined。
(2)引用類型:對(duì)象、數(shù)組、函數(shù)。

如果賦值的是引用類型的值,則必須在堆內(nèi)存中為這個(gè)值分配空間。由于這種值的大小不固定(對(duì)象有很多屬性和方法),因此不能把他們保存到棧內(nèi)存中。但內(nèi)存地址大小是固定的,因此可以將內(nèi)存地址保存在棧內(nèi)存中。

<script type="text/javascript”>
var box = new Object(); //創(chuàng)建一個(gè)引用類型
var box = "lee";  //基本類型值是字符串
box.age = 23;  //基本類型值添加屬性很怪異,因?yàn)橹挥袑?duì)象才可以添加屬性。
alert(box.age); //不是引用類型,無(wú)法輸出;
</script>

簡(jiǎn)而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類型值。

<script type="text/javascript">
  var man = new Object();//man指向了棧內(nèi)存的空間地址
  man.name = "Jack";
  var man2 = man;//man2獲得了man的指向地址

  alert(man2.name);//兩個(gè)都彈出Jack
  alert(man.name);
</script>

復(fù)制變量值

再看下面這個(gè)例子:

<script type="text/javascript">
  var man = new Object();//man指向了棧內(nèi)存的空間地址
  man.name = "Jack";
  var man2 = man;//man2獲得了man的指向地址

  man2.name = "ming";//因?yàn)樗麄兌贾赶蛲粋€(gè)object,同一個(gè)name,不管修改誰(shuí),大家都修改了
  alert(man2.name);//兩個(gè)都彈出ming
  alert(man.name);
</script>

由以上可以得出:在變量復(fù)制方面,基本類型和引用類型也有所不同,基本類型復(fù)制的是值本身,而引用類型復(fù)制的是地址。

傳遞參數(shù)

ECMAScript中,所有函數(shù)的參數(shù)都是按值傳遞的,

<script type="text/javascript">
   function box(num){   //按值傳遞
     num+=10;
     return num;
   }

   var num = 10;
   var result = box(num);
   alert(result); //如果是按引用傳遞,那么函數(shù)里的num會(huì)成為類似全局變量,把外面的number替換掉
   alert(num);  //也就是說(shuō),最后應(yīng)該輸出20(這里輸出10)
</script>

javascript沒(méi)有按引用傳遞的,如果存在引用傳遞的話,那么函數(shù)內(nèi)的變量將是全局變量,在外部也可以訪問(wèn)。但這明顯是不可能的。

執(zhí)行環(huán)境及作用域

執(zhí)行環(huán)境是javascript中最為重要的概念之一,執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問(wèn)其他數(shù)據(jù)。

全局執(zhí)行環(huán)境是最外圍的執(zhí)行環(huán)境,在web瀏覽器中,全局執(zhí)行環(huán)境是window對(duì)象,因此,所有的全局變量的函數(shù)都是作為window的屬性和方法創(chuàng)建的。

<script type="text/javascript">
   var name = "Jack";      //定義全局變量
   function setName(){
     return "trigkit4";
   }

   alert(window.name);    //全局變量,最外圍,屬于window屬性
   alert(window.setName()); //全局函數(shù),最外圍,屬于window方法
</script>

當(dāng)執(zhí)行環(huán)境內(nèi)的代碼執(zhí)行完畢后,該環(huán)境被銷毀,保存其中的變量和函數(shù)也隨之銷毀,如果是全局環(huán)境,需所有程序執(zhí)行完畢或網(wǎng)頁(yè)完畢后才會(huì)銷毀。

去掉var的局部變量

<script type="text/javascript">
   var name = "Jack";
   function setName(){
     name = "trigkit4";  //去掉var變成了全局變量
   }

   setName();
   alert(name);//彈出trigkit4
</script>

通過(guò)傳參,也是局部變量

<script type="text/javascript">
   var name = "Jack";
   function setName(name){  //通過(guò)傳參,也是局部變量
     alert(name);
   }

   setName("trigkit4");//彈出trigkit4
   alert(name);//彈出Jack
</script>

函數(shù)體內(nèi)還包含函數(shù),只有這個(gè)函數(shù)才可以訪問(wèn)內(nèi)一層的函數(shù)

<script type="text/javascript">
   var name = "Jack";
   function setName(){
     function setYear(){  //setYear()方法的作用域在setName()內(nèi)
       return 21;
     }
   }
   alert(setYear());//無(wú)法訪問(wèn),出錯(cuò) 
</script>

可以通過(guò)如下方法進(jìn)行訪問(wèn):

<script type="text/javascript">
   var name = "Jack";
   function setName(){
     function setYear(){  //setYear()方法的作用域在setName()內(nèi)
       return 21;
     }
     return setYear();
   }
   alert(setName()); //彈出21
</script>

再一個(gè)作用域例子:

<script type="text/javascript">
   var name = "Jack";
   function setName(){
     function setYear(){  //setYear()方法的作用域在setName()內(nèi)
       var b = "hi";   //變量b的作用域在setYear()內(nèi)
       return 21;
     }
     alert(b);//無(wú)法訪問(wèn) 
   }
</script>

當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行的時(shí)候,就會(huì)形成一種叫做作用域鏈的東西,它的用途是保證對(duì)執(zhí)行環(huán)境中有訪問(wèn)權(quán)限的變量和函數(shù)進(jìn)行有序訪問(wèn)(指按照規(guī)則層次來(lái)訪問(wèn)),作用域鏈的前端,就是執(zhí)行環(huán)境的變量對(duì)象。

作用域

變量沒(méi)有在函數(shù)內(nèi)聲明或者聲明的時(shí)候沒(méi)有帶var就是全局變量,擁有全局作用域,window對(duì)象的所有屬性擁有全局作用域;在代碼任何地方都可以訪問(wèn),函數(shù)內(nèi)部聲明并且以var修飾的變量就是局部變量,只能在函數(shù)體內(nèi)使用,函數(shù)的參數(shù)雖然沒(méi)有使用var但仍然是局部變量。

沒(méi)有塊級(jí)作用域

沒(méi)有塊級(jí)作用域

// if語(yǔ)句:

<script type="text/javascript">
if(true){            //if語(yǔ)句的花括號(hào)沒(méi)有作用域的功能。

var box = "trigkit4";
}
alert(box);//彈出 trigkit4
</script>


for循環(huán)語(yǔ)句也是如此。

變量的查詢

在變量的查詢中,訪問(wèn)局部變量要比全局變量來(lái)得快,因此不需要向上搜索作用域鏈。
如下例子:

<script type="text/javascript">
   var name = "Jack";
   function setName(){
      var name = "trigkit4";
      return name; //從底層向上搜索變量
  }
  alert(setName());   
</script>

內(nèi)存問(wèn)題

javascript具有自動(dòng)垃圾回收機(jī)制,一旦數(shù)據(jù)不再使用,可以將其設(shè)為"null"來(lái)釋放引用

循環(huán)引用

  一個(gè)很簡(jiǎn)單的例子:一個(gè)DOM對(duì)象被一個(gè)Javascript對(duì)象引用,與此同時(shí)又引用同一個(gè)或其它的Javascript對(duì)象,這個(gè)DOM對(duì)象可能會(huì)引發(fā)內(nèi)存泄露。這個(gè)DOM對(duì)象的引用將不會(huì)在腳本停止的時(shí)候被垃圾回收器回收。要想破壞循環(huán)引用,引用DOM元素的對(duì)象或DOM對(duì)象的引用需要被賦值為null。

閉包

在閉包中引入閉包外部的變量時(shí),當(dāng)閉包結(jié)束時(shí)此對(duì)象無(wú)法被垃圾回收(GC)。

var a = function() {
 var largeStr = new Array(1000000).join('x');
 return function() {
  return largeStr;
 }
}();

DOM泄露

當(dāng)原有的COM被移除時(shí),子結(jié)點(diǎn)引用沒(méi)有被移除則無(wú)法回收。

var select = document.querySelector;
var treeRef = select('#tree');

//在COM樹中l(wèi)eafRef是treeFre的一個(gè)子結(jié)點(diǎn)
var leafRef = select('#leaf'); 
var body = select('body');

body.removeChild(treeRef);

//#tree不能被回收入,因?yàn)閠reeRef還在
//解決方法:
treeRef = null;

//tree還不能被回收,因?yàn)槿~子結(jié)果leafRef還在
leafRef = null;

//現(xiàn)在#tree可以被釋放了。

Timers計(jì)(定)時(shí)器泄露

定時(shí)器也是常見(jiàn)產(chǎn)生內(nèi)存泄露的地方:

for (var i = 0; i < 90000; i++) {
 var buggyObject = {
  callAgain: function() {
   var ref = this;
   var val = setTimeout(function() {
    ref.callAgain();
   }, 90000);
  }
 }

 buggyObject.callAgain();
 //雖然你想回收但是timer還在
 buggyObject = null;
}

調(diào)試內(nèi)存

Chrome自帶的內(nèi)存調(diào)試工具可以很方便地查看內(nèi)存使用情況和內(nèi)存泄露:
在 Timeline -> Memory 點(diǎn)擊record即可:

相關(guān)文章

  • javascript prototype原型詳解(比較基礎(chǔ))

    javascript prototype原型詳解(比較基礎(chǔ))

    prototype原型是javascript中特別重要的概念,屬于必須要掌握,如果沒(méi)有良好的掌握的話,進(jìn)一步用好或者學(xué)好js基本是不可能的實(shí)現(xiàn)的事情,并且此概念稍有難度,可能對(duì)于初次接觸的朋友來(lái)說(shuō)有點(diǎn)困難,下面就通過(guò)代碼實(shí)例簡(jiǎn)單介紹一下prototype原型的用法
    2016-12-12
  • JavaScript 學(xué)習(xí)筆記之?dāng)?shù)據(jù)類型

    JavaScript 學(xué)習(xí)筆記之?dāng)?shù)據(jù)類型

    javascript數(shù)據(jù)類型非常簡(jiǎn)單,僅僅包含undefined、null、string、Boolean、number以及object,今天我們就針對(duì)這幾個(gè)數(shù)據(jù)類型,一一進(jìn)行講解,方便大家理解記憶
    2015-01-01
  • JavaScript開發(fā)規(guī)范要求(規(guī)范化代碼)

    JavaScript開發(fā)規(guī)范要求(規(guī)范化代碼)

    作為一名開發(fā)人員(WEB前端JavaScript開發(fā)),不規(guī)范的開發(fā)不僅使日后代碼維護(hù)變的困難,同時(shí)也不利于團(tuán)隊(duì)的合作,通常還會(huì)帶來(lái)代碼安全以及執(zhí)行效率上的問(wèn)題。
    2010-08-08
  • JS中attr和prop屬性的區(qū)別以及優(yōu)先選擇示例介紹

    JS中attr和prop屬性的區(qū)別以及優(yōu)先選擇示例介紹

    這篇文章主要介紹了JS中attr和prop屬性的區(qū)別以及優(yōu)先選擇,需要的朋友可以參考下
    2014-06-06
  • JavaScript中將數(shù)組進(jìn)行合并的基本方法講解

    JavaScript中將數(shù)組進(jìn)行合并的基本方法講解

    這篇文章主要介紹了JavaScript中將數(shù)組進(jìn)行合并的基本方法講解,包括快速合并多個(gè)數(shù)組的方法,需要的朋友可以參考下
    2016-03-03
  • JS中switch的四種寫法示例

    JS中switch的四種寫法示例

    這篇文章主要為大家介紹了JS中switch的四種寫法示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • js常用的鍵盤事件有哪些(用法示例)_鍵碼keyCode對(duì)照表

    js常用的鍵盤事件有哪些(用法示例)_鍵碼keyCode對(duì)照表

    用戶按下鍵盤上的鍵,首先會(huì)觸發(fā)keydown事件,然后是keypress事件,最后是keyup事件。其中,keydown和keypress事件是在文本框發(fā)生變化之前被觸發(fā);而keyup在文本框發(fā)生變化之后被觸發(fā)。如果用戶按下一個(gè)鍵不放,就會(huì)重復(fù)觸發(fā)keydown和keypress事件。
    2023-02-02
  • Javascript基礎(chǔ)教程之JavaScript語(yǔ)法

    Javascript基礎(chǔ)教程之JavaScript語(yǔ)法

    本文是javascript基礎(chǔ)教程的第一篇,給大家?guī)?lái)的是javascript的最基礎(chǔ)的東西--javascript的語(yǔ)法的注意事項(xiàng),希望大家能夠喜歡
    2015-01-01
  • js 小數(shù)取整的函數(shù)

    js 小數(shù)取整的函數(shù)

    js中對(duì)小數(shù)取整的函數(shù),需要的朋友可以參考下。
    2010-05-05
  • Javascript中arguments對(duì)象詳解

    Javascript中arguments對(duì)象詳解

    JavaScript不能像PHP一樣在函數(shù)參數(shù)中直接設(shè)置默認(rèn)值,但是JavaScript有一個(gè)arguments可以使用,這就可以為函數(shù)參數(shù)設(shè)置默認(rèn)值了
    2014-10-10

最新評(píng)論

拉萨市| 临澧县| 临沧市| 隆化县| 巧家县| 霞浦县| 昆明市| 余姚市| 通榆县| 古交市| 油尖旺区| 吴川市| 灵宝市| 荔浦县| 定州市| 连州市| 江安县| 松江区| 瑞金市| 潞西市| 义乌市| 额尔古纳市| 重庆市| 卢龙县| 黄梅县| 黔西| 武陟县| 大余县| 砚山县| 肥西县| 昌都县| 冷水江市| 礼泉县| 兰考县| 平邑县| 黎平县| 理塘县| 夏河县| 祁门县| 准格尔旗| 灵寿县|