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

資訊專欄INFORMATION COLUMN

ES6解構(gòu)賦值運算符

qpal / 470人閱讀

摘要:本次我領(lǐng)到的任務(wù)是在中有一個解構(gòu)賦值運算符,可以大大方便數(shù)據(jù)字段的獲取。解構(gòu)賦值運算符配合會比較有用。

本次我領(lǐng)到的任務(wù)是:

在ES6中有一個解構(gòu)賦值運算符,可以大大方便數(shù)據(jù)字段的獲取。 比如

const [a, b] = [1, 2, 3];
const {name, age} = {name: "helijia", age: 3};

上面的語句是我們常用的,可是你能解釋為什么下面的語句也能正常工作嗎?

const [a, b] = "abc";
const {toString: s} = 123;

任務(wù):

1. 解釋上面兩個解構(gòu)語句的工作原理
2. 你能夠?qū)崿F(xiàn)自定義類的數(shù)組解構(gòu)嗎?

比如:

class A = …
const a = new A();
const [e1, e2] = a;  //  怎么樣才能讓自定義的類也能支持支持數(shù)組的解構(gòu)呢?

應(yīng)用 默認值

ES5時,處理默認值的慣用法:

const scale = opts.scale || 1;

現(xiàn)在可以:

const {scale = 1} = opts;

不過兩者并不等價,默認值只會在目標值是undefined時才會生效。

const {scale = 1} = {}
// scale === 1

const {scale = 1} = {scale: null}
// scale === null

const {scale = 1} = {scale: undefined}
// scale === 1
交換

有個技巧是可以在一條語句內(nèi)實現(xiàn)變量值的交換。

原來需要三句話:

var tmp = a;
var a = b;
var b = a;

現(xiàn)在只需要:

const [a, b] = [b, a];

這讓我們在實現(xiàn)一些基礎(chǔ)算法時更加精練。

函數(shù)返回多個值

在ES5中函數(shù)只能返回一個值,有了解構(gòu)賦值,可以模擬出多個返回值。

const [a, b] = f();

當(dāng)然從設(shè)計上說,js的函數(shù)的返回值還是應(yīng)該是單一的模型比較合適。

很小看到接口層面返回一個數(shù)組作為多個值。 可能在編寫一些專業(yè)領(lǐng)域或DSL應(yīng)用時會用得到。

而在實現(xiàn)時經(jīng)常會使用解構(gòu)賦值帶來的便利:

const {name, age} = getInfo();
忽略數(shù)組中的一些值
const [a, , c] = [1, 2, 3];
// a === 1
// c === c

我想到的一個應(yīng)用是一下子從正則表達式match對象中取出多個元素。

const re = /^([^=]+)=(.*)$/;
const [, key, value] = re.exec("name=helijia");
// key === "name"
// value === "helijia"
spread

解構(gòu)賦值運算符配合spread會比較有用。

const {name, age, ...exts} = item;

return ;

exts對象中并不包含name和age,如果在ES5中要費好幾句語句。

數(shù)組也支持spread,但是數(shù)組本身具有slice等函數(shù),所以一般用不上。

var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]
重命名

對象的解構(gòu)還支持重新命名,這在名字沖突,或者簡化代碼時會比較有用。

const item = {
  artisanNick: "玉米"
  artisanLevel: 10,
  artisanType: 3
};

const {artisanNick:nick, artisanLevel:level, artisanType:type} = item;

原來我們寫成

const nick = item.artisanNick;
const level = item.artisanLevel;
const type = item.artisanType;

可配合默認值一起用:

const {a:aa = 10, b:bb = 5} = {a: 3}
函數(shù)參數(shù)的解構(gòu)

這在實際開發(fā)中就用的比較多了,比如在React組件開發(fā)中:

const Product = ({name, price}) => (
  
name: {name}
price: {price}
);
babel對解構(gòu)賦值的支持

以上描述的特性使用babel編譯器就能在主流瀏覽器中工作,babel對ES6的支持是通過將代碼編譯成ES5代碼來實現(xiàn)的;
而nodejs和chrome原生是直接支持es6的,它們是基于V8引擎在解釋器層面支持ES6,因此兩者能力是有差異的。

通過babel編譯的ES6,最后本質(zhì)是ES5代碼,是靜態(tài)的,所以只能支持一些語法糖的功能;

下面是一些示例:

常量
// ES6
const [a, b, c, d] = [1, 2, 3, 4];

// 對應(yīng)的ES5
var a = 1;
var b = 2;
var c = 3;
var d = 4;
數(shù)組
// ES6
const list = [1, 2, 3, 4];
const [a, b, c, d] = list;

