成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

(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 = "trigkit4"; //基本類型值是字符串 box.age = 21; //基本類型值添加屬性很怪異,因?yàn)橹挥袑?duì)象才可以添加屬性。 alert(box.age); //不是引用類型,無法輸出; </script>

簡(jiǎn)而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類型值。“引用”是一個(gè)指向?qū)ο髮?shí)際位置的指針。

在這里需注意的是,引用指向的是具體的對(duì)象,而不是另一個(gè)引用。

這里的對(duì)象可以是字符串對(duì)象,數(shù)字對(duì)象,數(shù)組對(duì)象等

 

  1. <script type="text/javascript"
  2.     var man = new Object();//man指向了棧內(nèi)存的空間地址 
  3.     man.name = "Jack"
  4.     var man2 = man;//man2獲得了man的指向地址 
  5.  
  6.     alert(man2.name);//兩個(gè)都彈出Jack 
  7.     alert(man.name); 
  8. </script> 

復(fù)制變量值

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

 

  1. <script type="text/javascript"
  2.     var man = new Object();//man指向了棧內(nèi)存的空間地址 
  3.     man.name = "Jack"
  4.     var man2 = man;//man2獲得了man的指向地址 
  5.  
  6.     man2.name = "ming";//因?yàn)樗麄兌贾赶蛲粋€(gè)object,同一個(gè)name,不管修改誰,大家都修改了 
  7.     alert(man2.name);//兩個(gè)都彈出ming 
  8.     alert(man.name); 
  9. </script> 

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

傳遞參數(shù)

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

 

  1. <script type="text/javascript"
  2.      function box(num){      //按值傳遞 
  3.          num+=10; 
  4.          return num; 
  5.      } 
  6.  
  7.      var num = 10; 
  8.      var result = box(num); 
  9.      alert(result);  //如果是按引用傳遞,那么函數(shù)里的num會(huì)成為類似全局變量,把外面的number替換掉 
  10.      alert(num);    //也就是說,***應(yīng)該輸出20(這里輸出10) 
  11. </script> 

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

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

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

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

 

  1. <script type="text/javascript"
  2.       var name = "Jack";           //定義全局變量 
  3.       function setName(){ 
  4.           return "trigkit4"
  5.       } 
  6.  
  7.       alert(window.name);        //全局變量,最外圍,屬于window屬性 
  8.       alert(window.setName());  //全局函數(shù),最外圍,屬于window方法 
  9. </script> 

 

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

去掉var的局部變量

 

  1. <script type="text/javascript"
  2.       var name = "Jack"
  3.       function setName(){ 
  4.           name = "trigkit4";   //去掉var變成了全局變量 
  5.       } 
  6.  
  7.       setName(); 
  8.       alert(name);//彈出trigkit4 
  9. </script> 

通過傳參,也是局部變量

 

  1. <script type="text/javascript"
  2.       var name = "Jack"
  3.       function setName(name){    //通過傳參,也是局部變量 
  4.           alert(name); 
  5.       } 
  6.  
  7.       setName("trigkit4");//彈出trigkit4 
  8.       alert(name);//彈出Jack 
  9. </script> 

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

 

  1. <script type="text/javascript"
  2.      var name = "Jack"
  3.       function setName(){ 
  4.           function setYear(){    //setYear()方法的作用域在setName()內(nèi) 
  5.               return 21; 
  6.           } 
  7.       } 
  8.       alert(setYear());//無法訪問,出錯(cuò)  
  9. </script> 

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

 

  1. <script type="text/javascript"
  2.      var name = "Jack"
  3.       function setName(){ 
  4.           function setYear(){    //setYear()方法的作用域在setName()內(nèi) 
  5.               return 21; 
  6.           } 
  7.           return setYear(); 
  8.       } 
  9.       alert(setName()); //彈出21 
  10. </script> 

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

 

  1. <script type="text/javascript"
  2.      var name = "Jack"
  3.       function setName(){ 
  4.           function setYear(){    //setYear()方法的作用域在setName()內(nèi) 
  5.               var b = "hi";     //變量b的作用域在setYear()內(nèi) 
  6.               return 21; 
  7.           } 
  8.           alert(b);//無法訪問  
  9.       } 
  10. </script> 

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

