JavaScript | 變量作用域與解構(gòu)賦值

Reference : JavaScript教程 - 廖雪峰的官方網(wǎng)站

原文變量作用域與解構(gòu)賦值 - 廖雪峰的官方網(wǎng)站

變量作用域

  • 在函數(shù)體中用var申明的變量:整個(gè)函數(shù)體,建議將var申明放到函數(shù)體的開頭
function foo() {
    var
        x = 1,
        y = x + 1,
        z, i;
    for (i = 0; i < 100; i++) {
        // ...
    }
}
  • 不在任何函數(shù)內(nèi)定義的變量具有全局作用域,可以通過全局對象window獲取。所有全局變量被綁定為window的屬性

  • 由于全局變量都在一個(gè)window對象上,當(dāng)涉及到多個(gè)js文件時(shí),容易出現(xiàn)命名沖突,且很難發(fā)現(xiàn)。解決這個(gè)問題的辦法是引入名字空間。定義一個(gè)全局對象作為名字空間,并把文件內(nèi)的變量和函數(shù)綁定到這個(gè)對象上,例如:

// 唯一的全局變量MYAPP:
var MYAPP = {};

// 其他變量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函數(shù):
MYAPP.foo = function () {
    return 'foo';
};

這個(gè)辦法也是許多著名的JavaScript庫的做法,如jQuery, YUI等。

  • let申明的變量是塊級變量,作用域僅存在于申明的語句塊內(nèi),如以下語句
'use strict'

for (let i = 0; i < 100; i ++) {
    sum += i;
}
i += 1; // Syntax error
  • const申明的是常量,對const申明的常量進(jìn)行賦值也許不會(huì)報(bào)錯(cuò),但一定不會(huì)修改常量的值。常量的作用域與let申明相同,僅在申明的塊內(nèi)有效

解構(gòu)賦值 [ES6]

解構(gòu)賦值是一種對一組變量進(jìn)行賦值的方法。

  1. 數(shù)組類型,注意等號左側(cè)的變量要用[...]括起來
'use strict'

var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
// x, y, z 分別被賦值為數(shù)組對應(yīng)元素

還可以忽略數(shù)組中的某些元素

let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前兩個(gè)元素
z; // 'ES6'
  1. 對象類型
'use strict';

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school'
};
var {name, age, passport} = person;
// name, age, passport分別被賦值為對應(yīng)屬性:
console.log('name = ' + name + ', age = ' + age + ', passport = ' + passport);

Output:

name = 小明, age = 20, passport = G-12345678

對一個(gè)對象進(jìn)行解構(gòu)賦值時(shí),同樣可以直接對嵌套的對象屬性進(jìn)行賦值,只要保證對應(yīng)的層次是一致的:

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school',
    address: {
        city: 'Beijing',
        street: 'No.1 Road',
        zipcode: '100001'
    }
};
var {name, address: {city, zip}} = person;
name; // '小明'
city; // 'Beijing'
zip; // undefined, 因?yàn)閷傩悦莦ipcode而不是zip
// 注意: address不是變量,而是為了讓city和zip獲得嵌套的address對象的屬性:
address; // Uncaught ReferenceError: address is not defined

使用解構(gòu)賦值對對象屬性進(jìn)行賦值時(shí),如果對應(yīng)的屬性不存在,變量將被賦值為undefined,這和引用一個(gè)不存在的屬性獲得undefined是一致的。如果要使用的變量名和屬性名不一致,可以用下面的語法獲?。?/p>

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school'
};

// 把passport屬性賦值給變量id:
let {name, passport:id} = person;
name; // '小明'
id; // 'G-12345678'
// 注意: passport不是變量,而是為了讓變量id獲得passport屬性:
passport; // Uncaught ReferenceError: passport is not defined

解構(gòu)賦值還可以使用默認(rèn)值,這樣就避免了不存在的屬性返回undefined的問題:

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678'
};

// 如果person對象沒有single屬性,默認(rèn)賦值為true:
var {name, single=true} = person;
name; // '小明'
single; // true

有些時(shí)候,如果變量已經(jīng)被聲明了,再次賦值的時(shí)候,正確的寫法也會(huì)報(bào)語法錯(cuò)誤:

// 聲明變量x, y
var x, y;
// 對已經(jīng)聲明過的x, y進(jìn)行解構(gòu)賦值:
{x, y} = { name: '小明', x: 100, y: 200};
// 語法錯(cuò)誤: Uncaught SyntaxError: Unexpected token =

這是因?yàn)镴avaScript引擎把{開頭的語句當(dāng)作了塊處理,于是=不再合法。解決方法是用小括號括起來:

({x, y} = { name: '小明', x: 100, y: 200});

使用場景

解構(gòu)賦值在很多時(shí)候可以大大簡化代碼。例如,交換兩個(gè)變量x和y的值,可以這么寫,不再需要臨時(shí)變量:

var x=1, y=2;
[x, y] = [y, x]

快速獲取當(dāng)前頁面的域名和路徑:

var {hostname:domain, pathname:path} = location;
domain;
path;

如果一個(gè)函數(shù)接收一個(gè)對象作為參數(shù),那么,可以使用解構(gòu)直接把對象的屬性綁定到變量中。例如,下面的函數(shù)可以快速創(chuàng)建一個(gè)Date對象:

function buildDate({year, month, day, hour=0, minute=0, second=0}) {
    return new Date(year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second);
}

使用解構(gòu)賦值可以減少代碼量,但是,需要在支持ES6解構(gòu)賦值特性的現(xiàn)代瀏覽器中才能正常運(yùn)行。目前支持解構(gòu)賦值的瀏覽器包括Chrome,F(xiàn)irefox,Edge等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容