網頁設計實戰之JavaScript(1) --變量與數據類型

一、JavaScript之變量

1、變量定義

定義變量是通過var關鍵字來定義一個變量,若變量不通過var定義,則視爲全局變量。

(1)變量聲明

  • 一般聲明方式
var name;//變量聲明
var age;//變量聲明
var add;//變量聲明
  • 同一行可以聲明若干變量,變量之間用逗號分開。
var name="AFADF",age=23,add=false;

變量名的規則:

  • 大小寫敏感,name 和 Name不是同一個變量。
  • 變量名中不能包括特殊字符,如:減號,加號等,
  • 變量名不能數字字母開頭。
  • 字母以駝峯形式便於閱讀,如:myName,yourAge
  • 變量名以確定含義的單詞,反映業務的內容。如:a,b,c這種變量名,難以理解它表示的含義。
  • 同名的變量聲明,會覆蓋前一個聲明的變量,原來的值會消失。
var name ="hello";
var name = "world";

(2)變量的初始化

變量在使用前需要初始化,給它一個值。
變量聲明時未初始化,那麼它的值是undefined,什麼也不是。既不是字符串,也不是數值,也不是對像。

  • 在聲明時初始化
var name="朱元璋"; //變量聲明時初始化
var age=78;      //變量聲明時初始化
  • 在程序中初始化:
var name; //變量聲明時無值,undefined
name="朱元璋"; //初始化

2、變量種類

若按照變量作用域和變量生命週期來劃分,可將變量分爲全局變量和局部變量。

(1) 全局變量

從作用域角度,全局變量位於作用域鏈的最頂端;從變量生命週期角度,全局變量生存期爲整個程序生命週期,即直到程序結束,全局變量才銷燬。

var address = "北京";//全局變量
 function GetUserInfo() {
	var userName = "小王";//userName局部變量
 	return userName +"-"+ address;
}
console.log(GetUserInfo());//小王-北京
console.log(address);//北京

(2) 局部變量

從作用域角度,局部變量位於特定的局部域,如特定的函數內部;從變量生命週期角度,局部變量聲明週期只在其所處的特定作用域內,超出該作用域,就失效。如函數變量,直在函數內部有效。

function GetUserInfo() {
       var userName = "我是小王";
       return userName;
    }
console.log(GetUserInfo());//我是小王
console.log(userName);//報錯:userName is not defined

3、變量鏈式作用域

JS中的變量作用域是通過this指針,從當前的作用域開始,從當前作用域由內向外查找,直到找到位置,這裏分爲幾個邏輯:

  • .從當前作用域由內向外查找,若找到,就停止查找,否則,繼續查找,直到查到window全局作用域爲止,若任然未找到,則會出錯,提示該變量未定義;

  • 當內部作用域變量名與外部作用域變量名相同時,內部作用域的覆蓋外部作用域。

var dateTime='2018-09-16';
function GetUserInfo(){
    var age=120;
    var name="中國";
    function printme(){
       var name="hello";
       var address="中國";   
       //中國-拳王-2018-06-05              
       console.log(address+"-"+name+
        "-"+age+"-"+dateTime);
     }
    return printme();
 }
GetUserInfo();//中國-hello-2018-09-16

作用域有三層:全局,GetUserInfo()函數內,printme()函數內。在printme()函數中,在調用log()函數時,name變量用本作用域中的name(=“hello”),age在本域中無此變量,則用外層的age變量,dateTime變量在本域中和外層域中都沒有這個變量,在再外層的外層中去查找。

4、注意

(1)、非規範化定義全局變量

定義全局變量的另一種方式,就是不使用關鍵字var

function GlobalParam() {
         userName = "hello";// 在函數中定義一個全局變量
 }
  GlobalParam();
 console.log(userName);//hello

(2)、js中沒有塊作用域

var maxNum = 100;
for (var i = 0; i < maxNum; i++) {
        var sum = 0;// 這個變量,在外層是可以訪問到的
       sum = sum + i;
}
console.log(sum);//99。因爲JavaScript沒有塊級作用域,因此能在for語句外部訪問變量sum

