ES6新增擴(kuò)展屬性及語法格式

let塊級作用域

怎么樣更好的認(rèn)識let;就是現(xiàn)有的聲明方式進(jìn)行比較;

1:var的聲明提升會在未初始化變量的時(shí)候提醒undefined;但是不報(bào)錯(cuò);未遵循先定義后使用的邏輯;
但是let是遵循的先定義后使用;未定義就是用的情況會報(bào)錯(cuò);
2:官方中的‘暫時(shí)性死區(qū)’;在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時(shí)性死區(qū)”;但是var不會;如圖;在使用let綁定后;也就綁定了區(qū)塊;在代碼塊內(nèi);let聲明就會出現(xiàn)暫時(shí)死區(qū);


image.png

3:不允許重復(fù)聲明:前提是在統(tǒng)一代碼塊內(nèi);另外函數(shù)內(nèi)部也不可以聲明和和參數(shù)相同的變量;但是下圖的方式可以;也就是剛才說到的在統(tǒng)一代碼塊內(nèi);


image.png

2:塊級作用域存在的意義;

 首先防止內(nèi)城變量覆蓋外層變量;第二場景用來計(jì)數(shù)的循環(huán)變量泄露為全局變量;

變量的解構(gòu)【比較重要和常用】

下面僅僅總結(jié)常用的一些語法;
首先截取剩余的數(shù)組;
let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] 1)
交換變量的值 let x = 1; let y = 2; [x, y] = [y, x];
(2)從函數(shù)返回多個(gè)值 函數(shù)只能返回一個(gè)值,如果要返回多個(gè)值,只能將它們放在數(shù)組或?qū)ο罄锓祷亍S辛私鈽?gòu)賦值,取出這些值就非常方便。 // 返回一個(gè)數(shù)組 function example() { return [1, 2, 3]; } let [a, b, c] = example(); // 返回一個(gè)對象 function example() { return { foo: 1, bar: 2 }; } let { foo, bar } = example();
(4)提取 JSON 數(shù)據(jù) 解構(gòu)賦值對提取 JSON 對象中的數(shù)據(jù),尤其有用。 let jsonData = { id: 42, status: "OK", data: [867, 5309] }; let { id, status, data: number } = jsonData; console.log(id, status, number); // 42, "OK", [867, 5309] 上面代碼可以快速提取 JSON 數(shù)據(jù)的值。

字符串的擴(kuò)展

1:includes(str,開始檢索的下標(biāo));使用includes()來代替indexOf;判斷是否含有某個(gè)字符串;
2:startsWith(str,開始檢索的下標(biāo)):返回布爾值,表示參數(shù)字符串是否在原字符串的頭部。
3:endsWith(str,檢索這個(gè)下標(biāo)前的數(shù)字):返回布爾值,表示參數(shù)字符串是否在原字符串的尾部。
4:repeat方法返回一個(gè)新字符串,表示將原字符串重復(fù)n次
5:padStart()用于頭部補(bǔ)全,padEnd()用于尾部補(bǔ)全;這兩個(gè)方法在

第六章數(shù)值的擴(kuò)展

1:Number.isFinite()用來檢查一個(gè)數(shù)值是否為有限的(finite)。

Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false

2:Number.isNaN()用來檢查一個(gè)值是否為NaN。

Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true'/0) // true
Number.isNaN('true'/'true') // true
補(bǔ)充:Number.isInteger();Number.isInteger()用來判斷一個(gè)值是否為整數(shù)。需要注意的是,在 JavaScript 內(nèi)部,整數(shù)和浮點(diǎn)數(shù)是同樣的儲存方法,所以3和3.0被視為同一個(gè)值。

對比:

它們與傳統(tǒng)的全局方法isFinite()和isNaN()的區(qū)別在于,傳統(tǒng)方法先調(diào)用Number()將非數(shù)值的值轉(zhuǎn)為數(shù)值,再進(jìn)行判斷,而這兩個(gè)新方法只對數(shù)值有效,Number.isFinite()對于非數(shù)值一律返回false, Number.isNaN()只有對于NaN才返回true,非NaN一律返回false。

