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

資訊專欄INFORMATION COLUMN

作用域和內(nèi)存問(wèn)題

myshell / 981人閱讀

摘要:當(dāng)代碼在一個(gè)黃靜中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈,作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。

基本類型和引用類型的值
ECMAscript 變量可能包含兩種不同的數(shù)據(jù)類型的值,基本類型值和引用類型值
基本類型指的是簡(jiǎn)單的數(shù)據(jù)段,而引用類型指那些可能有多個(gè)值構(gòu)成的對(duì)象

基本數(shù)據(jù)類型 :undefinedNull、BooleanNumberstring.這五種基本數(shù)據(jù)類型是按值訪問(wèn)的,因?yàn)榭梢圆僮鞔嬖谧兞恐械膶?shí)際的值

動(dòng)態(tài)屬性

定義基本類型的方式和引用類型的方式是類似的,創(chuàng)建一個(gè)變量并為該變量賦值。

對(duì)于引用類型的值,可以為其添加屬性和方法,也可以改變和刪除其屬性和方法

var person = new Object();
person.name = sunny;
console.log(person.name); // sunny
上面代碼創(chuàng)建了一個(gè)對(duì)象并將其保存了在變量person中,然后為該對(duì)象創(chuàng)建一個(gè)名為name的屬性。如果這個(gè)對(duì)象不被銷毀或者這個(gè)屬性不被刪除,則這個(gè)屬性將一直存在。

但是,我們不能給基本類型的值添加屬性

var name = "sunny";
name.age = 18;
consolem.log(name.age); // undefined
上面代碼為字符串name定義了一個(gè)名為age的屬性,并為該屬性賦值18,但是在下一行訪問(wèn)的這個(gè)屬性的時(shí)候,發(fā)現(xiàn)該屬性不見(jiàn)了,這說(shuō)明只能給引用類型值動(dòng)態(tài)添加屬性
復(fù)制變量值

如果從一個(gè)變量像另一個(gè)變量復(fù)制基本類型的值,會(huì)在變量對(duì)象上創(chuàng)建一個(gè)新值,然后把該值復(fù)制到新變量分配的位置上

var num1 = 10;
var num2 = num1; 
num1 = 20;
connsole.log(num1,num2) // 20 10
num1中保存的值是10;當(dāng)使用num1的值來(lái)初始化num2時(shí),num2也保存了值10,但num2中的10與num1中的10是完全獨(dú)立的,該值只是num1中10的一個(gè)副本,此后,這兩個(gè)變量可以完全參與任何操作而不會(huì)互相影響

當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值時(shí),同樣也會(huì)將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到為新變量分配的空間中。不同的是,這個(gè)值的副本實(shí)際上是一個(gè)指針,而這個(gè)指針指向存儲(chǔ)在堆中的一個(gè)對(duì)象,復(fù)制操作結(jié)束之后,這兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象,因此改變其中一個(gè)變量,就會(huì)影響另一個(gè)變量

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "sunny";
console.log(obj2.name); // sunny;
obj2.name = "zhang";
console.log(obj1.name); // zhang;
變量obj1保存了一個(gè)對(duì)象新實(shí)例,這個(gè)值被復(fù)制到obj2中,所以obj1和obj2都指向同一個(gè)對(duì)象,當(dāng)obj1或者obj2添加nane屬性的時(shí)候,這個(gè)屬性都是存儲(chǔ)在同一個(gè)對(duì)象。都可以通過(guò)obj1和obj2去訪問(wèn)。
傳遞參數(shù)
函數(shù)中的參數(shù)都是按值傳遞的,基本類型值的傳遞如同基本類型變量的復(fù)制一樣,而引用類型值的傳遞,則如同引用類型變量的復(fù)制一樣。被傳遞的值會(huì)被復(fù)制到一個(gè)局部變量(即命名參數(shù),或者用ECMAscript的概念來(lái)說(shuō),就是arguments對(duì)象中的一個(gè)元素)。

在向參數(shù)傳遞引用類型的值時(shí),會(huì)把這個(gè)值的內(nèi)存中的地址復(fù)制給一個(gè)局部變量,因此這個(gè)局部變量的變化會(huì)反映在函數(shù)的外部。

