成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6入門之函數(shù)的擴(kuò)展

graf / 985人閱讀

摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會(huì)取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行尾調(diào)用優(yōu)化。

1. 函數(shù)參數(shù)的默認(rèn)值
1.1 用法
在ES6之前是不能為函數(shù)的參數(shù)指定默認(rèn)值的,要想實(shí)現(xiàn)默認(rèn)值只能通過判斷賦值的方式來實(shí)現(xiàn),在ES6中允許函數(shù)為參數(shù)設(shè)置默認(rèn)值,主要是為了提高代碼的可閱讀性,有利于代碼的優(yōu)化。另外注意的是在參數(shù)賦值的時(shí)候,該參數(shù)不能重復(fù)使用,不能使用let const 進(jìn)行定義。
// ES6 之前實(shí)現(xiàn)
function log(x, y) {
  y = y || "World";
  if (typeof y === "undefined") {
      y = "World";
  }
  console.log(x, y);
}

log("Hello") // Hello World
log("Hello", "China") // Hello China
log("Hello", "") // Hello World


// ES6 中實(shí)現(xiàn)
function log(x, y = "World") {
  console.log(x, y);
}

log("Hello") // Hello World
log("Hello", "China") // Hello China
log("Hello", "") // Hello

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
}

const p = new Point();
p // { x: 0, y: 0 }

function foo(x = 5,x) { 
  let x = 1; // 報(bào)錯(cuò),不能同名參數(shù),不能對(duì)參數(shù)進(jìn)行l(wèi)et const 定義
  const x = 2;
}
1.2 與解構(gòu)賦值一起使用
如果函數(shù)在調(diào)用的時(shí)候沒有提供參數(shù),內(nèi)部變量就不會(huì)產(chǎn)生,就會(huì)產(chǎn)生錯(cuò)誤,通過提供函數(shù)的默認(rèn)值可以解決這種問題,如下:
function foo({x, y = 5}) {
  console.log(x, y);
}
foo() // 報(bào)錯(cuò)
foo({x:1}) // 1 5
foo({x:2,y:3) // 2 3
foo({}) // undefined 5

function foo ({x,y = 5} = {}){
    console.log(x,y)
}
foo() // undefined 5 
這樣就是如果沒有在調(diào)用的時(shí)候傳值 就默認(rèn)賦空對(duì)象。
如下例子:
function post(url, {b = "",type="get",h={}}){
    console.log(type)
}

post("w.b.c",{}) // get
post("w.b.c")    // 報(bào)錯(cuò)

// 改成這樣就可以了

function post(url, {b = "",type="get",h={}} = {}){
    console.log(type)
}

post("w.b.c",{}) // get
post("w.b.c")    // get
下面例子的區(qū)別
// 寫法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 寫法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

兩個(gè)都是有默認(rèn)值在調(diào)用的時(shí)候都傳值或者都不傳值的時(shí)候情況是一樣的。
但是如果傳空值,或者不傳值的情況會(huì)有差異如下:

m1({}) // 因?yàn)楸旧碛心J(rèn)值 所以為 [0,0]
m2({}) // 默認(rèn)值為空 解構(gòu)賦值沒有傳值 所以 [undefined,undefined]

// 其他情況同上
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]
m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]
1.3 參數(shù)默認(rèn)值的位置
如果定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)。而且這個(gè)參數(shù)是無法省略的,除非輸入undefined
1.4 函數(shù)的 length 屬性
函數(shù)參數(shù)指定了默認(rèn)值之后,函數(shù)的length屬性將會(huì)減去指定了默認(rèn)值的參數(shù)個(gè)數(shù)。因?yàn)樵搶傩哉J(rèn)為,指定了默認(rèn)值的參數(shù)將不包含在預(yù)期參數(shù)個(gè)數(shù)中。如下:
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
1.5 作用域
如果函數(shù)中的參數(shù)設(shè)置了默認(rèn)值,那么函數(shù)在聲明初始化的時(shí)候,參數(shù)會(huì)形成一個(gè)多帶帶的作用域,初始化完成后這個(gè)作用域就會(huì)消失,這種情況只在參數(shù)設(shè)置了默認(rèn)值的情況下。如下:
var x = 1;

function f(x, y = x) {
  console.log(y);
}

f(2) // 2
// 因?yàn)?設(shè)置了默認(rèn)值 所以在調(diào)用 f 的時(shí)候就形成了作用域,這時(shí)候因?yàn)閷賦值給y 
傳入的x 為 2  所以y是2,如果這時(shí)候 調(diào)用的時(shí)候不傳值,
那么x將指向全局,所以y = 1
1.6 應(yīng)用
利用參數(shù)默認(rèn)值,可以指定某一個(gè)參數(shù)不得省略,如果省略就報(bào)錯(cuò),如下
function throwIfMissing() {
  throw new Error("Missing parameter");
}

function foo(mustBeProvided = throwIfMissing()) {
  return mustBeProvided;
}

foo()
// Error: Missing parameter
foo(2) // 2
2. rest 參數(shù)
ES6 中 增加了 rest 參數(shù)(...變量名),用于獲取函數(shù)多余的參數(shù),rest參數(shù)搭配的變量是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中。
function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