{
	var test = "hello";
}
console.log(test ); // "hello", 在C++和C#等開發語言不同。

5、變量的存儲和回收

(1) 變量的存儲

js中的變量雖然不區分類型,但是實際上Ecmascript包含兩種類型,基本類型和引用類型.

基本類型有5種:Undefined,Null,Boolean,Number,String,基本類型是按值訪問的,因爲可以操作保存在變量中的實際的值。

引用類型的值是保存在內存中的對象。與其他語言不同,JavaScript 不允許直接訪問內存中的位置,也就是說不能直接操作對象的內存空間。在操作對象時,實際上是在操作對象的引用(也稱爲句柄)而不是實際的對象.

(2)回收機制

每個對象中都有一個引用次數,跟蹤記錄每個值被引用的次數。當聲明瞭一個變量並將一個引用類型值賦給該變量時,則這個值的引用次數就是1。如果同一個值又被賦給另一個變量,則該值的引用次數加1。相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值的引用次數減 1。當這個值的引用次數變成 0 時,則說明沒有辦法再訪問這個值了,因而就可以將其佔用的內存空間回收回來。這樣,當垃圾收集器下次再運行時,它就會釋放那些引用次數爲零的值所佔用的內存。

垃圾收集器在運行的時候會給存儲在內存中的所有變量都加上標記。然後,它會去掉環境中的變量以及被環境中的變量引用的變量的標記。而在此之後再被加上標記的變量將被視爲準備刪除的變量,原因是環境中的變量已經無法訪問到這些變量了。最後,垃圾收集器完成內存清除工作,銷燬那些帶標記的值並回收它們所佔用的內存空間。

(3)、內存泄漏

  • 全局變量引起的內存泄漏
function mem_leaks(){  
    leak_str = 'xxxxxx';//leak_str 成爲一個全局變量,不會被回收
}
  • 閉包引起的內存泄漏
var leaks = (function(){  
    var leak = 'xxxxxx';// 被閉包所引用,不會被回收
    return function(){
        console.log(leak);
    }
})()

二、數據類型

1、基本數據類型

  • 布爾值(Boolean):有2個值分別是:true 和 false.
  • null : 一個表明 null 值的特殊關鍵字。 JavaScript 是大小寫敏感的,因此 null 與 Null、NULL或變體完全不同。
  • undefined :和 null 一樣是一個特殊的關鍵字,undefined 表示變量未定義時的屬性。
  • 數值(Number):整數或浮點數,例如: 42 或者 3.14159。
  • 字符串(String):字符串是一串表示文本值的字符序列,例如:“Howdy” 。
  • 代表(Symbol) ( 在 ECMAScript 6 中新添加的類型).。一種實例是唯一且不可改變的數據類型。

2、對象(Object)

對象是組成類型,一個對象是多個原始類型的值的集合,可以看作是一個存放各種值的容器。對象是最複雜的數據類型,又可以分成三個子類型:
狹義的對象(object)
數組(array)
函數(function)
狹義的對象和數組是兩種不同的數據組合方式,除非特別聲明,一般而言“對象”都特指狹義的對象。函數其實是處理數據的方法,JavaScript 把它當成一種數據類型,可以賦值給變量,這爲編程帶來了很大的靈活性,也爲 JavaScript 的“函數式編程”奠定了基礎。

(1)、Number.NaN 屬性

NaN 屬性是代表非數字值的特殊值。該屬性用於指示某個值不是數字。可以把 Number 對象設置爲該值,來指示其不是數字值。
使用 isNaN() 來判斷一個值是否是數字。原因是 NaN 與所有值都不相等,包括它自己。
isNaN() 函數可用於判斷其參數是否是 NaN,該值表示一個非法的數字(比如被 0 除後得到的結果)。

console.log(typeof Number.NaN === 'number'); // true

(2)、特殊的null

null的類型,使用typeof時返回的是object,只把它當作object的一種特殊值。

