国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ECMAScript6 新特性——“函數(shù)的擴(kuò)展”

Jiavan / 2970人閱讀

摘要:返回空字符串,返回將一個具名函數(shù)賦值給一個變量,則和的屬性都返回這個具名函數(shù)原本的名字。不可以使用對象,該對象在函數(shù)體內(nèi)不存在。等到運(yùn)行結(jié)束,將結(jié)果返回到,的調(diào)用幀才會消失。

1 函數(shù)參數(shù)的默認(rèn)值

ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面:

function log(x = "message.",y = "duration infomation.") {
    console.log(x, y);
}

log(); //message. duration infomation.
log("hello world.", "connecting."); //hello world. connecting.

參數(shù)變量是默認(rèn)聲明的,所以不能用let和const再次聲明

function add(x = 0, y = 0) {
    let x; //報(bào)錯
    const y; //報(bào)錯
    console.log(x + y);
}
add();

與結(jié)構(gòu)賦值默認(rèn)值結(jié)合使用

function add({x = 0, y = 0}) {
    console.log(x + y);
}
add({}); //0
add({y: 1}); //1

//當(dāng)add()時,則會報(bào)錯
add(); //報(bào)錯

//如何才能在add()時不報(bào)錯呢?
//這就需要用到雙重默認(rèn)值,即默認(rèn)為函數(shù)傳入一個對象
function add({x = 0, y = 0} = {}) {
    console.log(x + y);
}
add({}); //0
add({y: 1}); //1
add(); //0

如下:

function add({name = "your name here", age = "your age here"} = {}) {
    console.log(`${name}, ${age}`);
}
add(); //your name here, your age here
add({name: "Oliver"}); //Oliver, your age here
add({name: "Troy", age: 18}); //Troy, 18

函數(shù)的length屬性

指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個數(shù)。

function add(x,y = 0) {
    console.log(x + y);
}
console.log(add.length); //1 函數(shù)預(yù)期傳入1個參數(shù),因?yàn)橛幸粋€參數(shù)已經(jīng)有默認(rèn)值了

作用域

如果參數(shù)默認(rèn)值是一個變量,則該變量所處的作用域,與其他變量的作用域規(guī)則是一樣的,即先是當(dāng)前函數(shù)的作用域,然后才是全局作用域。

var x = 10;
function log(x, y = x) { //x已經(jīng)在內(nèi)部生成,使用的將是內(nèi)部的x
    console.log(y);
}
log(2); //2

var x = 10;
function log(y = x) { //x不存在,使用的將是外部的x
    console.log(y);
}
log(); //10

實(shí)際應(yīng)用

省略參數(shù)拋出錯誤:

function throwIfMissing() {
    throw new Error("Missing parameter.");
}
function foo(x = throwIfMissing()) {
    return x;
}
console.log(foo(10)); //10
console.log(foo()); //Uncaught Error: Missing parameter.
2 rest參數(shù)

rest參數(shù)(形式為“...變量名”),用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對象了

function foo(...values) {
    let sum = 0;
    for(let val of values) sum += val;
    console.log(sum);
}
foo(1,2,3);

注意,rest參數(shù)之后不能再有其他參數(shù)(即只能是最后一個參數(shù)),否則會報(bào)錯。

function foo(x, ...values) {
    let sum = 0;
    for(let val of values) sum += val;
    console.log(x, sum);
}
foo(1,2,3); //x是1,sum是2+3

function foo(x, ...values, y) {
    let sum = 0;
    for(let val of values) sum += val;
    console.log(x, sum);
}
foo(1,2,3); //Rest parameter must be last formal parameter
3 擴(kuò)展運(yùn)算符

擴(kuò)展運(yùn)算符(spread)是三個點(diǎn)(...)。它好比rest參數(shù)的逆運(yùn)算,將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列。

let a = [1,2,3,4,5,6,7];
console.log(...a); //1 2 3 4 5 6 7
a.push(...a);
console.log(a); //[1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7]

該運(yùn)算符主要用于函數(shù)的調(diào)用

let a = [1,2,3,4,5,6,7];
function add(...args) {
    let sum = 0;
    for (let val of args) console.log(sum += val);
    console.log(`done. final sum: ${sum}`);
}
add(...a); //依次傳入a數(shù)列中的值
//1
//3
//6
//10
//15
//21
//28
//done. final sum: 28

替代數(shù)組的apply方法

擴(kuò)展運(yùn)算符可以展開數(shù)組,所以不再需要apply方法

//ES5
let a = [1,2,3,4,5,6,7];
console.log(Math.max.apply(null,a)); //7
//ES6
console.log(Math.max(...a)); //7

又比如push函數(shù)

let a = [];
let num = [1,2,3,4,5,6,7];
a.push(...num);
console.log(a.toString()); //1,2,3,4,5,6

