1. 程式人生 > >ES5 基本語法變數篇的注意點

ES5 基本語法變數篇的注意點

ES5 基本語法變數篇的注意點

JavaScript的基本語法

變數

變數概念

如果只是宣告變數而沒有賦值,則該變數的值是undefined。

var a;
console.log(a) // undefined

如果變數賦值的時候,忘了寫var命令,這條語句也是有效的,但是這裡建立的是全域性變數。這種方式雖然可以,但是不利於理解和程式碼管理

function test () {
    a = 1;
    console.log(a) // 1
}
console.log(a) // 1

如果一個變數沒有宣告就直接使用,JavaScript 會報錯,告訴你變數未定義。

console.log(x) //  ReferenceError: x is not defined

可以在同一條var命令中宣告多個變數;

var a, b;
console.log(a) // undefined
console.log(b) // undefined
var aa, bb = 10;
console.log(aa) // undefined
console.log(bb) // 10

(1)、如果使用var重新宣告一個已經存在的變數,只是宣告不賦值,第二次宣告是無效的。

(2)、如果第二次宣告賦值了,第二次覆蓋第一次的。

(3)、注意這種情況限定在同一作用域中,作用域不同則不一樣

var bb = 1;
var bb;
console.log(bb) // 1
var xx = 1;
var xx = 2;
console.log(xx) // 2
var x = 1; // 全域性的
function test () {
    var x = 2; // 區域性
    console.log('function_x--',x) // 2
}
test()
console.log('outter_x---',x) // 1

變數提升

JavaScript 引擎的工作方式是,先解析程式碼,獲取所有被宣告的變數,然後再一行一行地執行。這造成的結果,就是所有的變數的宣告語句,都會被提升到程式碼的頭部,這就叫做變數提升

console.log(a) // undefined
var a = 1;
// 真實的執行順序
var a;
console.log(a)
a = 1;

補充!!!ES6之前,JavaScript沒有塊級作用域,只有全域性作用域和函式作用域。變數提升就是將變數的宣告提升到它所在的作用域的頂層

function test() {
    var num = 123;
    console.log(num); // 123
}
test();            
console.log(num); // ReferenceError: num is not defined;num在函式作用域中

只有函式宣告才存在函式提升

console.log(f1()); // f1f1
console.log(f2());  // undefined
function f1() {console.log('f1f1')} // 函式的宣告
var f2 = function() {console.log('f2')} // 函式表示式
var str= "我是MT";
test();
function test() {
  console.log(str); //undefined
  var str= "哈哈哈";
  console.log(str); //"哈哈哈"
}
console.log(str);       //我是MT
函式外部的str是全域性變數
函式內部的是str是區域性變數,他們分屬的作用域是不同的。
在函式內部,str的宣告會被提升到函式的作用域的頂部。
function test(){
  if("a" in window){
    var a = 10;
  }
  console.log(a); 
}
test(); // undefined
// 這裡a會被提升到test的頂部執行,但是test是區域性的,不會再window中,所以a被聲明瞭但是沒被賦值
var foo = 1;
function bar() {
 if(!foo)
 {
    var foo = 10;
  }
  console.log(foo); 
 }
 bar();//   10
 //外面的foo和函式裡面的foo不在同一個作用域中
 var foo = 1;
 function bar () {
     var foo; // undefined
     if (!foo) { // true
         var foo = 10;
     }
     console.log(foo) // 10
 }
 bar()

變數提升的練習1

變數提升的練習2

function Foo() {
        getName = function(){
            console.log("1");
        };
        return this;
    }
    Foo.getName = function() {
        console.log("2");
    };
    Foo.prototype.getName = function(){
        console.log("3");
    };
    var getName = function() {
        console.log("4");
    };
    function getName(){
        console.log("5");
    }
    Foo.getName(); // 2 
    getName(); // 4
    Foo().getName(); //1 ? 4 ? 2 ?報錯   
    getName(); // ?    1
    new Foo.getName(); //  2
    new Foo().getName(); // 3
    new new Foo().getName(); // 3

區塊

對於var命令來說,JavaScript 的區塊不構成單獨的作用域

注意這裡和ES6的區別

{
    var a = 1;
}
console.log(a) // 1

switch結構

switch語句後面的表示式,與case語句後面的表示式比較執行結果時,採用的是嚴格相等運算子(=),而不是相等運算子(),這意味著比較時不會發生型別轉換

var x = 1;
switch (x) {
  case true:
    console.log('x 發生型別轉換');
    break;
  default:
    console.log('x 沒有發生型別轉換');
}
// x 沒有發生型別轉換

三元運算子?:

(條件) ? 表示式1 : 表示式2

var n = 10;
var msg = '數字' + n + '是' + (n % 2 === 0 ? '偶數' : '奇數');
console.log(msg) // 數字10是偶數

標籤(label)

JavaScript 語言允許,語句的前面有標籤(label),相當於定位符,用於跳轉到程式的任意位置,標籤的格式如下。

標籤通常與break語句和continue語句配合使用,跳出特定的迴圈

function t1() {
top:
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      if (i === 1 && j === 1) break top;
      console.log('i=' + i + ', j=' + j);
    }
  } 
  console.log('bottom')
}
t1();
//i=0, j=0
//i=0, j=1
//i=0, j=2
//i=1, j=0
// 普通的break只能跳出內層迴圈,配合label後可以跳出外層迴圈