《ECMAScript6 入門》阮一峰 讀書(shū)筆記
- let和const
- let
- 聲明的變量?jī)H在
塊級(jí)作用域內(nèi)有效,var聲明的變量在全局范圍內(nèi)有效 - let
不存在變量提升,所以變量一定要先聲明后使用,換言之,var是有變量提升的(也就是可以先使用后聲明,聲明在編譯的時(shí)候會(huì)被提升到最開(kāi)頭) - 暫時(shí)性死區(qū),也就是使用let命令聲明變量之前,該變量都是不可用的,也就是第二條。暫時(shí)性死區(qū)的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。
-
不允許重復(fù)聲明,也就是在同一個(gè)作用域內(nèi)不能重復(fù)聲明同一個(gè)變量。
- 聲明的變量?jī)H在
- let
- 塊級(jí)作用域
- 不合理場(chǎng)景一
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = "hello world";
}
}
f(); // undefined,因?yàn)樽兞刻嵘齼?nèi)層的tmp變量覆蓋了外層的tmp變量????
??有疑惑,并不理解。。。
2. 不合理場(chǎng)景二,變量泄漏為全局變量(比如for循環(huán)里面的計(jì)數(shù)變量,如果用var來(lái)聲明,其實(shí)在全局也是可以訪問(wèn)到的)
3. 塊級(jí)作用域與函數(shù)聲明
- es5規(guī)定函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級(jí)作用域中聲明,比如在if語(yǔ)句里面就不能聲明一個(gè)變量,但實(shí)際上,瀏覽器是支持的
- es6明確允許在塊級(jí)作用域之中聲明函數(shù)。比較特別的是,塊級(jí)作用域之中,函數(shù)聲明語(yǔ)句的行為類似于`let`,在`塊級(jí)作用域之外是不可以引用的`
```
eg:
function f(){console.log("I am outside");}
(function (){
if(false){
function f(){console.log("I am inside");}
}
f()
}())
*===================================================*
es5中實(shí)際上是如此運(yùn)行的:
function f(){console.log("I am outside");}
(function (){
function f(){console.log("I am inside");}//變量提升
if(false){}
f()
}())
*===================================================*
es6中實(shí)際運(yùn)行代碼如下:
function f(){console.log("I am outside");}
(function(){
f()//在塊級(jí)內(nèi)聲明的那個(gè)inside的f函數(shù)對(duì)作用域之外沒(méi)有影響,所以相當(dāng)于不存在,
調(diào)用的是外面的函數(shù),因?yàn)樽饔糜虿檎叶际窍蛲獠檎覈}!
}())
```
- ??為了兼容的問(wèn)題,es6允許瀏覽器可以不遵守上面的規(guī)定,也就是可以有自己的行為方式,具體表現(xiàn)為(也就是實(shí)際上定義函數(shù)的時(shí)候遵守的規(guī)則,只針對(duì)支持es6的瀏覽器有效):
- 允許在塊級(jí)作用域內(nèi)聲明函數(shù)
- 函數(shù)聲明類似于var,即會(huì)提升到全局作用域或函數(shù)作用域的頭部
- 同時(shí),函數(shù)聲明還會(huì)提升到所在的塊級(jí)作用域的頭部
- 在塊級(jí)作用域內(nèi)聲明函數(shù)的時(shí)候,塊級(jí)作用域一定要加大括號(hào),比如在if里面聲明一個(gè)函數(shù),if后面一定要有大括號(hào)
const聲明一個(gè)只讀的常量,聲明之后,值不能改變。所以,
聲明的時(shí)候就要賦值,其他的和let一樣。有一個(gè)注意的點(diǎn)是,比如const了一個(gè)數(shù)組,這個(gè)數(shù)組本身是不能給賦值的,但是這個(gè)數(shù)組是可以push一個(gè)變量的!-
頂層對(duì)象的屬性
- 全局變量在es5中是頂層對(duì)象的屬性,es6規(guī)定,var和function命令聲明的全局變量依然是頂層對(duì)象的屬性,但是let、const、class命令聲明的全局變量不屬于頂層對(duì)象的屬性。
-
頂層對(duì)象
混亂的頂層對(duì)象
- 瀏覽器里面,頂層對(duì)象是window,但Node和Web Worker沒(méi)有
window - 瀏覽器和Web Worker里面,
self指向頂層對(duì)象,但是Node 沒(méi)有self - Node里面,頂層對(duì)象是
global,但其他環(huán)境都不支持
為了在不同的環(huán)境中都能去到頂層對(duì)象,一般使用
this變量,但是有局限性
- 全局環(huán)境中,this會(huì)返回頂層對(duì)象,但是,Node模塊和ES模塊中,this返回的是當(dāng)前模塊
- 函數(shù)里面的this,如果函數(shù)不是作為對(duì)象的方法運(yùn)行,而是單純作為函數(shù)運(yùn)行,this會(huì)指向頂層對(duì)象,但是,嚴(yán)格模式下,this會(huì)返回undefined。
- 不管是嚴(yán)格模式,還是普通模式,new Function('return this')(),總是會(huì)返回全局對(duì)象,但是,如果瀏覽器用了CSP(Content Security Policy,內(nèi)容安全政策),那么eval、new Function這些方法都可能無(wú)法使用。
綜上所述,兩種解決辦法: 方法一: (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('unalble to locate global object'); } - 瀏覽器里面,頂層對(duì)象是window,但Node和Web Worker沒(méi)有
- 變量的解構(gòu)賦值
es6允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行復(fù)賦值,成為解構(gòu)賦值。
- 數(shù)組的解構(gòu)賦值
- “模式匹配”,也就是只要等號(hào)兩邊的模式相同,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值。
let [foo, , baz] = [1,2,[d]];//foo就是1,baz就是[d]這個(gè)數(shù)組 let [head, ...tail] = [1,2,3,4];//head就是1,tail就是[2,3,4] let [x,y,...z] = ['a'];//x就是“ a”,y是undefined(解構(gòu)不成功的話,變量的值就等于undefined),z是[],為啥z是[](????為啥??),因?yàn)?..."是將右邊剩余的值用數(shù)組的形式賦給左邊的值,所以z就得到了一個(gè)空的數(shù)組 let [a,[b],d] = [1,[2,3],4];//a是1,b是2(完全對(duì)應(yīng)過(guò)去,如果b不加外面的中括號(hào),那b就是[2,3]),d是4- 等號(hào)的右邊如果不是可遍歷的結(jié)構(gòu),會(huì)報(bào)錯(cuò)的
- 默認(rèn)值,允許指定默認(rèn)值,數(shù)組成員嚴(yán)格等于
undefined才會(huì)使默認(rèn)值生效
var [foo = true] = [];//foo是true - 對(duì)象的解構(gòu)賦值
- 變量必須與對(duì)象的屬性同名,才能取到正確的值,如果沒(méi)有對(duì)應(yīng)的同名屬性,取不到值的話,值為undefined
誰(shuí)后面有“:”,誰(shuí)就是模式,并不是變量var {bar, foo} = {foo:'aaa',bar:'bbb'}//foo的值是'aaa',bar的值是'bbb' //注意真正被賦值的是誰(shuí) var {foo:baz} = {foo:"aaa",bar:"bbb"}//baz的值是"aaa"而不是foo的值是“aaa”,foo是個(gè)“模式”- 這種寫法,變量的聲明和賦值是一體的,像下面,如果用let或const是不行的,但是用var是可以的。
let foo; let {foo} = {foo:1}//這樣會(huì)報(bào)錯(cuò)滴,因?yàn)閒oo在上面已經(jīng)聲明過(guò)了,所以不能再次聲明 //如果非常想用let并且分開(kāi)的話,可以用下面的方式 let foo; ({foo} = {foo:1})//這樣不會(huì)報(bào)錯(cuò),外面必須用()包起來(lái),因?yàn)榻馕銎鲿?huì)將起首的大括號(hào)理解成一個(gè)代碼塊而不是賦值語(yǔ)句。- 默認(rèn)值,默認(rèn)值生效的條件是,對(duì)象的屬性值嚴(yán)格等于
undefined,同樣,如果解構(gòu)失?。ㄒ簿褪菍?duì)應(yīng)右邊沒(méi)有相同變量名的屬性),那么變量的值等于undefined - 實(shí)際應(yīng)用場(chǎng)景:可以很方便的把一些對(duì)象的屬性值賦值給其他的變量,不用一個(gè)一個(gè)的寫
var { log,sin,cos } = Math - 字符串的解構(gòu)賦值
var [a,b,c] = 'hello'; //a==>h,b==>e,c==>l var {length:len} = 'hello'; //len的值是5,有點(diǎn)懵???(類似數(shù)組的對(duì)象都有一個(gè)length屬性,所以就5了???) - 數(shù)值和布爾值的解構(gòu)賦值
解構(gòu)賦值時(shí),如果等號(hào)右邊是數(shù)值或布爾值,則會(huì)先轉(zhuǎn)為對(duì)象,(undefined和null無(wú)法轉(zhuǎn)為對(duì)象,所以對(duì)他們解構(gòu)賦值會(huì)出錯(cuò))
- 函數(shù)形式參數(shù)的解構(gòu)賦值
- 變量的解構(gòu)賦值的用途
- 交換變量的值
[x,y] = [y,x]//數(shù)組的解構(gòu)是嚴(yán)格按照順序的- 從函數(shù)返回多個(gè)值:函數(shù)一次只能返回一個(gè)值,如果要返回多個(gè)值,只能將她們放在數(shù)組或?qū)ο罄锓祷?,有了解?gòu)賦值,可以很方便的取出這些值
function example(){ return [1,2,3] } var [a,b,c] = example()//這樣就賦值了,多方便??- 函數(shù)參數(shù)的定義
function f([x,y,z]){....} f([1,2,3])- 提取JSON數(shù)據(jù)
var jsonData = { id:42, status:"ok", data:[22,3] } let { id, status, data:number } = jsonData;- 遍歷Map結(jié)構(gòu)
- 輸入模塊的指定方法
- 字符串的擴(kuò)展(這節(jié)好深?yuàn)W,先放下??
- 字符的Unicode表示法,
用\uxxxx形式來(lái)表示一個(gè)字符,其中xxxx表示字符的碼點(diǎn)
- 字符的Unicode表示法,
- 正則的擴(kuò)展
- 數(shù)值的擴(kuò)展
-
數(shù)組的拓展
-
Array.from(),用于將兩類對(duì)象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對(duì)象和可遍歷的對(duì)象。
let arrayLike = { '0':'a', '1':'b', '2':'c', length:3 };//類似數(shù)組的對(duì)象 let arr = Array.from(arrayLike);//['a','b','c']- 實(shí)際應(yīng)用中,常見(jiàn)的類似數(shù)組的對(duì)象是DOM操作返回的NodeList集合,以及函數(shù)內(nèi)部的arguments對(duì)象。(所謂類似數(shù)組的對(duì)象本質(zhì)特征只有一點(diǎn),即必須有l(wèi)ength屬性,任何有l(wèi)ength屬性的對(duì)象,都可以通過(guò)Array.from方法轉(zhuǎn)為數(shù)組)
-
Array.of(),用于將一組值轉(zhuǎn)換為數(shù)組,沒(méi)有參數(shù)的時(shí)候返回一個(gè)空數(shù)組
Array.of(1,2,4)//【1,2,4】-
copyWithin(),在當(dāng)前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置(會(huì)覆蓋原有成員),然后返回當(dāng)前數(shù)組,也就是會(huì)修改當(dāng)前數(shù)組。
Array.prototype.copyWith(target,start,end)//接受三個(gè)參數(shù),其中target是必需的,target代表從該位置開(kāi)始替換數(shù)據(jù),start表示從該位置開(kāi)始讀取數(shù)據(jù),默認(rèn)為0,負(fù)數(shù)則表示倒數(shù),end表示到該位置前停止讀取數(shù)據(jù),默認(rèn)等于數(shù)組長(zhǎng)度,負(fù)數(shù)則表示倒數(shù) [1,2,3,4].copyWithin(0,3)//[4,4,4,4],從0開(kāi)始用3位置上(也就是4這個(gè)數(shù)字到末尾的0來(lái)替換0- 數(shù)組實(shí)例的find()和findIndex()
find方法用于找出第一個(gè)符合條件的數(shù)組成員,參數(shù)是一個(gè)回調(diào)函數(shù),所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù),直到找出第一個(gè)返回值為true的成員,然后返回該成員。如果沒(méi)有符合條件的成員,則返回undefined。回調(diào)函數(shù)可以接受三個(gè)參數(shù),
依次為當(dāng)前的值,當(dāng)前的位置,原數(shù)組。[1,2,-5].find(n => n < 0)//返回第一個(gè)小于0的成員findIndex方法返回第一個(gè)符合條件的數(shù)組成員的位置,如果都不符合條件,則返回-1,回調(diào)函數(shù)參數(shù)和find方法一致。
find和findIndex方法都可以接受除回調(diào)函數(shù)以外的第二個(gè)參數(shù),用來(lái)綁定回調(diào)函數(shù)的this對(duì)象。- 數(shù)組實(shí)例的fill()
fill方法使用給定值,填充一個(gè)數(shù)組。如果數(shù)組中已有元素,則會(huì)全部被抹去。參數(shù)和copyWithin函數(shù)的參數(shù)是一致的。
['a','b','c'].fill(7)//返回一個(gè)[7,7,7]- 數(shù)組實(shí)例的entries(),keys()和values()----遍歷數(shù)組的函數(shù)
------對(duì)鍵名的遍歷 for(let index of ['a','b'].keys()){ console.log(index); }//結(jié)果如下 //0 //1 ------對(duì)鍵值的遍歷 for(let elem of ['a','b'].values()){ console.log(elem); }//結(jié)果如下 //'a' //'b' ------對(duì)鍵值對(duì)的遍歷 for(let [index,elem] of ['a','b'].entries()){ console.log(index,elem); }//結(jié)果如下 //0 "a" //1 "b"- 數(shù)組實(shí)例的includes()
Array.prototype.includes方法返回一個(gè)布爾值,表示某個(gè)數(shù)組是否包含給定的值,與字符串的includes方法類似。
[1,2,3].includes(2)//包含2,所以返回trueMap結(jié)構(gòu)的has方法,是用來(lái)查找鍵名的 Set結(jié)構(gòu)的has方法,是用來(lái)查找值的- 數(shù)組的空位
數(shù)組的空位是指,數(shù)組的某一個(gè)位置沒(méi)有任何值,es6明確的將空位轉(zhuǎn)為undefined。以上數(shù)組的擴(kuò)展方法都會(huì)把空位考慮進(jìn)去,而不是忽略。
-
-
函數(shù)的擴(kuò)展
- 函數(shù)參數(shù)的默認(rèn)值
function log(x, y = 'world'){ ...}- 與解構(gòu)賦值默認(rèn)值結(jié)合使用(沒(méi)看懂??
- 參數(shù)默認(rèn)值的位置
非尾部的參數(shù)如果設(shè)置了默認(rèn)值,那么這個(gè)參數(shù)是不能夠省略的!
- 函數(shù)的length屬性
指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒(méi)有指定默認(rèn)值的參數(shù)個(gè)數(shù),也就是說(shuō),指定了默認(rèn)值以后,length屬性將失真。
失真也就是不算它。(function (a,b=2){}).length //1-
作用域---大爺
- 如果參數(shù)默認(rèn)值是一個(gè)變量,則該變量所處的作用域,與其他變量的作用域規(guī)則是一樣的,即先是當(dāng)前函數(shù)的作用域,然后才是全局作用域。
情況一: var x = 1; function f(x, y = x){ 略 } //比如這里,y的默認(rèn)值就是一個(gè)變量x,那么x的值要優(yōu)先取傳進(jìn)來(lái)的x的值,如果沒(méi)有, 才是全局變量中的x。情況二: let x = 1; function f(y=x){ let x = 2; console.log(y); } f()//輸出的是1,因?yàn)榻oy賦值的時(shí)候,x尚未在函數(shù)內(nèi)部生成,故取全局變量中的x給y賦值, 如果此時(shí)全局變量中的x不存在,就會(huì)報(bào)錯(cuò)了。情況三: let foo = "outer"; function bar(func = x=> foo){ let foo = "inner"; console.log(func()); } bar() //當(dāng)函數(shù)的參數(shù)是一個(gè)函數(shù)的時(shí)候,該函數(shù)的作用域是其聲明時(shí)所在的作用域。 ????bar方法的參數(shù)func是一個(gè)匿名函數(shù),具體的意義是傳進(jìn)去x,返回值為foo, 也就是func()的值,匿名函數(shù)聲明的時(shí)候(也就是給func賦值的時(shí)候),bar函數(shù)的作 用域還沒(méi)有形成,所以匿名函數(shù)里面的foo指向外層作用域來(lái)的foo,輸出的是outer ????2.rest參數(shù)
rest參數(shù)形式為"...變量名",用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對(duì)象了,rest參數(shù)搭配的變量是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中。??需要注意的是rest參數(shù)之后不能再有其他參數(shù),也就是這個(gè)參數(shù)只能放在最后面。
function add(...values){ let sum = 0; for(var val of values){ sum+=val; } return sum; } add(2,4,5)//神似python里的參數(shù)??
3.擴(kuò)展運(yùn)算符
擴(kuò)展運(yùn)算符(spread)是三個(gè)點(diǎn)
...,rest參數(shù)的逆運(yùn)算,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。注意,擴(kuò)展運(yùn)算符針對(duì)的是數(shù)組數(shù)組數(shù)組??也就是把一個(gè)數(shù)組相當(dāng)于給拆開(kāi)了。console.log(...[1,2,3]) //1 2 3function push(array, ...items){ array.push(...items); } function add(x, y){ return x + y; } var numbers = [4,3]; add(...numbers)//7替代數(shù)組的apply方法(??總結(jié)一下apply方法,因?yàn)榈弥繿pply究竟是干嘛才知道怎么個(gè)替代法??10.26)
-
擴(kuò)展運(yùn)算符的應(yīng)用:
- 合并數(shù)組
var arr1 = ['a','b']; var arr2 = ['c','d']; var arr = [...arr1,...arr2]- 與解構(gòu)賦值結(jié)合
這里和前面的解構(gòu)賦值很容易混啊?? const [first,...rest]=[1,2,3,4]; first===》1 rest====》2,3,4 //有個(gè)易錯(cuò)點(diǎn),和前面很像,就是i 這個(gè)...變量只能放在最后??- 函數(shù)的返回值,返回多個(gè)值的時(shí)候
- 字符串,可以將字符串轉(zhuǎn)換為真正的數(shù)組
[...'hello'] //['h','e','l','l','o']- 實(shí)現(xiàn)了Iterator接口的對(duì)象,任何Iterator接口的對(duì)象,都可以用擴(kuò)展運(yùn)算符轉(zhuǎn)為真正的數(shù)組。
let arrayLike = { '0':'a', '1':'b', '2':'c', length:3 }; let arr = [...arrayLike]//TypeError //arrayLike是一個(gè)類似數(shù)組的對(duì)象,但是沒(méi)有部署Iterator接口,擴(kuò)展運(yùn)算符就會(huì)報(bào)錯(cuò), 這時(shí),可以改為使用Array.from方法將arrayLike轉(zhuǎn)為真正的數(shù)組。- Map結(jié)構(gòu)和Set結(jié)構(gòu),Generator函數(shù)
擴(kuò)展運(yùn)算符內(nèi)部調(diào)用的是數(shù)據(jù)結(jié)構(gòu)的Iterator接口,因此只要具有Iterator接口的對(duì)象,都可以使用擴(kuò)展運(yùn)算符。
4.嚴(yán)格模式
use strictes6規(guī)定,只要函數(shù)的形參使用了默認(rèn)值、解構(gòu)賦值或者擴(kuò)展運(yùn)算符,那么函數(shù)內(nèi)部就不能顯示的設(shè)定為嚴(yán)格模式。
5.name屬性,函數(shù)的name屬性,返回該函數(shù)的函數(shù)名
6.箭頭函數(shù)
=>- 如果箭頭函數(shù)不需要參數(shù)或者需要多個(gè)參數(shù),就使用一個(gè)圓括號(hào)代表參數(shù)部分。
- 如果箭頭函數(shù)的代碼塊部分多于一條語(yǔ)句,就要使用大括號(hào)將他們括起來(lái),并且使用return語(yǔ)句返回
- 如果要返回一個(gè)對(duì)象,外面要用小括號(hào)包起來(lái),因?yàn)榇罄ㄌ?hào)被解釋為代碼塊,所以必須在對(duì)象外面加上括號(hào)
-
函數(shù)體內(nèi)的this對(duì)象,就是定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象,在箭頭函數(shù)中,this是固定的。因?yàn)榧^函數(shù)沒(méi)有自己的this,他們的this其實(shí)都是外層對(duì)象(也就是函數(shù))的this。所以bind(),call(),apply()這些方法無(wú)法改變this的指向。 - 不可以當(dāng)做構(gòu)造函數(shù),也就是不能用new操作符
- 不可以使用arguments對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在,如果要用,可以用rest參數(shù)代替
- 不可以使用yield命令,因此箭頭函數(shù)不能用做generator函數(shù)
7.綁定this
::es7的一個(gè)題案,如果用的話需要babel轉(zhuǎn)碼器雙冒號(hào)左邊是一個(gè)對(duì)象,右邊是一個(gè)函數(shù),該運(yùn)算符會(huì)自動(dòng)將左邊的對(duì)象,作為上下文環(huán)境(即this對(duì)象)綁定到右邊的函數(shù)上面,如果雙冒號(hào)左邊為空,右邊是一個(gè)對(duì)象的方法,則等于將該方法綁定在該對(duì)象上面。
8.尾調(diào)用優(yōu)化??看不懂??10.27
尾調(diào)用是函數(shù)式編程的一個(gè)重要概念,指的是某個(gè)函數(shù)的最后一步是調(diào)用另一個(gè)函數(shù)
-
對(duì)象的擴(kuò)展
- 屬性的簡(jiǎn)潔表示法
情況一: var foo = 'a'; var baz = {foo}; //以往寫對(duì)象的時(shí)候要屬性名、屬性值成對(duì)出現(xiàn),es6允許在對(duì)象中,只寫屬性名, 不寫屬性值,這時(shí),屬性值等于屬性名所代表的變量。 情況二: var o = { method(){ return "hello";//這不就是之前寫react的用法嘛?? } }; 等同于: var o = { method:function(){ return "hello"; } }; 綜合的例子: var birth = '2000/01/01'; var Person = { name: '張三', //等同于birth: birth birth,//react返回對(duì)象的時(shí)候就是這樣寫的!??!?? // 等同于hello: function ()... hello() { console.log('我的名字是', this.name); } };- 屬性名表達(dá)式??
- Object.js()
比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符:相等運(yùn)算符
==和嚴(yán)格相等運(yùn)算符===,前者會(huì)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。Object.is用來(lái)比較兩個(gè)值是否嚴(yán)格相等,彌補(bǔ)了===的缺點(diǎn)。- Object.assign()
Object.assign()用于對(duì)象的合并,將源對(duì)象的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象。Object.assign(target,source1,source2...) //第一個(gè)參數(shù)是目標(biāo)對(duì)象,也就是最終的,后面都是源對(duì)象。如果只有一個(gè)參數(shù)那就直接返回 //????????如果目標(biāo)對(duì)象與源對(duì)象有同名屬性,或者多個(gè)源對(duì)象有同名屬性,則后面的屬性會(huì) 覆蓋前面的屬性 ??undefined和null不能放在目標(biāo)對(duì)象的位置(放,報(bào)錯(cuò),不放也就是放在別的位置會(huì)被跳過(guò)) ??字符串可以作為源對(duì)象,復(fù)制到目標(biāo)對(duì)象里會(huì)是數(shù)組的形式,布爾值和數(shù)值都不能作為源對(duì)象, 雖然不報(bào)錯(cuò),但是會(huì)跳過(guò)??注意點(diǎn) 1.Object.assign是淺拷貝,如果源對(duì)象某個(gè)屬性的值是對(duì)象,如果源對(duì)象某個(gè)屬性的值是對(duì)象, 那么目標(biāo)對(duì)象拷貝得到的是這個(gè)對(duì)象的引用。 2.Object.assign也可以處理數(shù)組,但是也是將數(shù)組視為對(duì)象。- Object.assign常見(jiàn)用途 - 為對(duì)象添加屬性 - 為對(duì)象添加方法,目標(biāo)對(duì)象就是xxx.prototype,然后源對(duì)象就是用大括號(hào)包裹的函數(shù) - 克隆對(duì)象 - 合并多個(gè)對(duì)象 - 為屬性指定默認(rèn)值(可以將屬性的默認(rèn)值為一個(gè)對(duì)象,用戶輸入的為另一個(gè)對(duì)象,兩個(gè)對(duì)象作為源對(duì)象復(fù)制給目標(biāo)對(duì)象,因?yàn)橛脩糨斎氲姆旁诤竺嫠詴?huì)覆蓋掉默認(rèn)值對(duì)象的值,so~)- 屬性的可枚舉性
對(duì)象的每個(gè)屬性都有一個(gè)描述對(duì)象(Descriptor),用來(lái)控制該屬性的行為。
Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對(duì)象let obj = {foo:123}; Object.getOwnPropertyDescriptor(obj,'foo') //{ // value:123, // writable:true, // enumerable:true,是否可以枚舉 // configurable:true //}- 屬性的遍歷
-
for...in,遍歷對(duì)象自身的和繼承的可枚舉屬性(不包含Symbol屬性) -
Object.keys(obj),返回一個(gè)數(shù)組,包括對(duì)象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。 -
Object.getOwnPropertyNames(obj),返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。 -
Object.getOwnPropertySymbols(obj),返回一個(gè)數(shù)組,包含對(duì)象自身的所有Symbol屬性 -
Reflect.ownKeys(obj),返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可以枚舉。
-