數組
同一段代碼爲了可以在各類環境, 都能取到頂層對象, 如今通常是使用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();
1.let 不能預解析 ( 只要塊級做用域內存在let命令,它所聲明的變量就「綁定」(binding)這個區域,再也不受外部的影響。)函數
2.同做用域內 let聲明的變量 不容許重複ui
3.有塊級做用域{ ... } 內部定義變量 外部不能訪問this
4.只能先聲明在使用spa
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" //若是沒法編譯將會報錯
模板字符串
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 參數(... 剩餘參數)
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 } };
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 //調用一次計算一次
// 默認參數最好定義再尾部,由於使用形參默認參數,那麼那個位置的形參必傳 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
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"}
//定義簡單函數 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