首頁  >  文章  >  web前端  >  有關JavaScript變數相關問題詳解

有關JavaScript變數相關問題詳解

迷茫
迷茫原創
2017-03-26 17:02:291372瀏覽

  本文重點在於探討JavaScript變數所包含的兩種不同資料型別的值-基本型別值與參考型別值的差異。在此外稍微帶過ECMAScript和JavaScript的關係。

  題為JavaScript變量,但更具體的說法應該是ECMAScript變數。

  二十世紀九十年代,Netscape公司和微軟公司推出了兩個不同版本的JavaScript,不利於JavaScript的開發和使用,促使歐洲電腦製造商協會(ECMA, European Computer Manufacturers Association)著手處理JavaScript的標準化問題,從而完成了著名的ECMA-262——定義了一種名為ECMAScript的新腳本語言的標準。

  一個完整的JavaScript實作包含ECMAScript,文件物件模型(DOM,Document Object Model),以及瀏覽器物件模型(BOM,Browser Object Model)。 ECMAScript作為JavaScript的核心以及實現的基礎,是ECMA-262標準規定的在語法、類型、語句、關鍵字、保留字、操作符和對象這幾個方面內容的語言的描述。

 ECMA-262標準規定的ECMAScript變數是鬆散類型的,可以用來保存任何類型的數據,所以不同類型初始化變數的操作可以放在一條語句中執行,如下列程式碼是合法的。

 var message = "hello",  //string     
 age = 20,           //number3     
 found = false;   //boolean 

  用 var 運算子定義的變數將成為定義該變數的作用域中的局部變量,而退出該作用域後變數會立即被銷毀。例如在函數內定義一個變量,當函數被呼叫的時候,該變量即被創建,但在函數退出後,該變量將無法再被繼續訪問。

  ECMAScript中有6種資料型別(也只有6種資料型別(也只有6中,ECMAScript不支援任何建立自訂類型的機制)。

  其中基本資料型別包括5種-underfined、null、boolean、number、string,這5種基本資料型別按值訪問,其值屬於文章開頭提到的基本類型值,是簡單的資料段,可以操作保存在變數中的實際的值。

  第6種為複雜資料型別-object,本質上是由一組無序的名-值對組成的,屬於引用型別值,是保存在記憶體中的對象。 JavaScript不允許直接操作物件的記憶體空間,在操作物件時實際上是在操作物件的引用而不是實際的物件。

  雖然定義變數時不需要規定其為何種資料型別,但基本型別和參考型別的值可以執行的動作還是大相逕庭。

  屬性的新增

  對於引用型別的值,可以為其屬性和方法進行新增、變更和刪除,如下列程式碼:  

var obj = new object();  //创建对象并保存在obj中
obj.name = "Marry";      //添加名为name的属性,赋予字符串值“Marry”
alert(obj.name);         //弹出"Marry"

    如果obj物件不被銷毀或name屬性不被刪除,這個屬性將一直存在。

  再看基本類型值:

var name = "Marry";  //创建字符串
name.age = 20;       //添加名为age的属性,赋予number值20
alert(name.age);     //弹出"underfined"

  name字串被加入了一個age屬性,為其賦值20,但下次訪問時這個屬性就不見了。

  這說明只能動態地新增屬性給引用型別值。

  複製變數值

##  從變數a變數b複製基本型別的值,會在變數b物件上建立一個新值,將該值複製到給變數a指派的位置上,獨立保存。這兩個變數參與的任何操作都不會互相影響。

  若从变量c变量d复制引用类型的值,同样会将存储在变量d对象中的值复制一份放到为变量c分配的空间中,但这个值的副本实际是一个指针,与变量d指向堆内存中的同一个对象。两个变量实际引用同一个对象,改变其中一个变量,将影响另一个变量。

  具体区别见如下例子:

//基本类型值
var num1 = 5;var num2 = num1;
num2 = num2 + 5;
alert(num1);                   
//5alert(num2);                   
//10/
/引用类型值
var obj1 = new object();var obj2 = obj1;
obj1.name = "Marry";
alert(obj2.name);            
//"Marry"

   函数传参

  ECMAScript中所有函数的参数都是按值传递的,即将函数外部的值复制给函数内部的参数。鉴于基本类型值与引用类型值复制变量的不同,其函数传参的效果也不同。

  在向参数传递基本类型值时,被传递的参数被赋给一个局部变量,函数内部参数的变化不影响函数外部的变量;向参数传递引用类型值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化将会反映在函数的外部。如下列例子:

//传递基本类型值function addnum(num) {
    num += 10;    return num; 
}var num1 = 5;var num2 = addnum(num1);
alert(num1);                  
//5,无变化alert(num2);                  
//15//传递引用类型值
function setage(obj) {
    obj.age = 20;
}var obj1 = new object();
setage(obj1)
alert(obj1.age);            //20

在局部作用域中修改的对象反映在全局作用域中,很多人会以为这是按引用传递。但函数对象确实都是按值传递,见下列例子:

function setage(obj) {
    obj.age = 20;
    obj = new object();
    obj.age = 30;
}var obj1 = new object();
setage(obj1)
alert(obj1.age);           
//20

  此例中在函数内部为obj重新定义了一个对象,且为其age属性重新赋值,但这一变化并未反映在函数外部,说明obj1 并不是按引用传递的。实际函数内重新定义的对象为局部对象,在退出函数后就会被立即销毁。

  检测类型

  基本类型值可以通过typeof检测,但typeof检测引用类型时只能返回object。所以为了知道某个值是什么类型的对象,ECMAScript提供了instanceof操作符,语法如下:

result = variable instanceof constructor

如果变量是引用类型的实例,instanceof操作符就会返回true。

以上是有關JavaScript變數相關問題詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn