Es6 筆記

頂層對象

在瀏覽器環境指的是window對象, 瀏覽器和 Web Worker 裏面,self也指向頂層對象, 可是 Node 沒有self。 Node 裏面,頂層對象是global,但其餘環境都不支持。數組

取頂層對象

同一段代碼爲了可以在各類環境, 都能取到頂層對象, 如今通常是使用this變量,可是有侷限性瀏覽器

全局環境中,this會返回頂層對象。 可是,Node 模塊和 ES6 模塊中,this返回的是當前模塊,嚴格模式下,這時this會返回undefined。 無論是嚴格模式,仍是普通模式,new Function('return this')(),老是會返回全局對象。安全

可是,若是瀏覽器用了 CSP(Content Security Policy,內容安全政策),那麼eval、new Function這些方法均可能沒法使用。 在全部狀況下,都取到頂層對象。下面是兩種勉強能夠使用的方法。數據結構

// 方法一
(typeof window !== 'undefined'
   ? window
   : (typeof process === 'object' &&
     typeof require === 'function' &&
     typeof global === 'object')
    ? global
    : this);
​
// 方法二
var getGlobal = function () {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

 

墊片庫system.global模擬了這個提案,能夠在全部環境拿到global。app

// CommonJS 的寫法
require('system.global/shim')();
​
// ES6 模塊的寫法
import shim from 'system.global/shim'; shim();
上面代碼能夠保證各類環境裏面,global對象都是存在的。
​
// CommonJS 的寫法
var global = require('system.global')();
​
// ES6 模塊的寫法
import getGlobal from 'system.global';
const global = getGlobal();

 

let

1.let 不能預解析 ( 只要塊級做用域內存在let命令,它所聲明的變量就「綁定」(binding)這個區域,再也不受外部的影響。)函數

2.同做用域內 let聲明的變量 不容許重複ui

3.有塊級做用域{ ... } 內部定義變量 外部不能訪問this

4.只能先聲明在使用spa

 

const

let 4條規則都適用prototype

聲明的常量不容許從新賦值 

2.常量必須初始化

const a; //報錯 

const a ={ } 

3.能夠改變引用類

const實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址不得改動。 const只能保證這個指針是固定的,至於它指向的數據結構是否是可變的,就徹底不能控制了。

數組解構賦值

let [a, b, c] = [1, 2, 3];
//上面代碼表示,能夠從數組中提取值,按照對應位置,對變量賦值。
​
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
​
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
​
let [x, , y] = [1, 2, 3];
x // 1
y // 3
​
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
​
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
​
let [x = 1] = [undefined];
x // 1
​
let [x = 1] = [null];
x // null

上面代碼中,若是一個數組成員是null,默認值就不會生效,由於null不嚴格等於undefined。

對象解構賦值

let {foo:aa,bar="hi"} = { foo:"123"}
console.log(foo)//報錯
console.log(aa)123
console.log(bar )//hi

foo是匹配的模式,baz纔是變量。真正被賦值的是變量baz,而不是模式foo

若是p也要做爲變量賦值,能夠寫成下面這樣。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};
​
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

 

字符串擴展

查找字符
let str = 'Hello Brother!';

//includes 是否包含參數字符串
str.includes('Br'); //true

//startsWith  開頭是否存在參數字符串
str.startsWith('Hello') //true

//endsWith 結尾是否存在參數字符串
str.endsWith('er!')//true
重複字符
re.repeat(2); //"Hello Brother!Hello Brother!"

re.repeat(-2); // Invalid count value
re.repeat(Infinity); // Invalid count value
//小數會取整 
re.repeat(1.9) // "Hello Brother!"
re.repeat(-0.9) // ""
補全字符
//補全開頭 padStart 補齊尾部 padEnd
let pd = 'Brother!'; 
pd.padStart(14,'Hello '); //"Hello Brother!"
//第一個參數爲補齊的最大長度(整串字符) 第二個參數爲補齊缺省的字符串

//若是原始字符長度大於等於最大長度,返回原字符串
pd.padStart(7,'Hello ')// 'Brother!'
pd.padStart(8,'Hello ')// 'Brother!'

//若是最大長度小於補齊長度,則去除超出部分
pd.padStart(9,'Aay ')//'ABrother!'

//若是缺省第二個參數則 默認使用空格補齊
pd.padStart(9)//' Brother!'
轉義符
//以 x 開頭,會被當作 16 進制

 `\x23` // #

 //以 u 開頭,會被當作 unicode  字符
 `\u004F` //"O"

//若是沒法編譯將會報錯
ES2018 放鬆了對`標籤模板`裏面的字符串轉義的限制,沒法轉義的返回`undefined`;

模板字符串

let obj={
  name:"ww",
  age:"18"
   }
​
let  tag = "<div><span>"+obj.name +"</span></div>";
let  tpl= `<div><span>${obj.name}</span></div>` 
// 反引號 左上角 ESC鍵下方
​
let  fn= function (info){
    return info
    }
