1. 程式人生 > 實用技巧 >JavaScript函式和作用域以及解構賦值

JavaScript函式和作用域以及解構賦值

函式

第一種function定義函式;

function a(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

第二種匿名函式賦值給變數;

var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};

arguments是函式內起作用的關鍵字,指向當前函式傳入的所有引數,類似Array但不是;

function foo(x) {
    console.log(
'x = ' + x); // 10 for (var i=0; i<arguments.length; i++) { console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30 } } foo(10, 20, 30);

rest引數用...標識,獲取多餘的引數;

function foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

foo(1, 2, 3, 4, 5);
// a = 1 // b = 2 // Array [ 3, 4, 5 ] foo(1); // a = 1 // b = undefined // Array []

作用域

var宣告變數在函式內,就不能在外面引用。

函式能夠巢狀,內部函式可以訪問外部函式定義的變數。

不在函式內定義的變數都是全域性變數,JavaScript預設有一個全域性物件window,全域性變數實際上被繫結為window的屬性。

var course = 'Learn JavaScript';
alert(window.course); // 'Learn JavaScript'

function foo() {
    alert('foo');
}
window.foo(); 
// 通過window.foo()呼叫 window.alert('呼叫window.alert()'); //alert也是window的變數

由於全域性變數都會繫結到window上,不同的JavaScript檔案如果使用相同全域性變數,或者相同函式名,那麼會造成命名衝突,並且很難被發現。

減少衝突的一個方法是把自己的所有變數和函式全部繫結到一個全域性變數中;

// 唯一的全域性變數MYAPP:
var MYAPP = {};

// 其他變數:
MYAPP.name = 'myapp';

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

由於在for迴圈等語句塊中無法定義區域性變數,所以ES6引入了let關鍵字,宣告塊作用域變數;

function foo() {
    for (var i=0; i<100; i++) {
        
    }
    i += 100; // 仍然可以引用變數i
}

function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    // 報錯:
    i += 1;
}

const定義常量,也有塊作用域。

解構賦值也就是多變數賦值,變數和值用[]包起來,如果值本身有巢狀,那麼變數和它一樣巢狀就行了。

let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
x; // 'hello'
y; // 'JavaScript'

let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前兩個元素,只對z賦值第三個元素

如需要從物件取出若干屬性,也可以使用解構賦值;

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
};
var {name, age} = person;
console.log('name = ' + name + ', age = ' + age ); //name = 小明, age = 20

同樣可以直接對巢狀的物件屬性進行賦值,只要層次一致:

var person = {
    name: '小明',
    address: {
        city: 'Beijing',
        street: 'No.1 Road',
        zipcode: '100001'
    }
};
var {name, address: {city, zip}} = person;
name; // '小明'
city; // 'Beijing'
zip; // undefined, 因為屬性名是zipcode而不是zip
// address不是變數,而是為了讓city和zip獲得巢狀的address物件的屬性:
address; // Uncaught ReferenceError: address is not defined