function name([參數, 參數, ... 參數) { statements }複製代碼
function myFunc(theObject) { theObject.make = "Toyota"; }var mycar = {make: "Honda", model: "Accord", year: 1998};var x, y; x = mycar.make; // x獲取的值爲 "Honda"myFunc(mycar); y = mycar.make; // y獲取的值爲 "Toyota"// (make屬性被函數改變了)複製代碼
hoisted(); // "foo"function hoisted() { console.log("foo"); }/* equal to*/var hoisted; hoisted = function() { console.log("foo"); } hoisted();// "foo" 複製代碼
let 變量名稱 = function 函數名稱(參數, 參數, ...參數) { statements };複製代碼
const square = function(number) { return number * number; };var x = square(4); // x gets the value 16const factorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};console.log(factorial(3));複製代碼
notHoisted(); // TypeError: notHoisted is not a functionvar notHoisted = function() { console.log('bar'); };複製代碼
定義一個生成器函數 (generator function),它返回一個 Generator 對象。數組
function* 函數名(參數,參數, ... 參數) { statements }複製代碼
function* generator(i) { yield i; yield i + 10; }const gen = generator(10);console.log(gen.next().value);// expected output: 10console.log(gen.next().value);// expected output: 20複製代碼
var x = function*(y) { yield y * y; };複製代碼
(param1, param2, …, paramN) => { statements }複製代碼
var elements = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium']; elements.map(function(element) { return element.length; }); // 返回數組:[8, 6, 7, 9]// 上面的普通函數能夠改寫成以下的箭頭函數elements.map((element) => { return element.length; }); // [8, 6, 7, 9]// 當箭頭函數只有一個參數時,能夠省略參數的圓括號elements.map(element => { return element.length; }); // [8, 6, 7, 9]// 當箭頭函數的函數體只有一個 `return` 語句時,能夠省略 `return` 關鍵字和方法體的花括號elements.map(element => element.length); // [8, 6, 7, 9]// 在這個例子中,由於咱們只須要 `length` 屬性,因此可使用參數解構// 須要注意的是字符串 `"length"` 是咱們想要得到的屬性的名稱,而 `lengthFooBArX` 則只是個變量名,// 能夠替換成任意合法的變量名elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]複製代碼
function Person() { // Person() 構造函數定義 `this`做爲它本身的實例. this.age = 0; setInterval(function growUp() {// 在非嚴格模式, growUp()函數定義 `this`做爲全局對象,// 與在 Person()構造函數中定義的 `this`並不相同.this.age++; }, 1000); }var p = new Person();複製代碼
<!--經過將this值分配給封閉的變量,能夠解決this問題-->function Person() { var that = this; that.age = 0; setInterval(function growUp() {// 回調引用的是`that`變量, 其值是預期的對象.that.age++; }, 1000); }複製代碼
<!--箭頭函數不會建立本身的this,它只會從本身的做用域鏈的上一層繼承this-->function Person(){ this.age = 0; setInterval(() => {this.age++; // |this| 正確地指向 p 實例 }, 1000); }var p = new Person();複製代碼
//結果爲true證實沒函數都是一個Function對象(function(){}).constructor === Function //true複製代碼
<!--能夠正常執行-->const sum = new Function("a", "b", "return a + b");console.log(sum(2, 6)); <!--能夠正常執行-->const sum2 = Function.prototype.constructor( "a", "b", "return a + b" );console.log(sum2(2, 6));複製代碼
<!--用法--> new Function (參數, 參數, ...參數, functionBody字符串) //例如 const sum = new Function('a', 'b', 'return a + b'); console.log(sum(2, 6)); // expected output: 8複製代碼
const x = 10;function createFunction1() {const x = 20;return new Function("return x;"); // 這裏的 x 指向最上面全局做用域內的 x}function createFunction2() {const x = 20;function f() {return x; // 這裏的 x 指向上方本地做用域內的 x}return f; }const f1 = createFunction1();console.log(f1()); // 10const f2 = createFunction2();console.log(f2()); // 20複製代碼
每次構造函數被調用,傳遞給Function構造函數的函數體字符串都要被解析一次 。安全
雖然函數表達式每次都建立了一個閉包,但函數體不會被重複解析,所以函數表達式仍然要快於"new Function(...)"閉包
在經過解析Function構造函數字符串產生的函數裏,內嵌的函數表達式和函數聲明不會被重複解析。app
Object.getPrototypeOf(function*(){}).constructor複製代碼
new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody字符串)複製代碼
var GeneratorFunction = Object.getPrototypeOf(function*(){}).constructorvar g = new GeneratorFunction("a", "yield a * 2");var iterator = g(10);console.log(iterator.next().value); // 20複製代碼
// 下面的變量定義在全局做用域(global scope)中var num1 = 20, num2 = 3, name = "Chamahk";// 本函數定義在全局做用域function multiply() { return num1 * num2; } multiply(); // 返回 60// 嵌套函數的例子function getScore() { var num1 = 2, num2 = 3; function add() {return name + " scored " + (num1 + num2); } return add(); } getScore(); // 返回 "Chamahk scored 5"複製代碼
var pet = function(name) { //外部函數定義了一個變量"name" var getName = function() {//內部函數能夠訪問 外部函數定義的"name"return name; } //返回這個內部函數,從而將其暴露在外部函數做用域 return getName; }; myPet = pet("Vivie"); myPet(); 複製代碼
function outside() { var x = 5; function inside(x) {return x * 2; } return inside; } outside()(10); // returns 20 instead of 10複製代碼
function func1(a, b, c) { console.log(arguments[0]); // expected output: 1 console.log(arguments[1]); // expected output: 2 console.log(arguments[2]); // expected output: 3} func1(1, 2, 3);複製代碼
從ECMAScript 6開始,有兩個新的類型的參數:默認參數,剩餘參數ide
在JavaScript中,函數參數的默認值是 undefined。在過去,用於設定默認參數的通常策略是在函數的主體中測試參數值是否爲undefined,若是是則賦予這個參數一個默認值。函數
function multiply(a, b) { b = (typeof b !== 'undefined') ? b : 1; return a*b; } multiply(5); // 5複製代碼
<!--使用默認參數,在函數體的檢查就再也不須要-->function multiply(a, b = 1) { return a*b; } multiply(5); // 5複製代碼
剩餘參數語法容許將不肯定數量的參數表示爲數組。測試
function multiply(multiplier, ...theArgs) { return theArgs.map(x => multiplier * x); }var arr = multiply(2, 1, 2, 3);console.log(arr); // [2, 4, 6]複製代碼