定義
// 第一種方式
funcation funA(x, y){return (x + y);}
// 第二種方式
var funB = funcation (x, y){return (x + y);};
若沒(méi)有 return 默認(rèn)返回 undefined
調(diào)用
// js函數(shù)允許傳入任意個(gè)參數(shù)。執(zhí)行時(shí)只會(huì)調(diào)用它需要的參數(shù)
funA(2, 8, 8);
arguments
js函數(shù)內(nèi)部有一個(gè)默認(rèn)的關(guān)鍵字 arguments唇敞,它指向當(dāng)前函數(shù)調(diào)用者傳入所有的參數(shù)蔗草。arguments類似于Arrary,卻不是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 參數(shù)
為了更加方便管理傳入多余的參數(shù)疆柔, ES6 引用了 rest數(shù)組來(lái)接收多余的參數(shù)蕉世,沒(méi)有多余的參數(shù),rest.length為 0
function foo(a, b, ...rest) {
console.log('a = ' + a);
console.log('b = ' + b);
console.log(rest);
}
foo(1, 2, 3, 4, 5);
// 結(jié)果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]
變量提升
函數(shù)在調(diào)用時(shí)會(huì)先掃描函數(shù)體內(nèi)部所定義的所有變量婆硬,把所有變量提升到函數(shù)體的最前列。只提升變量的申明奸例,不提升變量的賦值彬犯。
'use strict';
function foo() {
var x = 'Hello, ' + y;
console.log(x);
var y = 'Bob';
}
foo(); // Hello, undefined
由于js的變量提升特性,我們?cè)诙x局部變量時(shí)查吊,在函數(shù)體內(nèi)首先把變量全部定義好谐区,稍后在賦值。
function foo() {
var
x = 1, // x初始化為1
y = x + 1, // y初始化為2
z, i; // z和i為undefined
// 其他語(yǔ)句:
for (i=0; i<100; i++) {
...
}
}
變量作用域
js中只有一個(gè)全局作用域逻卖,不在任何函數(shù)內(nèi)申明的變量都在全局作用域中宋列。
第二種函數(shù)的定義方式,就是申明一個(gè)全局的變量评也,指向一個(gè)函數(shù)炼杖。
全局作用域中默認(rèn)有一個(gè) window 對(duì)象。全局作用域中的所有變量都自動(dòng)綁定到 window 中盗迟±ば埃可通過(guò) window.name 來(lái)獲取全局變量。
alert()
就是 window 的一個(gè)變量罚缕。任何變量若在當(dāng)前函數(shù)作用域中沒(méi)有找到艇纺,就會(huì)向上級(jí)作用域?qū)ふ遥恢钡饺肿饔糜蚨紱](méi)找到邮弹,就會(huì)報(bào)錯(cuò)
ReferenceError
由于不同的JS文件共用一個(gè)全局作用域黔衡,很容易造成命名沖突。解決方案是:定義一個(gè)唯一的全局變量腌乡,把自己寫(xiě)的每一變量或者函數(shù)都綁定到這個(gè)全局變量上:
// 唯一的全局變量MYAPP:
var MYAPP = {};
// 其他變量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函數(shù):
MYAPP.foo = function () {
return 'foo';
};
很多著名的JS庫(kù)都是這么干的盟劫,jQuery,YUI导饲,underscore等等捞高。
解構(gòu)賦值
ES6 中可以同時(shí)對(duì)一組變量賦值
從數(shù)組中解構(gòu)賦值
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前兩個(gè)元素氯材,只對(duì)z賦值第三個(gè)元素
從對(duì)象中解構(gòu)賦值
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對(duì)象的屬性:
address; // Uncaught ReferenceError: address is not defined
解構(gòu)賦值時(shí)硝岗,也可以給個(gè)缺省值氢哮。
解構(gòu)賦值,大大簡(jiǎn)化了代碼型檀,減少了代碼量冗尤。
高階函數(shù)
map() 、filter()胀溺、 reduce() 裂七、sort()是Array的函數(shù)。將Array的元素作為參數(shù)帶入傳入的函數(shù)中仓坞。
map(funcName) / reduce(funcName)
// map() 將Arr中每一個(gè)元素分別代入函數(shù)String中背零,將每個(gè)結(jié)果組成數(shù)組返回。
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
// reduce() 將Arr中前兩個(gè)元素代入函數(shù)中无埃,將每個(gè)結(jié)果和下一個(gè)元素再次代入計(jì)算徙瓶,直到每個(gè)元素都被計(jì)算后,返回最后結(jié)果嫉称。
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
sort()
默認(rèn)把所有類型轉(zhuǎn)成字符類型再按ASCII碼排序侦镇。下面是大坑
// 看上去正常的結(jié)果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];
// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']
// 無(wú)法理解的結(jié)果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
自定義排序
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
if (x < y) {
return 1; // 調(diào)換順序
}
if (x > y) {
return -1; // 不調(diào)換順序
}
return 0; // 相等
}); // [20, 10, 2, 1]
filter()
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是變量arr
return true;
});
閉包
返回值為函數(shù)的的函數(shù)。
箭頭函數(shù)
function (x) {
return x * x;
}
相當(dāng)于x => x * x
generator(生成器)
同Python中的generator用法一樣