擴(kuò)展運(yùn)算符的應(yīng)用

合并數(shù)組

let a = [];
let a1 = [1,2,3];
let a2 = [4,5];
let a3 = [6,7,8,9,10];
a = [...a1, ...a2, ...a3];
console.log(a.toString()); //1,2,3,4,5,6,7,8,9,10

與解構(gòu)賦值結(jié)合

let [...rest] = [1,2,3,4,5,6];
console.log(rest); //[1,2,3,4,5,6]

函數(shù)的返回值

var dateFields = readDateFields(database);
var d = new Date(...dateFields);

字符串

console.log([..."hello"]); //["h", "e", "l", "l", "o"]

擴(kuò)展運(yùn)算符能夠識別32位Unicode字符

可以正確返回字符串長度:

console.log([..."hello"]); //["h", "e", "l", "l", "o"]
function len(...args) {
    for (let val of args) console.log([...val].length);
}
len("hello", "another one 哈哈"); //14

類似數(shù)組的對象

var nodeList = document.getElementsByTagName("p");
var array = [...nodeList];

含有Iterator接口對象

只要具有Iterator接口的對象,都可以使用擴(kuò)展運(yùn)算符

Map,Set,Generator等

4 name屬性

函數(shù)的name屬性,返回該函數(shù)的函數(shù)名。

如果將一個匿名函數(shù)賦值給一個變量,ES5的name屬性,會返回空字符串,而ES6的name屬性會返回實(shí)際的函數(shù)名。

var x = function() {};
console.log(x.name); //"" ES5返回空字符串,ES6返回x

將一個具名函數(shù)賦值給一個變量,則ES5和ES6的name屬性都返回這個具名函數(shù)原本的名字。

var x = function y() {};
console.log(x.name); //"y"

Function構(gòu)造函數(shù)返回的函數(shù)實(shí)例,name屬性的值為“anonymous”。

console.log((new Function).name); //anonymous

bind返回的函數(shù),name屬性值會加上“bound ”前綴。

function foo() {};
foo.bind({}).name // "bound foo"

(function(){}).bind({}).name // "bound "
5 箭頭函數(shù)

ES6允許使用“箭頭”(=>)定義函數(shù)。

let add = (x,y) => x + y;
console.log(add(1,2)); //3

function add(x,y) {
    return x + y;
}
console.log(add(1,2)); //3

如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號將它們括起來,并且使用return語句返回。

let add = (x, y) => {
    console.log("done");
    return x + y;
};
console.log(add(1, 2)); //3

如果箭頭函數(shù)直接返回一個對象,必須在對象外面加上括號。

let add = (x, y) => ({ result: x + y });
console.log(add(1, 2).result); //3

箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用。

let add = ({ name, age }) => ({ result: `${name},${age}` });
console.log(add({ name: "Oliver", age: 18 }).result); //Oliver,18

箭頭函數(shù)的一個用處是簡化回調(diào)函數(shù)

var arr = [1, 2, 3, 4, 5];
arr.map(function(item, index, array) {
    console.log(item);
});

arr.map((item, index, array) => { console.log(item); });

//上面兩種函數(shù)寫法功能相同,下面的明顯較為簡潔

使用注意點(diǎn)

函數(shù)體內(nèi)的this對象,就是定義時所在的對象,而不是使用時所在的對象。

不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會拋出一個錯誤。

不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在。如果要用,可以用Rest參數(shù)代替。

不可以使用yield命令,因此箭頭函數(shù)不能用作Generator函數(shù)。

6 ES7函數(shù)綁定

ES7中函數(shù)綁定運(yùn)算符(::)作用是代替call、apply、bind調(diào)用。

7 尾調(diào)用優(yōu)化

尾調(diào)用

尾調(diào)用(Tail Call)就是指某個函數(shù)的最后一步是調(diào)用另一個函數(shù):

function g() {
    console.log("done.");
}

function j() {
    console.log("almost done.");
}

function log(x) {
    if (x > 0) {
        return g();
    }
    return j();
}
log(10); //done.
log(0); //almost done.

g()和j()的調(diào)用都屬于尾調(diào)用,因?yàn)槎际呛瘮?shù)的最后一步

尾調(diào)用優(yōu)化

函數(shù)調(diào)用會在內(nèi)存形成一個“調(diào)用記錄”,又稱“調(diào)用幀”(call frame),保存調(diào)用位置和內(nèi)部變量等信息。如果在函數(shù)A的內(nèi)部調(diào)用函數(shù)B,那么在A的調(diào)用幀上方,還會形成一個B的調(diào)用幀。等到B運(yùn)行結(jié)束,將結(jié)果返回到A,B的調(diào)用幀才會消失。如果函數(shù)B內(nèi)部還調(diào)用函數(shù)C,那就還有一個C的調(diào)用幀,以此類推。所有的調(diào)用幀,就形成一個“調(diào)用棧”(call stack)。

