ES5 基本語法變數篇的注意點
阿新 • • 發佈:2019-01-08
ES5 基本語法變數篇的注意點
變數
變數概念
如果只是宣告變數而沒有賦值,則該變數的值是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()
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後可以跳出外層迴圈