function addTen(){
    num += 10;
    return num; 
}
var count = 20;
var result = addTen(count);
console.log(count); // 20  沒(méi)有變化
console.log(result); // 30 返回 num += 10的結(jié)果
上面變量count做為參數(shù)被傳遞給函數(shù),這個(gè)變量的值是20;數(shù)值20被復(fù)制到參數(shù)num以便在addTen()函數(shù)中使用,在函數(shù)內(nèi)部num+=10,但這一變化不會(huì)影響函數(shù)外部的count變量。參數(shù)nun和count互不認(rèn)識(shí),它們僅僅具有想同的值。

使用對(duì)象傳遞參數(shù)。

function setName(obj){
    obj.name = "sunny";
}
var person = new Object();
setName(person);
console.log(person.name); // sunny
上面代碼中創(chuàng)建一個(gè)對(duì)象,并將其保在了變量person中,在這個(gè)函數(shù)內(nèi)部,參數(shù)obj和變量person引用的都是同一個(gè)對(duì)象,當(dāng)在函數(shù)內(nèi)部為obj添加name屬性后,函數(shù)外部的person也會(huì)有所反映。因?yàn)閜erson指向的對(duì)象在堆內(nèi)存中只有一個(gè),而且還是全局對(duì)象。

很多人錯(cuò)誤的認(rèn)為 (在局部作用域中修改的對(duì)象會(huì)在全局作用域中反映出來(lái),就說(shuō)明參數(shù)是按引用傳遞的),為了證明對(duì)象是按值傳遞的,下面修改一下代碼

function setName(obj) {
    obj.name = "sunny";
    obj = new Object(); // 重新定義一個(gè)新對(duì)象
    obj.name = "zhang";
}
var person = new Object();
setName(person);
console.log(person.name); // sunny
obj重新定義一個(gè)對(duì)象,并設(shè)置name屬性 值為 zhang,如果person是按引用傳遞的話,那么person就會(huì)自動(dòng)修改為指向其name屬性值為zhang 的新對(duì)象,但是訪問(wèn)person.name時(shí),值仍然是sunny,這說(shuō)明即使在函數(shù)內(nèi)部修改了參數(shù)的值,但原始的引用保持不變,實(shí)際上,在函數(shù)內(nèi)部重寫(xiě)obj時(shí),這個(gè)變量引用就是一個(gè)局部變量了。而這個(gè)局部變量在執(zhí)行完畢后立刻被銷毀
檢測(cè)類型
要檢測(cè)一個(gè)變量是不是基本數(shù)據(jù)類型,typeof操作符是最佳的工具。typeof操作符是確定一個(gè)變臉是字符串、數(shù)值、布爾值、Undefined的最佳工具,如果一個(gè)變量的值是null,則typeof操作符會(huì)返回object
var name = "sunny"; // string類型
var age = 18;  // Number類型
var bool = true;  // boolean
var unde;   // Undefined
var n = null;  // null
var person = new Object();  // 對(duì)象實(shí)例

console.log(typeof(name));  // string
console.log(typeof(age));  // number
console.log(typeof(bool));  // boolean
console.log(typeof(unde));  // undefined
console.log(typeof(n)); // object
console.log(typeof(person)); // object

雖然在檢測(cè)基本類型的時(shí)候,typeof操作符是非常得力的助手,但是在檢測(cè)引用類型的時(shí)候,這個(gè)操作符的作用不大。想知道是什么類型的對(duì)象,使用instanceof操作符

如果變量是給定引用類型(根據(jù)它的原型鏈來(lái)識(shí)別)的實(shí)例,那么instanceof就會(huì)返回 true ;
var name = "sunny";
var my_array = new Array();
var my_obj = new Object();

console.log(my_array instanceof Array); // true
console.log(my_obj instanceof Object); // true
console.log(name instanceof Object); // false
console.log(my_array instanceof Object); // true
console.log(my_obj instanceof Array); // false
所有引用類型的值都是Object的實(shí)例,在檢測(cè)一個(gè)引用類型和Object構(gòu)造函數(shù)時(shí),instanceof操作符始終會(huì)返回 true。如果使用instanceof操作符檢測(cè)基本類型的值始終會(huì)返回false,因?yàn)榛绢愋筒皇菍?duì)象
執(zhí)行環(huán)境及作用域
執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問(wèn)的其他數(shù)據(jù)。決定它們各自的行為,每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。