isFinite(25) // true
isFinite("25") // true
Number.isFinite(25) // true
Number.isFinite("25") // false

isNaN(NaN) // true
isNaN("NaN") // true
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
Number.isNaN(1) // false

3:ES6 將全局方法parseInt()和parseFloat(),移植到Number對象上面,行為完全保持不變。

// ES5的寫法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45

// ES6的寫法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

4:Number.EPSILON;ES6在Number對象上面,新增一個(gè)極小的常量Number.EPSILON。

5.551115123125783e-17 < Number.EPSILON  但是如果這個(gè)誤差能夠小于Number.EPSILON,我們就可以認(rèn)為得到了正確結(jié)果。

5:Math方法的擴(kuò)展;Math.trunc方法用于去除一個(gè)數(shù)的小數(shù)部分,返回整數(shù)部分。

Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0
對于非數(shù)值,Math.trunc內(nèi)部使用Number方法將其先轉(zhuǎn)為數(shù)值。
對于空值和無法截取整數(shù)的值,返回NaN。
Math.trunc('123.456')
Math.trunc(NaN);      // NaN
Math.trunc('foo');    // NaN
Math.trunc();         // NaN

函數(shù)擴(kuò)展

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

ES6之前的默認(rèn)值顯示方法
function log(x, y) {
  y = y || 'World';
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World
上面代碼檢查函數(shù)log的參數(shù)y有沒有賦值,如果沒有,則指定默認(rèn)值為World。這種寫法的缺點(diǎn)在于,如果參數(shù)y賦值了,但是對應(yīng)的布爾值為false,
則該賦值不起作用。就像上面代碼的最后一行,參數(shù)y等于空字符,結(jié)果被改為默認(rèn)值。
為了避免這個(gè)問題,通常需要先判斷一下參數(shù)y是否被賦值,如果沒有,再等于默認(rèn)值。
if (typeof y === 'undefined') {
  y = 'World';
}
ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面。
function log(x, y = 'World') {
  console.log(x, y);
}

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

注意;

參數(shù)變量是默認(rèn)聲明的,所以不能用let或const再次聲明。
function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

與結(jié)構(gòu)結(jié)合的用法;

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

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
基礎(chǔ)用法和注意事項(xiàng):上面代碼只使用了對象的解構(gòu)賦值默認(rèn)值,沒有使用函數(shù)參數(shù)的默認(rèn)值。
只有當(dāng)函數(shù)foo的參數(shù)是一個(gè)對象時(shí),變量x和y才會通過解構(gòu)賦值生成。如果函數(shù)foo調(diào)用時(shí)沒提供參數(shù)
  ,變量x和y就不會生成,從而報(bào)錯(cuò)。通過提供函數(shù)參數(shù)的默認(rèn)值,就可以避免這種情況。


function fetch(url, { body = '', method = 'GET', headers = {} }) {
  console.log(method);
}

fetch('http://example.com', {})
// "GET"

fetch('http://example.com')
// 報(bào)錯(cuò)

// 寫法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

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

上面兩種寫法都對函數(shù)的參數(shù)設(shè)定了默認(rèn)值,區(qū)別是寫法一函數(shù)參數(shù)的默認(rèn)值是空對象,但是設(shè)置了對象解構(gòu)賦值的默認(rèn)值;寫法二函數(shù)參數(shù)的默認(rèn)值是一個(gè)有具體屬性的對象,但是沒有設(shè)置對象解構(gòu)賦值的默認(rèn)值。

// 函數(shù)沒有參數(shù)的情況
m1() // [0, 0]
m2() // [0, 0]

// x 和 y 都有值的情況
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

// x 有值,y 無值的情況
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

// x 和 y 都無值的情況
m1({}) // [0, 0];
m2({}) // [undefined, undefined]

m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

參數(shù)默認(rèn)值的位置

// 例一
function f(x = 1, y) {
  return [x, y];
}

f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 報(bào)錯(cuò)
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報(bào)錯(cuò)
f(1, undefined, 2) // [1, 5, 2]

rest 參數(shù)

ES6 引入 rest 參數(shù)(形式為...變量名),用于獲取函數(shù)的多余參數(shù),
這樣就不需要使用arguments對象了。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
//正常將argument變?yōu)閿?shù)組的辦法就是使用var arr = Array.prototype.slice.apply(arguments);
或者Array.prototype.slice.call(arguments).sort();

注意:

1 注意,rest 參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù)),否則會報(bào)錯(cuò)
// 報(bào)錯(cuò)
function f(a, ...b, c) {
  // ...
}//就會報(bào)錯(cuò)
   2: ES2016 做了一點(diǎn)修改,規(guī)定只要函數(shù)參數(shù)使用了默認(rèn)值、解構(gòu)賦值、或者擴(kuò)展運(yùn)算符,那么函數(shù)內(nèi)部就不能顯式設(shè)定為嚴(yán)格模式,否則會報(bào)錯(cuò)。