尾調(diào)用由于是函數(shù)的最后一步操作,所以不需要保留外層函數(shù)的調(diào)用幀,因?yàn)檎{(diào)用位置、內(nèi)部變量等信息都不會再用到了,只要直接用內(nèi)層函數(shù)的調(diào)用幀,取代外層函數(shù)的調(diào)用幀就可以了。

注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行“尾調(diào)用優(yōu)化”。

function addOne(a) {
    var one = 1;

    function inner(b) {
        return b + one;
    }
    return inner(a);
}

尾遞歸

遞歸非常耗費(fèi)內(nèi)存,因?yàn)樾枰瑫r保存成千上百個調(diào)用幀,很容易發(fā)生“棧溢出”錯誤。但對于尾遞歸來說,由于只存在一個調(diào)用幀,所以永遠(yuǎn)不會發(fā)生“棧溢出”錯誤。

所以確保最后只調(diào)用自身就可以了,做法是將所有參數(shù)傳入要調(diào)用的函數(shù)中去:

// function log(n) {
//     if (n === 1) {
//         return 1
//     };
//     return n * log(n - 1);
// }
// console.log(log(5)); //120

function log(n, total) {
    if (n === 1) {
        return total
    };
    return log(n - 1, n * total);
}
console.log(log(5, 1)); //120
8 ES7函數(shù)參數(shù)的尾逗號

ES7提案允許函數(shù)的最后一個參數(shù)有尾逗號。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79157.html

相關(guān)文章

  • ECMAScript6(5):函數(shù)擴(kuò)展

    摘要:否則調(diào)用時依然需要傳參報(bào)錯注意這里不能用觸發(fā)默認(rèn)值這里我們還需要單獨(dú)討論一下默認(rèn)參數(shù)對的影響很明顯,默認(rèn)參數(shù)并不能加到中。關(guān)于作用域集中在函數(shù)擴(kuò)展的最后討論。那如果函數(shù)的默認(rèn)參數(shù)是函數(shù)呢?zé)X的要來了如果基礎(chǔ)好那就根本談不上不燒腦。 參數(shù)默認(rèn)值 ES5中設(shè)置默認(rèn)值非常不方便, 我們這樣寫: function fun(a){ a = a || 2; console.log(a); ...

    afishhhhh 評論0 收藏0
  • ECMAScript6 特性——“l(fā)et和const命令”

    摘要:基本用法所聲明的變量,只在命令所在的代碼塊內(nèi)有效。在循環(huán)中適合使用不存在變量提升不像那樣會發(fā)生變量提升現(xiàn)象暫時性死區(qū)只要塊級作用域內(nèi)存在命令,它所聲明的變量就綁定這個區(qū)域,不再受外部的影響。塊級作用域?qū)嶋H上為新增了塊級作用域。 1 let 基本用法 所聲明的變量,只在let命令所在的代碼塊內(nèi)有效。 { let b = 100; console.log(b); //100...

    PascalXie 評論0 收藏0
  • ECMAScript6 特性——“正則擴(kuò)展

    摘要:第二個參數(shù)指定修飾符,如果存在則使用指定的修飾符。屬性表示是否設(shè)置了修飾符屬性的屬性返回正則表達(dá)式的正文的屬性返回正則表達(dá)式的修飾符字符串必須轉(zhuǎn)義,才能作為正則模式。 1 RegExp構(gòu)造函數(shù) ES6 允許RegExp構(gòu)造函數(shù)接受正則表達(dá)式作為參數(shù)。第二個參數(shù)指定修飾符,如果存在則使用指定的修飾符。 var regexp = new RegExp(/xyz/i, ig); consol...

    Shisui 評論0 收藏0
  • ECMAScript6 特性——“數(shù)值擴(kuò)展

    摘要:二進(jìn)制和八進(jìn)制表示法提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴或和或表示。用來檢查是否為有窮以及是否為這兩個新方法只對數(shù)值有效,非數(shù)值一律返回。引入了和這兩個常量,用來表示這個范圍的上下限。因?yàn)橛芯认拗疲^的次方的值無法精確表示。 1 二進(jìn)制和八進(jìn)制表示法 ES6提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴0b(或0B)和0o(或0O)表示。 console.log(0b10...

    Dean 評論0 收藏0
  • ECMAScript6 特性——“變量解構(gòu)賦值”

    摘要:數(shù)組的解構(gòu)賦值允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)。如果變量名與屬性名不一致,必須寫成下面這樣。 1 數(shù)組的解構(gòu)賦值 ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)。 基本用法 { var [a,[b,c],d,,...f] = [1,[2,3],4,5,6,7]; console...

    Eric 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<