全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境,在web瀏覽器中,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象。因此所有全局變量和函數(shù)都是作為window對(duì)象的屬性和方法創(chuàng)建的。某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后,該環(huán)境被銷毀,保存在其中的所有變量和函定義也隨之銷毀(全局執(zhí)行環(huán)境直到應(yīng)用程序退出后--例如關(guān)閉頁(yè)面或退出瀏覽器時(shí)才會(huì)被銷毀)。

當(dāng)代碼在一個(gè)黃靜中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈,作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象作為變量對(duì)象。活動(dòng)對(duì)象在最開(kāi)始時(shí)只包含一個(gè)變量,即arguments對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)。

全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象。標(biāo)識(shí)符解析是沿著作用域鏈一級(jí)一級(jí)地搜索標(biāo)識(shí)符的過(guò)程,搜索過(guò)程始終從作用域鏈的前端開(kāi)始,然后逐級(jí)地向后回溯,知道找到標(biāo)識(shí)符為止(如果找不到標(biāo)識(shí)符,通常會(huì)導(dǎo)致錯(cuò)誤)。

var color = "blue";
function changecolor(){
    if(color === "blue"){
        color = "red";
    }
    else {
        color = "blue";
    }
}
changecolor();
console.log("color is now" + color); // red
在簡(jiǎn)單的例子中,函數(shù)changecolor()的作用域鏈包含著兩個(gè)對(duì)象,它子級(jí)的變量對(duì)象(其中定義這arguments)和全局環(huán)境變量對(duì)象??梢栽诤瘮?shù)內(nèi)部訪問(wèn)變量color,就是因?yàn)榭梢栽谶@個(gè)作用域鏈中找到它
var color  = "blue";
function changecolor(){
    var anothercolor = "red";
    function swapcolor(){
        var tempcolor = anothercolor;
        anothercolor = color;
        color = tempcolor
        //  這里可以訪問(wèn)到color 、anothercolor、 tempcolor
    }
    // 這里可以訪問(wèn)到//  這里可以訪問(wèn)到color 、anothercolor,但是不能訪問(wèn) tempcolor
}
// 這里只能訪問(wèn)color;
changecolor();
以上代碼共涉及3個(gè)執(zhí)行環(huán)境:全局環(huán)境,changecolor()的局部變量環(huán)境和swapcolor()的局部變量環(huán)境,內(nèi)部環(huán)境可以通過(guò)作用域鏈訪問(wèn)所有的外部環(huán)境,但外部壞境不能訪問(wèn)內(nèi)部環(huán)境中的任何變量和函數(shù)。每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名,但任何環(huán)境都不能通過(guò)向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。
延長(zhǎng)作用域鏈
有些語(yǔ)句可以在作用域鏈的前端臨時(shí)添加一個(gè)變量對(duì)象,該變量對(duì)象會(huì)在代碼執(zhí)行后被移除。具體來(lái)說(shuō)就是當(dāng)執(zhí)行流進(jìn)入下列任何一個(gè)語(yǔ)句時(shí),作用域鏈就得到加長(zhǎng)。

try-catch語(yǔ)句中的catch

catch語(yǔ)句會(huì)創(chuàng)建一個(gè)新的變量對(duì)象。其中包含的是拋出的錯(cuò)誤對(duì)象的聲明。
try{
    affffdlert("Welcome guest!");
    }
catch(err){
    //  創(chuàng)建一個(gè)err對(duì)象
    console.log(err.message); 
}

with語(yǔ)句

將指定的對(duì)象添加到作用域鏈中。
var s = "?debug=true";
with(location){
    var url = href + s ; // 實(shí)際引用的是location.href;
}
console.log(url); // 輸出 location對(duì)象下的href屬性的值。
// 等同于  console.log(location.href);
沒(méi)有塊級(jí)作用域

javascript中,if語(yǔ)句中的變量聲明會(huì)添加到當(dāng)前的執(zhí)行環(huán)境中。

if(true){
    var color = "blue";
}
console.log(color); // blue

javascript中,for語(yǔ)句創(chuàng)建的變量即使在變量即使在循環(huán)執(zhí)行結(jié)束后,也依舊會(huì)存在與循環(huán)環(huán)境外部的執(zhí)行環(huán)境中