// 注意:rest 參數(shù)之后不能再有其他參數(shù),另外rest參數(shù)也不計(jì)算在
函數(shù)的length屬性中。
3. 嚴(yán)格模式
ES6 中,如果函數(shù)參數(shù)使用了默認(rèn)值,解構(gòu)賦值,或者擴(kuò)展運(yùn)算符,那么函數(shù)內(nèi)部將不能顯式設(shè)定為嚴(yán)格模式,否則會(huì)報(bào)錯(cuò)。因?yàn)楹瘮?shù)執(zhí)行的時(shí)候 先執(zhí)行函數(shù)參數(shù),在執(zhí)行函數(shù)體,但是因?yàn)橹挥性诤瘮?shù)體中才能知道參數(shù)是否以嚴(yán)格模式執(zhí)行,但是參數(shù)卻應(yīng)該先于函數(shù)執(zhí)行。有兩種方法可以規(guī)避:一、 設(shè)置全局嚴(yán)格模式,二、把函數(shù)包在一個(gè)無參數(shù)的立即執(zhí)行函數(shù)里面。
4. name屬性
返回函數(shù)的函數(shù)名,如下:
function foo(){}
foo.name // foo

var f = function(){}
// ES5
f.name // ""
// ES6
f.name // f

var f = function c(){}

f.name // c
5. 箭頭函數(shù)
ES6 允許使用 “箭頭” (=>)定義函數(shù)
var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

// 如果箭頭函數(shù)后面的語句較多就要用大括號(hào)包裹起來 并return返回
var sum = (num1, num2) => { return num1 + num2; 

//rest 參數(shù)與箭頭函數(shù)結(jié)合的例子。

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]

const headAndTail = (head, ...tail) => [head, tail];

headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]
注意點(diǎn)
1. 函數(shù)體內(nèi)的this對(duì)象,就是在定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象。
2. 不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤。
3. 不可以使用arguments對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用,可以用 rest 參數(shù)代替。
4. 不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)。
5. 由于箭頭函數(shù)沒有自己的this,所以當(dāng)然也就不能用call()、apply()、bind()這些方法去改變this的指向。
不適用場景
1. 定義對(duì)象的方法,且該方法內(nèi)部包括this
2. 動(dòng)態(tài)定義this 的場合,如點(diǎn)擊事件中this 的指向
嵌套的箭頭函數(shù)
箭頭函數(shù)內(nèi)部可以在嵌套使用箭頭函數(shù)。
6. 尾調(diào)用優(yōu)化
什么是尾調(diào)用
函數(shù)式編程的一個(gè)重要概念,指某個(gè)函數(shù)的最后一步是調(diào)用另一個(gè)函數(shù)
function f(x){
  return g(x);
}

// 一下都不屬于
// 情況一
function f(x){
  let y = g(x);
  return y;
}

// 情況二
function f(x){
  return g(x) + 1;
}

// 情況三
function f(x){
  g(x);
}
尾調(diào)用優(yōu)化
只保留內(nèi)層函數(shù)的調(diào)用幀。如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。這就是“尾調(diào)用優(yōu)化”的意義。
function f() {
  let m = 1;
  let n = 2;
  return g(m + n);
}
f();

// 等同于
function f() {
  return g(3);
}
f();

// 等同于
g(3);

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

尾遞歸
函數(shù)調(diào)用自身,稱為遞歸。如果尾調(diào)用自身,就稱為尾遞歸。
ES6 的尾調(diào)用優(yōu)化只在嚴(yán)格模式下開啟,正常模式是無效的。
尾遞歸優(yōu)化的實(shí)現(xiàn)
在正常模式下,可以使用減少調(diào)用棧,采用循環(huán)換掉遞歸的方法

歡迎關(guān)注 公眾號(hào)【小夭同學(xué)】

ES6入門系列

ES6入門之let、cont

ES6入門之變量的解構(gòu)賦值

ES6入門之字符串的擴(kuò)展

ES6入門之正則的擴(kuò)展

ES6入門之?dāng)?shù)值的擴(kuò)展

Git教程

前端Git基礎(chǔ)教程

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103917.html

相關(guān)文章

  • ES6入門對(duì)象擴(kuò)展

    摘要:循環(huán)遍歷對(duì)象自身的和繼承的可枚舉屬性不含屬性。返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性的鍵名。目前,只有對(duì)象方法的簡寫法可以讓引擎確認(rèn),定義的是對(duì)象的方法。showImg(https://user-gold-cdn.xitu.io/2019/5/21/16ada8456223b0e1); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量和函數(shù),作為對(duì)象的屬性和方法,使得代碼的書寫更為簡潔。...

    RiverLi 評(píng)論0 收藏0
  • ES6入門對(duì)象擴(kuò)展

    摘要:屬性的簡潔表示法在中允許直接寫入變量和函數(shù),作為對(duì)象的屬性和方法,使得代碼的書寫更為簡潔。循環(huán)遍歷對(duì)象自身的和繼承的可枚舉屬性不含屬性。返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性的鍵名。 showImg(https://segmentfault.com/img/remote/1460000019259004?w=1282&h=1920); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量...

    AWang 評(píng)論0 收藏0
  • ES6入門函數(shù)擴(kuò)展

    摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會(huì)取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行尾調(diào)用優(yōu)化。 showImg(https://segmentfault.com/img/bVbrTHp?w=1080&h=1920); 1. 函數(shù)參數(shù)的默認(rèn)值 1.1 用法 在ES6之前是不能為...

    dackel 評(píng)論0 收藏0
  • ES6入門對(duì)象新增方法

    showImg(https://user-gold-cdn.xitu.io/2019/5/22/16adcec448a45d82); 1. Object.is() 用來解決在ES5中 兩種相等運(yùn)算符的缺點(diǎn)。用來比較兩個(gè)值是否嚴(yán)格相等,行為和(===)基本一致。 在ES5中判斷兩個(gè)值是否相等,只能用(==)相等運(yùn)算符和(===)嚴(yán)格相等運(yùn)算符,但是這兩貨都有缺點(diǎn),前者 兩邊的值都會(huì)轉(zhuǎn)換數(shù)據(jù)類型,...

    zhou_you 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<