// ES5
var list = [1, 2, 3, 4];
var a = list[0];
var b = list[1];
var c = list[2];
var d = list[3];
別名和默認值
// ES6
const {a:aa = 10, b:bb = 5} = {a: 3}

// ES5
var _a = { a: 3 };
var _a$a = _a.a;
var aa = _a$a === undefined ? 10 : _a$a;
var _a$b = _a.b;
var bb = _a$b === undefined ? 5 : _a$b;

重命名和默認值的處理。

字符串
// ES6
const [a, b, c] = "1234";

// ES5
var _ = "1234";
var a = _[0];
var b = _[1];
var c = _[2];

字符串也當(dāng)成數(shù)組一樣處理了,所以剛好正常工作。

迭代器

其實只要實現(xiàn)迭代器接口,就能夠解構(gòu)。

const set = new Set([1, 2, 3, 4])
const [a, b, c] = set;
console.log(a, b, c);
// 1 2 3

這段代碼在chrome的cosnole和nodejs中都能正常工作,不過在babel中就歇菜了。

因為它編譯后的結(jié)果為:

var set = new Set([1, 2, 3, 4]);
var a = set[0];
var b = set[1];
var c = set[2];

console.log(a, b, c);
// undefined undefined undefined

當(dāng)然Map也是實現(xiàn)了迭代器接口的。

const map = new Map();
map.set("window", window);
map.set("document", document);

for (const [key, value] of map) {
  console.log(key + " is " + value);
}

const [[k1, v1], [k2, v2]] = map;   // destructring

再來一個例子:

function* iter() {
  yield 1;
  yield 2;
  yield 3;
}

const [a, b, c] = iter();
console.log(a, b, c);
// 1 2 3

同樣這段代碼在babel中也不能正常工作。

回到任務(wù)
const [a, b] = "abc";
const {toString: s} = 123;

任務(wù):

1. 解釋上面兩個解構(gòu)語句的工作原理
2. 你能夠?qū)崿F(xiàn)自定義類的數(shù)組解構(gòu)嗎?

所以以上兩個語句能正常工作,原因是分場景的,在通過babel編譯成ES5和通過解釋器直接執(zhí)行原理是不一樣的。

babel編譯器會把它編譯成

// ES6
const [a, b, c] = "1234";
const {toString: s} = "123";

// ES5
var _ = "1234";
var a = _[0];
var b = _[1];
var c = _[2];
var _2 = "123";
var s = _2.toString;

而js引擎執(zhí)行ES6是因為字符串實現(xiàn)了迭代器接口,以及支持對象屬性訪問。

對于第2個問題,我們可以讓自定義類實現(xiàn)迭代器接口來支持,只是在babel中不能正常工作。

以下是一個示例:

class Random {
  [Symbol.iterator]() {
    return {
      next() {
        return {value: Math.random(), done: false};
      }
    }
  }
}

const random = new Random();
for (const n of random) {
  if (n > 0.8) {
    break;
  }
  console.log(n);
}

const [e1, e2, e3, e4] = new Random();
console.log(e1, e2, e3, e4);
規(guī)范和V8對解構(gòu)賦值的支持

運行語義

看到數(shù)組的解構(gòu)處理,第一步總是取得一個迭代器,然后操作這個迭代器。

從規(guī)范中知道,解構(gòu)賦值操作符對應(yīng)的元素就是 DestructuringAssignment,查詢V8代碼可知,

V8在parser階段就會把解構(gòu)賦值語句重寫成等效的賦值語句, 這樣解釋器不需要做修改就可以運行新的語法,也保證了效率。

關(guān)鍵代碼片段:

RewriteDestructuringAssignments

RewriteDestructuringAssignment

VisitArrayLiteral

Pattern Match

使用了近一年半的Elixir,有許多語言特性另人著迷,其中模式匹配就是一個。

在ES6中引入了和模式匹配語法有點接近的解構(gòu)賦值(Destructring Assigmnent)語句,但是僅僅是部分精簡代碼的語法糖,而在語義和表達上并沒有本質(zhì)變化。

不過搜索github上,看到已有相關(guān)的proposal,以及babel實現(xiàn)的issue,所以借此機會熟悉了解一番。

另外發(fā)現(xiàn)一個js庫js-pattern-matching,提供了一個函數(shù)來支持模式匹配

其中這個JS庫在不引入新語法特性的基礎(chǔ)上支持較好的模式匹配語法,我覺得挺贊的。 它的原理是利用function.toString,得到函數(shù)字符串,再生成匹配的新的函數(shù)。

我寫了幾個簡單的示例試用了一下,感覺還不錯,不過在類型匹配時有些BUG。

基于解構(gòu)賦值的匹配
const match = require("js-pattern-matching");