for (var i = 0; i < 10; i++){    
}
console.log(i);  // 10
1.變量聲明

使用var聲明的變量會(huì)自動(dòng)被添加到最接近的環(huán)境之中,在函數(shù)內(nèi)部,最接近的環(huán)境就是函數(shù)的局部環(huán)境,在with語(yǔ)句中,最接近的環(huán)境是函數(shù)環(huán)境。如果初始化變量沒(méi)有使用var聲明,該變量會(huì)自動(dòng)被添加到全局環(huán)境中

function add(num1,num2){
    var sum = num1 + num2;
    return sum;
}
var result = add(20,30);
console.log(result); // 50
console.log(sum); // sum is not defined

使用var定義的sum變量,只能在函數(shù)add內(nèi)訪問(wèn)到,如果忽略var關(guān)鍵字定義sum,則可以在函數(shù)外部訪問(wèn)得到

function add(num1,num2){
    sum = num1 + num2;
    return sum;
}
var result = add(20,30);
console.log(result); // 50
console.log(sum); // 50
變量被初始化賦值的時(shí)候沒(méi)有使用var關(guān)鍵字,則該變量會(huì)添加到全局環(huán)境中。
垃圾收集

javascript 中最長(zhǎng)用的垃圾收集方式是標(biāo)記清除(mark-and-sweep)。當(dāng)變量進(jìn)入環(huán)境(例如,在函數(shù)中聲明一個(gè)變量)時(shí),就將這個(gè)變量標(biāo)記為"進(jìn)入環(huán)境"。從邏輯上講,永遠(yuǎn)不能釋放進(jìn)入環(huán)境的變量所占用的內(nèi)存,當(dāng)變量離開(kāi)環(huán)境時(shí),則將其標(biāo)記為"離開(kāi)環(huán)境"

引用計(jì)數(shù)

通過(guò)跟蹤每個(gè)值被引用的次數(shù)來(lái)清除所占用的內(nèi)存,當(dāng)聲明一個(gè)變量并將一個(gè)引用類型賦值給該變量的時(shí)候,則這個(gè)值的引用次數(shù)就是1,如果同一個(gè)值又被賦值給另一個(gè)變量,則該值的引用次數(shù)加1,相反,如果包含這個(gè)值引用的變量又取得了另一個(gè)值,則引用次數(shù)減1,當(dāng)引用次數(shù)為0時(shí),就將其占用的內(nèi)存空間回收回來(lái)。

性能問(wèn)題

垃圾收集器是周期性運(yùn)行的,而且如果為變量分配的內(nèi)存數(shù)量很可觀,那么回收工作量也是想當(dāng)大的

有是瀏覽器中可以直接觸發(fā)垃圾收集過(guò)程,(但我們不建議這么做),在IE中,調(diào)用window.CollectGarbage()方法會(huì)立即執(zhí)行垃圾收集,在opera7及更高版本中,調(diào)用window.opera.Collect()也會(huì)啟動(dòng)垃圾收集案例
管理內(nèi)存

一旦數(shù)據(jù)不再有用,就將其值設(shè)置為null來(lái)釋放其引用—這個(gè)做法一般叫“解除引用”,這個(gè)做法適用于大多數(shù)全局變量和全局對(duì)象的屬性。局部變量會(huì)在它們離開(kāi)執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用。
不過(guò),解除一個(gè)值的引用并不意味著自動(dòng)回收該值所占用的內(nèi)存,而是讓值脫離執(zhí)行環(huán)境,以更垃圾收集器下次運(yùn)行時(shí)將其回收。

function crean(name){
    var localperson = new Object();
    localperson.name = name;
    return localperson;
}
var globalperson = crean("sunny");
console.log(globalperson); // sunny
globalperson = nill;  // 手動(dòng)解除 globalperson 的引用

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

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