作用域

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

沒有塊級(jí)作用域

 

  1. // if語句: 
  2.  
  3. <script type="text/javascript"
  4. if(true){                        //if語句的花括號(hào)沒有作用域的功能。 
  5.  
  6. var box = "trigkit4"
  7. alert(box);//彈出 trigkit4 
  8. </script> 

 

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

變量的查詢

在變量的查詢中,訪問局部變量要比全局變量來得快,因此不需要向上搜索作用域鏈。

如下例子:

 

  1. <script type="text/javascript"
  2.      var name = "Jack"
  3.       function setName(){ 
  4.            var name = "trigkit4"
  5.            return name;  //從底層向上搜索變量 
  6.     } 
  7.     alert(setName());       
  8. </script> 

每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名;但任何環(huán)境都不能通過向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。在這里,如果去掉var name = "trigkit4",那么將彈出“Jack”

內(nèi)存問題

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

循環(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ì)象無法被垃圾回收(GC)。

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

DOM泄露

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

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í)器也是常見產(chǎn)生內(nèi)存泄露的地方:

 

  1. for (var i = 0; i < 90000; i++) { 
  2.   var buggyObject = { 
  3.     callAgain: function() { 
  4.       var ref = this
  5.       var val = setTimeout(function() { 
  6.         ref.callAgain(); 
  7.       }, 90000); 
  8.     } 
  9.   } 
  10.  
  11.   buggyObject.callAgain(); 
  12.   //雖然你想回收但是timer還在 
  13.   buggyObject = null

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

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

責(zé)任編輯:張燕妮 來源: trigkit4
相關(guān)推薦

2011-04-18 09:31:35

JavaScript

2013-09-05 10:07:34

javaScript變量

2021-10-28 10:26:35

Javascript 高階函數(shù)前端

2015-08-18 13:42:42

js作用域鏈變量

2024-03-14 11:27:16

C++變量編程

2019-03-13 08:00:00

JavaScript作用域前端

2011-09-06 09:56:24

JavaScript

2020-12-16 11:09:27

JavaScript語言開發(fā)

2015-07-08 10:25:05

Javascript上下文作用域

2021-03-09 08:50:58

JavaScript前端作用域

2017-09-14 13:55:57

JavaScript

2010-01-07 16:16:03

VB.NET變量作用域

2011-03-18 09:27:00

Spring

2023-06-28 08:34:02

Bind()函數(shù)JavaScript

2020-11-19 07:49:24

JS變量作用域

2011-05-12 18:26:08

Javascript作用域

2015-07-21 13:39:58

Javascript作用域

2021-06-02 07:02:42

js作用域函數(shù)

2010-02-03 16:42:45

C++變量作用域

2009-06-01 11:16:48

PHP網(wǎng)站開發(fā)變量作用域
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 人成在线视频 | www.色.com | 国产高清视频一区二区 | 成人在线视频免费观看 | 精品福利在线 | 久久久精品一区 | 一区二区三区免费 | 毛片a级 | 国产精品我不卡 | 91视视频在线观看入口直接观看 | 国产成都精品91一区二区三 | 国产片侵犯亲女视频播放 | 国产精品久久久久久久久久免费看 | 日韩伦理一区二区 | 亚洲午夜精品 | 欧美日韩专区 | 美女久久久久久久 | 亚洲高清视频在线 | 四虎在线视频 | 精品一级 | 亚洲香蕉在线视频 | 欧美成年人视频在线观看 | 在线国产小视频 | 99精品在线免费观看 | 欧美激情国产日韩精品一区18 | 亚洲一区二区三区视频 | 久久综合伊人 | 国产亚洲成av人在线观看导航 | 日本在线黄色 | 欧美综合一区二区三区 | 欧美成人hd | 日韩精品一区二区三区高清免费 | 色男人的天堂 | 成人午夜精品一区二区三区 | 综合久久综合久久 | 成人精品高清 | 亚洲精品2区 | 精品国产伦一区二区三区观看说明 | 欧美成视频 | 狠狠久| 国产日韩精品视频 |