const sum = (list) => match(list) (
  ([x,...xs]) => x + sum(xs),
  ([]) => 0
);

console.log(sum([]));
console.log(sum([1, 2, 3, 4]));
常量匹配

因為要符合語法,所以加個前續(xù)v=,文檔說是可改成其他字母。

const fibs = (n) => match(n) (
  (v= 0) => 0,
  (v= 1) => 1,
  _ => fibs(n - 2) + fibs(n - 1)
);

for (let i = 0; i < 10; i++) {
  console.log(fibs(i));
}
類型匹配
const type = (v) => match(v) (
  (Array) => "array",
  (Object) => "object",
  _ => "unknow"
);

我也看了proposal的語法,感覺風(fēng)格和原來的js差異太大,設(shè)計成Expression,可以在任何地方使用,可能會因為功能太強而導(dǎo)致濫用,反而起不到原來模式匹配優(yōu)雅簡潔的目的。

其他人的一些探索,不過這個語法不是很美觀。

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

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

相關(guān)文章

  • 學(xué)習(xí)ES6 變量的解構(gòu)賦值

    摘要:變量的解構(gòu)賦值數(shù)組的解構(gòu)賦值允許寫成下面這樣本質(zhì)上,這種寫法屬于模式匹配,只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值。對象的解構(gòu)賦值對象的解構(gòu)與數(shù)組有一個重要的不同。由于和無法轉(zhuǎn)為對象,所以對他們進行解構(gòu)賦值,都會報錯。 變量的解構(gòu)賦值 數(shù)組的解構(gòu)賦值 let a = 1; let b = 2; let c = 3; ES6允許寫成下面這樣 let [a,b,c] = [1,...

    sugarmo 評論0 收藏0
  • ES6-變量的解構(gòu)賦值(3)

    摘要:數(shù)組的解構(gòu)賦值特點根據(jù)數(shù)據(jù)的下標來賦值的,有次序。模式能夠匹配起來,如長度為數(shù)值和布爾值的解構(gòu)賦值解構(gòu)賦值的規(guī)則是只要等號右邊的值不是對象或數(shù)組,就先將其轉(zhuǎn)為對象。布爾值解構(gòu)賦值為字符串的一種。在很多獨立細小的方面,解構(gòu)賦值都非常有用。 1、解構(gòu)賦值簡介 官方解釋:按照一定的模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)(Destructuring)。 舉個例子,想獲取數(shù)組中...

    Jason_Geng 評論0 收藏0
  • es6解構(gòu)賦值、擴展算符、rest參數(shù)使用

    摘要:模板字符串甚至還能嵌套解構(gòu)賦值允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)。運算符使用場景應(yīng)該稍少一些,主要是處理不定數(shù)量參數(shù),可以避免對象的使用。 es6中較為常用的書寫風(fēng)格 為了書寫的方便,es6中提出了很多比較友好的書寫方式,其中最為常見的屬于以下幾個: 字符串模板 `abcdef${test}` 解構(gòu)賦值 let [a, b, c] = [1,...

    xuweijian 評論0 收藏0
  • [譯] 最深刻而易懂的ES6解構(gòu)教程

    摘要:被解構(gòu)的數(shù)據(jù)項位于賦值運算符的右側(cè),可以是任何數(shù)組和對象的組合,允許隨意嵌套。數(shù)組模式位于賦值運算符的左側(cè),被結(jié)構(gòu)的數(shù)組在其右側(cè)。 解構(gòu)是ES6的新特性,用于從JavaScript對象和數(shù)組中提取數(shù)據(jù),語法上比ES5所提供的更加簡潔、緊湊、清晰。它不僅能減少你的代碼量,還能從根本上改變你的編碼方式。用的越多,你就會發(fā)現(xiàn)越多塑造數(shù)據(jù)和函數(shù)的方式,這些實現(xiàn)方式在過去幾乎是不可能的。本文將深...

    AlphaGooo 評論0 收藏0
  • ES6 ...操作符

    摘要:在語法中,操作符有兩種意義剩余語法,參數(shù)和展開語法,展開數(shù)組對象,作為函數(shù)數(shù)組對象的擴展運算符。使用和參數(shù)進行操作其余參數(shù)傳給原始函數(shù)展開語法運算則可以看作是參數(shù)的逆運算。 在ES6語法中,...操作符有兩種意義:rest(剩余語法,rest參數(shù)) 和 spread(展開語法,展開數(shù)組/對象),作為函數(shù)、數(shù)組、對象的擴展運算符。 從某種意義上說,剩余語法與展開語法是相反的:剩余語法將多...

    MorePainMoreGain 評論0 收藏0

發(fā)表評論

0條評論

qpal

|高級講師

TA的文章

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