3:這樣規(guī)定的原因是,函數(shù)內(nèi)部的嚴(yán)格模式,同時(shí)適用于函數(shù)體和函數(shù)參數(shù)。但是,函數(shù)執(zhí)行的時(shí)候,先執(zhí)行函數(shù)參數(shù),然后再執(zhí)行函數(shù)體。
這樣就有一個(gè)不合理的地方,只有從函數(shù)體之中,才能知道參數(shù)是否應(yīng)該以嚴(yán)格模式執(zhí)行,但是參數(shù)卻應(yīng)該先于函數(shù)體執(zhí)行。
// 報(bào)錯(cuò)
function doSomething(value = 070) {
  'use strict';
  return value;
}
上面代碼中,參數(shù)value的默認(rèn)值是八進(jìn)制數(shù)070,但是嚴(yán)格模式下不能用前綴0表示八進(jìn)制,
所以應(yīng)該報(bào)錯(cuò)。但是實(shí)際上,JavaScript 引擎會先成功執(zhí)行value = 070,然后進(jìn)入函數(shù)體內(nèi)部,發(fā)現(xiàn)需要用嚴(yán)格模式執(zhí)行,這時(shí)才會報(bào)錯(cuò)。

雖然可以先解析函數(shù)體代碼,再執(zhí)行參數(shù)代碼,但是這樣無疑就增加了復(fù)雜性。
因此,標(biāo)準(zhǔn)索性禁止了這種用法,只要參數(shù)使用了默認(rèn)值、解構(gòu)賦值、或者擴(kuò)展運(yùn)算符,就不能顯式指定嚴(yán)格模式。
兩種方法可以規(guī)避這種限制。第一種是設(shè)定全局性的嚴(yán)格模式,這是合法的。第二種是把函數(shù)包在一個(gè)無參數(shù)的立即執(zhí)行函數(shù)里面。

2:箭頭函數(shù)

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

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

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

用法1:與結(jié)構(gòu)的配合

const full = ({ first, last }) => first + ' ' + last;

// 等同于
function full(person) {
  return person.first + ' ' + person.last;
}

用法2:簡化回調(diào)函數(shù)

[1,2,3].map(function (x) {
  return x * x;
});

// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);

關(guān)于箭頭函數(shù)中this指向問題的變化

var x=11;
var obj={
  x:22,
  say:function(){
    console.log(this);
    obj2={
        x:33,
        say:function(){
            console.log(this);
        }
    }
    obj2.say()
  }
}
obj.say();//22

數(shù)組的擴(kuò)展屬性;

ES5中數(shù)組方法復(fù)習(xí):

image.png

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

ES5中使用toString的方法
console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

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

function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

var numbers = [4, 38];
add(...numbers) // 42