不同的對象在底層都表示爲二進制,在 JavaScript 中二進制前三位都爲 0 的話會被判斷爲 object 類型,null 的二進制表示是全 0,自然前三位也是 0,所以執行 typeof 時會返回“object”。

console.log(typeof null);// object

(3)、null與undefined

都可以表示“沒有”,含義非常相似。將一個變量賦值爲undefined或null,老實說,語法效果幾乎沒區別。實際的區別是:null是一個表示“空”的對象,轉爲數值時爲0;undefined是一個表示"此處無定義"的原始值,轉爲數值時爲NaN。

注意:
JavaScript 預期某個位置應該是布爾值,會將該位置上現有的值自動轉爲布爾值。轉換規則是:

  • 除了下面六個值被轉爲false,其他值都視爲true。undefined;null;false;0;NaN;""或’’(空字符串)。
  • 空數組([])和空對象({})對應的布爾值,都是true。

3、字面量(常量)

字面量是由語法表達式定義的常量;或通過由一定字詞組成的語詞表達式定義的常量。

  • 數組字面量
    數組字面值是一個封閉在方括號對([])中的包含有零個或多個表達式的列表,其中每個表達式代表數組的一個元素。當你使用數組字面值創建一個數組時,該數組將會以指定的值作爲其元素進行初始化,而其長度被設定爲元素的個數。
var arr = ["a", "b", "c"];
var a=[3];

  • 布爾字面量
    true和false。
    不要混淆作爲布爾對象的真和假與布爾類型的原始值true和false。布爾對象是原始布爾數據類型的一個包裝器。

  • 整數字面量

整數可以用十進制(基數爲10)、十六進制(基數爲16)、八進制(基數爲8)以及二進制(基數爲2)表示。
十六進制整數以0x(或0X)開頭,可以包含數字(0-9)和字母 a~f 或 A~F。

0, 117, -345 (十進制, 基數爲10)
015, 0001, -0o77 (八進制, 基數爲8) 
0x1123, 0x00111,  -0xF1A7 (十六進制, 基數爲16"hex")
0b11, 0b0011,  -0b11 (二進制, 基數爲2)
  • 浮點數字面量
    浮點數字面值可以有以下的組成部分:

一個十進制整數,可以帶正負號(即前綴“+”或“ - ”),
小數點(“.”),
小數部分(由一串十進制數表示),
指數部分。
指數部分以“e”或“E”開頭,後面跟着一個整數,可以有正負號(即前綴“+”或“-”)。浮點數字面量至少有一位數字,而且必須帶小數點或者“e”(大寫“E”也可)。
簡言之,其語法是:
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

3.14      
-.2345789 // -0.23456789
-3.12e+12  // -3.12*1012
.1e-23    // 0.1*10-23=10-24=1e-24
  • 對象字面量
    對象字面值是封閉在花括號對({})中的一個對象的零個或多個"屬性名-值"對的(元素)列表。你不能在一條語句的開頭就使用對象字面值,這將導致錯誤或產生超出預料的行爲, 因爲此時左花括號({)會被認爲是一個語句塊的起始符號。

  • RegExp 字面值
    一個正則表達式是字符被斜線(譯註:正斜槓“/”)圍成的表達式。

var re = /ab+c/;
  • 字符串字面量
    字符串字面量是由雙引號(")對或單引號(’)括起來的零個或多個字符。字符串被限定在同種引號之間;也即,必須是成對單引號或成對雙引號。
""
''
"adfadf"
'12312'
"123564564"

4、類型轉換

javaScript是一種動態類型語言,聲明變量時可以不必指定數據類型,而數據類型會在代碼執行時會根據需要自動轉換。

在包含的數字和字符串的表達式中使用加法運算符(+),JavaScript 會把數字轉換成字符串。

var a = "1234"+56; // 123456

在涉及其它運算符(減號’-’)時,JavaScript語言不會把數字變爲字符串。

var a = "100" - 10// 90
var a = "10" * 10// 100
var a = "10" / 2// 5
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章