相關(guān)文章

  • 《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》——變量、作用域和內(nèi)存問(wèn)題(四)

    摘要:執(zhí)行環(huán)境的類型有兩種全局全局執(zhí)行環(huán)境局部函數(shù)執(zhí)行環(huán)境每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名但任何環(huán)境都不能通過(guò)向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。內(nèi)部可通過(guò)作用域鏈訪問(wèn)外部,外部不能訪問(wèn)內(nèi)部。 變量、作用域和內(nèi)存問(wèn)題 ECMAScript 數(shù)據(jù)類型 基本類型(5種): Undefined,Null,Boolean,Number,String typeof() 檢測(cè)...

    YacaToy 評(píng)論0 收藏0
  • 變量、作用域和內(nèi)存問(wèn)題

    摘要:使用聲明的變量會(huì)動(dòng)被添加到最近的環(huán)境中查詢標(biāo)識(shí)符,現(xiàn)在作用域鏈的最前端開(kāi)始搜索,逐步向上級(jí)查詢,直到找到匹配的標(biāo)識(shí)符,在變量查詢中,訪問(wèn)局部變量要比全局變量更快,因?yàn)椴恍枰蛏纤阉髯饔糜颉? 基本類型和引用類型的值 基本類型值指的是簡(jiǎn)單的數(shù)據(jù)段;引用類型值指那些可能由多個(gè)值構(gòu)成的對(duì)象。不能給基本類型添加屬性,可以給引用類型值動(dòng)態(tài)的添加屬性。 基本類型按值訪問(wèn),存放在棧內(nèi)存中。引用類型按引...

    lentrue 評(píng)論0 收藏0
  • 變量作用域和內(nèi)存問(wèn)題

    摘要:變量作用域和內(nèi)存問(wèn)題基本類型和引用類型的值基本類型就是簡(jiǎn)單的數(shù)據(jù)段種值類型,而引用類型就是對(duì)象操控對(duì)象的引用。但是不但能訪問(wèn)自己的變量,也能訪問(wèn)和全局作用域下的變量。延長(zhǎng)作用域鏈相當(dāng)于創(chuàng)造了一個(gè)新的變量對(duì)象在當(dāng)前作用域的上方。 變量作用域和內(nèi)存問(wèn)題 1.基本類型和引用類型的值 基本類型就是簡(jiǎn)單的數(shù)據(jù)段(5種值類型),而引用類型就是對(duì)象(操控對(duì)象的引用)。 1.1復(fù)制變量值 引用類型實(shí)際...

    wuyangchun 評(píng)論0 收藏0
  • JavaScript紅寶書(shū)筆記(四)---變量、作用域和內(nèi)存問(wèn)題

    摘要:在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。為此,引用類型的值是按引用訪問(wèn)的。標(biāo)記清除是目前主流的垃圾收集算法,這種算法的思想是給當(dāng)前不使用的值加上標(biāo)記,然后再回收其內(nèi)存 1.在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。為此,引用類型的值是按引用訪問(wèn)的。 2.當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值時(shí),兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象,因此,改變其中一個(gè)變量,就會(huì)...

    imtianx 評(píng)論0 收藏0
  • JavaScript變量、作用域和內(nèi)存問(wèn)題

    摘要:全局變量是最外圍的一個(gè)執(zhí)行環(huán)境,代碼在環(huán)境中執(zhí)行,會(huì)創(chuàng)建一個(gè)作用域鏈,用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)所有變量和函數(shù)的有序訪問(wèn)。作用域鏈中最后一個(gè)對(duì)象始終是全局執(zhí)行環(huán)境。內(nèi)部環(huán)境可以通過(guò)作用域鏈訪問(wèn)所有的外部環(huán)境,外部則不能訪問(wèn)內(nèi)部。 1、基本類型和引用類型的值 * 基本類型 : 指的是簡(jiǎn)單的數(shù)據(jù)段,五種基本類型是按值訪問(wèn)的,可以直接操作保存在變量中實(shí)際的值。 * 引用類型 : 指那些可能...

    Dr_Noooo 評(píng)論0 收藏0
  • 高程(第四章) 變量、作用域和內(nèi)存問(wèn)題

    摘要:不允許直接訪問(wèn)內(nèi)存中的位置,也就是說(shuō)不能直接操作對(duì)象的內(nèi)存空間。在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收 1 基本類型和引用類型的值 基本數(shù)據(jù)類型是按值訪問(wèn)的,因?yàn)榭梢圆僮鞅4嬖谧兞恐械膶?shí)際的值 基本類型值在內(nèi)存中占據(jù)固定大小的空間,因此被保存在棧內(nèi)存中 引用類型的值是保存在內(nèi)存中的對(duì)象。JavaSc...

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

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

0條評(píng)論

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