擴(kuò)展運(yùn)算符與正常的函數(shù)參數(shù)可以結(jié)合使用,非常靈活。
function f(v, w, x, y, z) { }
var args = [0, 1];
f(-1, ...args, 2, ...[3]);

2:替代數(shù)組的 apply 方法 由于擴(kuò)展運(yùn)算符可以展開數(shù)組,所以不再需要apply方法,將數(shù)組轉(zhuǎn)為函數(shù)的參數(shù)了。

// ES5 的寫法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f.apply(null, args);

// ES6的寫法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f(...args);
下面是擴(kuò)展運(yùn)算符取代apply方法的一個(gè)實(shí)際的例子,應(yīng)用Math.max方法,簡化求出一個(gè)數(shù)組最大元素的寫法。
// ES5 的寫法
Math.max.apply(null, [14, 3, 77])

// ES6 的寫法
Math.max(...[14, 3, 77])

// 等同于
Math.max(14, 3, 77);

3:另一個(gè)例子是通過push函數(shù),將一個(gè)數(shù)組添加到另一個(gè)數(shù)組的尾部。

// ES5的 寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);

// ES6 的寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
上面代碼的 ES5 寫法中,push方法的參數(shù)不能是數(shù)組,所以只好通過apply方法變通使用push方法。有了擴(kuò)展運(yùn)算符,就可以直接將數(shù)組傳入push方法。

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

1:合并數(shù)組

// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]

var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];

// ES5的合并數(shù)組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6的合并數(shù)組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

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

// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list

3:擴(kuò)展運(yùn)算符還可以將字符串轉(zhuǎn)為真正的數(shù)組。

[...'hello']
// [ "h", "e", "l", "l", "o" ]

7:數(shù)組實(shí)例的 entries(),keys() 和 values()

ES6 提供三個(gè)新的方法——entries(),keys()和values()——用于遍歷數(shù)組。
它們都返回一個(gè)遍歷器對象(詳見《Iterator》一章),可以用for...of循環(huán)進(jìn)行遍歷,
唯一的區(qū)別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。
`for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
  console.log(elem);
  }
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"`
如果不使用for...of循環(huán),可以手動(dòng)調(diào)用遍歷器對象的next方法,進(jìn)行遍歷。
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
ES5中的迭代的方法.png

對象中新增的方法;

var obj={ fun:function(){"函數(shù)內(nèi)容"} } 原來寫法,在簡寫對應(yīng)的屬性的時(shí)候,需要名字相同,和定義的對象的屬性名字相同,
const obj={ fun(){"函數(shù)的內(nèi)容"} } ES6中函數(shù)的寫法
var target={a:1}; var source1={b:2}; var source2={c:3}; Object.assign(target,source1,source2) 這個(gè)時(shí)候target的值就是target={a:1,b:2,c:3} Object.assign屬于淺拷貝;只是拷貝的指針,如果源對象某個(gè)屬性的值是對象,那么目標(biāo)對象拷貝得到的是這個(gè)對象的引用。

:Symbol

數(shù)組的擴(kuò)展

擴(kuò)展運(yùn)算符(...);就是這三個(gè)點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 三,字符串?dāng)U展 3.1 Unicode表示法 ES6 做出了改進(jìn),只要將碼點(diǎn)放入大括號,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,561評論 0 8
  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,442評論 0 1
  • 1.函數(shù)參數(shù)的默認(rèn)值 (1).基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。
    趙然228閱讀 704評論 0 0
  • 昨晚好像夢到了一篇很深?yuàn)W的文章,具體內(nèi)容不記得了。
    duoduo_four閱讀 117評論 0 0
  • 家和薩提亞領(lǐng)導(dǎo)力:自我關(guān)愛分享 第49天簽到(2016.11.9) 每天堅(jiān)持一件事:冥想三十分鐘 我是個(gè)比較獨(dú)立...
    孫麗霞閱讀 141評論 0 0