let  tpl= `<div><span>${obj.name}</span></div><div><span>${obj.age}</span></div>
    <div>
    <span>${fn("你好")}</span>
    <span>${1+1}</span>
    </div>

 

函數參數解構賦值

一,

function fn(param="ss",age=15){ console.log(param - age); } fn();//ss - 15 fn("nihao",18)//nihao - 18

 

二,

 function fn({name ="ls", age}={}) { console.log(name - age);

} fn();//ls - undefind

fn("nihao",18)//nihao - 18

 

三, rest 參數(... 剩餘參數)

> 使用形式 `...arg` 實數以數組的形勢賦給變量
> reset 參數後不能再有形參,不然報錯
function fn (a,...arg){
    return arg;
}
fn(0,2,3,4,5)//[2,3,4,5]

function foo (a,...arg,b){
    return arg;
}
//ught SyntaxError: Rest parameter must be last formal parameter
只要函數參數使用了默認值、解構賦值、或者擴展運算符,那麼函數內部就不能顯式設定爲嚴格模式,不然會報錯。
/ 報錯
function f(a, b = a) {
  'use strict';
  // code
}

// 報錯
const foo = function ({a, b}) {
  'use strict';
  // code
};

// 報錯
const fn = (...a) => {
  'use strict';
  // code
};

const obj = {
  // 報錯
  fn({a, b}) {
    'use strict';
    // code
  }
};

 

 

函數擴展

形參指定默認值
> 形參 不能再次使用 let 和 const 聲明
> 形參不能重名
> 函數 length 不包含設置默認值和後面的形參個數
> 使用 `...arg` 中的參數 length 也不包含
const fn = (x, y = 'Owen') =>( console.log(x,y));
fn(1) // 1 "Owen"

//默認參數 惰性求值
let x = 99;
function foo(y = x + 1) {
  console.log(y);
}
foo() // 100
x = 100;
foo() // 101
//調用一次計算一次
事實上 每次調用函數,若是不傳遞參數, 形參默認傳遞 `undefined`
 // 默認參數最好定義再尾部,由於使用形參默認參數,那麼那個位置的形參必傳

function f(x, y = 5, z, ...arg) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報錯
f(1, undefined, 2) // [1, 5, 2]

//length 不包含設置默認值 和後面的形參 的個數,
f().length // 1
做用域
> 函數中的 變量沒法訪問  默認值
> 函數中的形參名不能和默認名同樣
//函數變量沒法訪問默認值
function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // ReferenceError: x is not defined

//函數中的形參名不能和默認名同樣
//參數x = x造成一個單獨做用域。實際執行的是let x = x,因爲暫時性死區的緣由,這行代碼會報錯
function f(x = x) {
  console.log(x);
}
f()//  x is not defined

var x = 1;
function foo(x, y = function() { x = 2; }) {
  var x = 3;
  y();
  console.log(x);
}

foo() // 3
x // 1
因爲 var 聲明的 x 和函數形參 x 再也不同一個做用域 , 所以調用 y() x值不變;
若是 去掉 var , 那麼 x 就指向 形參 x ,調用 y() x = 2。
 
箭頭函數
>使用 ` () => ` 定義函數
注意:
- this 指向函數定義時所綁定的普通函數,不會被(bind,call,apply)更改,也不會被調用時的上下文改變。
let fn = () =>console.log(this);
let obj = {name:"Owen"};

fn.call(obj) //window

fn.bind(obj)
fn() //window

fn.apply(obj)  //window
 
 
 //能夠經過改變宿主環境來改變 this 指向
 
 function foo (){
 
return () =>{ 
  console.log(this);

  return ()=> {console.log(this)};
  }
}
foo.call(obj)() //{name: "Owen"}
foo.call(obj)()() //{name: "Owen"} {name: "Owen"}
- 外層沒有普通函數 ,嚴格模式和非嚴格模式下它的this都會指向window(全局對象)。

- 不能夠看成構造函數,也就是說,不能夠使用new命令,沒有`prototype`屬性,不支持`new.target`,不然會拋出一個錯誤。
- 參數和箭頭之間不能換行
- 不能夠使用arguments對象,該對象在函數體內不存在。若是要用,能夠用 rest 參數代替。

- 不能夠使用yield命令,所以箭頭函數不能用做 Generator 函數。
//定義簡單函數
let fn = () => 'Owen';
fn()// 'Owen'

let foo = r => r;
foo('Owen') // 'Owen'

let f = (num1,num2) => num1 + num2;
f(1,2)//3

//若是返回一個對象須要小括號包裹,f不然會報錯
let f = (name,age) => ({name,age});
f('Owen',18)//{name: "Owen", age: 18}


//若是代碼部分大於一條語句,那麼須要 大括號包裹,使用return 返回值

let fn1 = r => {
    let a = 1;
    console.log(a);
    return r + a;

}

不推薦使用場景

var obj = {
  gender:"man",
  getSex: () =>  {console.log(this.gender)}
}
obj.getSex() //undefined
//this -> global
相關文章
相關標籤/搜索