es6學(xué)習(xí)筆記

《ECMAScript6 入門》阮一峰 讀書筆記

  • let和const
    • let
      1. 聲明的變量僅在塊級作用域內(nèi)有效,var聲明的變量在全局范圍內(nèi)有效
      2. let不存在變量提升,所以變量一定要先聲明后使用,換言之,var是有變量提升的(也就是可以先使用后聲明,聲明在編譯的時(shí)候會被提升到最開頭)
      3. 暫時(shí)性死區(qū),也就是使用let命令聲明變量之前,該變量都是不可用的,也就是第二條。暫時(shí)性死區(qū)的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。
      4. 不允許重復(fù)聲明,也就是在同一個(gè)作用域內(nèi)不能重復(fù)聲明同一個(gè)變量。
  • 塊級作用域
    1. 不合理場景一
var tmp = new Date();
function f() {
  console.log(tmp);
  if (false) {
      var tmp = "hello world";
  }
}
f(); // undefined,因?yàn)樽兞刻嵘齼?nèi)層的tmp變量覆蓋了外層的tmp變量????
??有疑惑,并不理解。。。
2. 不合理場景二,變量泄漏為全局變量(比如for循環(huán)里面的計(jì)數(shù)變量,如果用var來聲明,其實(shí)在全局也是可以訪問到的)
3. 塊級作用域與函數(shù)聲明
    - es5規(guī)定函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級作用域中聲明,比如在if語句里面就不能聲明一個(gè)變量,但實(shí)際上,瀏覽器是支持的
    - es6明確允許在塊級作用域之中聲明函數(shù)。比較特別的是,塊級作用域之中,函數(shù)聲明語句的行為類似于`let`,在`塊級作用域之外是不可以引用的`
    
    ```
    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()//在塊級內(nèi)聲明的那個(gè)inside的f函數(shù)對作用域之外沒有影響,所以相當(dāng)于不存在,
    調(diào)用的是外面的函數(shù),因?yàn)樽饔糜虿檎叶际窍蛲獠檎覈}!
    }())
    ```
    
    - ??為了兼容的問題,es6允許瀏覽器可以不遵守上面的規(guī)定,也就是可以有自己的行為方式,具體表現(xiàn)為(也就是實(shí)際上定義函數(shù)的時(shí)候遵守的規(guī)則,只針對支持es6的瀏覽器有效):
        - 允許在塊級作用域內(nèi)聲明函數(shù)
        - 函數(shù)聲明類似于var,即會提升到全局作用域或函數(shù)作用域的頭部
        - 同時(shí),函數(shù)聲明還會提升到所在的塊級作用域的頭部
     - 在塊級作用域內(nèi)聲明函數(shù)的時(shí)候,塊級作用域一定要加大括號,比如在if里面聲明一個(gè)函數(shù),if后面一定要有大括號
  • const聲明一個(gè)只讀的常量,聲明之后,值不能改變。所以,聲明的時(shí)候就要賦值,其他的和let一樣。有一個(gè)注意的點(diǎn)是,比如const了一個(gè)數(shù)組,這個(gè)數(shù)組本身是不能給賦值的,但是這個(gè)數(shù)組是可以push一個(gè)變量的!

  • 頂層對象的屬性

    • 全局變量在es5中是頂層對象的屬性,es6規(guī)定,var和function命令聲明的全局變量依然是頂層對象的屬性,但是let、const、class命令聲明的全局變量不屬于頂層對象的屬性。
  • 頂層對象

    混亂的頂層對象

    • 瀏覽器里面,頂層對象是window,但Node和Web Worker沒有window
    • 瀏覽器和Web Worker里面,self指向頂層對象,但是Node 沒有self
    • Node里面,頂層對象是global,但其他環(huán)境都不支持

    為了在不同的環(huán)境中都能去到頂層對象,一般使用this變量,但是有局限性
    - 全局環(huán)境中,this會返回頂層對象,但是,Node模塊和ES模塊中,this返回的是當(dāng)前模塊
    - 函數(shù)里面的this,如果函數(shù)不是作為對象的方法運(yùn)行,而是單純作為函數(shù)運(yùn)行,this會指向頂層對象,但是,嚴(yán)格模式下,this會返回undefined。
    - 不管是嚴(yán)格模式,還是普通模式,new Function('return this')(),總是會返回全局對象,但是,如果瀏覽器用了CSP(Content Security Policy,內(nèi)容安全政策),那么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('unalble to locate global object'); }

  • 變量的解構(gòu)賦值

es6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行復(fù)賦值,成為解構(gòu)賦值。

  • 數(shù)組的解構(gòu)賦值
    • “模式匹配”,也就是只要等號兩邊的模式相同,左邊的變量就會被賦予對應(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(完全對應(yīng)過去,如果b不加外面的中括號,那b就是[2,3]),d是4
    
    • 等號的右邊如果不是可遍歷的結(jié)構(gòu),會報(bào)錯(cuò)的
    • 默認(rèn)值,允許指定默認(rèn)值,數(shù)組成員嚴(yán)格等于undefined才會使默認(rèn)值生效
    var [foo = true] = [];//foo是true
    
  • 對象的解構(gòu)賦值
    • 變量必須與對象的屬性同名,才能取到正確的值,如果沒有對應(yīng)的同名屬性,取不到值的話,值為undefined
    var {bar, foo} = {foo:'aaa',bar:'bbb'}//foo的值是'aaa',bar的值是'bbb'
    //注意真正被賦值的是誰
    var {foo:baz} = {foo:"aaa",bar:"bbb"}//baz的值是"aaa"而不是foo的值是“aaa”,foo是個(gè)“模式”
    
    誰后面有“:”,誰就是模式,并不是變量
    • 這種寫法,變量的聲明和賦值是一體的,像下面,如果用let或const是不行的,但是用var是可以的。
    let foo;
    let {foo} = {foo:1}//這樣會報(bào)錯(cuò)滴,因?yàn)閒oo在上面已經(jīng)聲明過了,所以不能再次聲明
    //如果非常想用let并且分開的話,可以用下面的方式
    let foo;
    ({foo} = {foo:1})//這樣不會報(bào)錯(cuò),外面必須用()包起來,因?yàn)榻馕銎鲿⑵鹗椎拇罄ㄌ柪斫獬梢粋€(gè)代碼塊而不是賦值語句。
    
    • 默認(rèn)值,默認(rèn)值生效的條件是,對象的屬性值嚴(yán)格等于undefined,同樣,如果解構(gòu)失?。ㄒ簿褪菍?yīng)右邊沒有相同變量名的屬性),那么變量的值等于undefined
    • 實(shí)際應(yīng)用場景:可以很方便的把一些對象的屬性值賦值給其他的變量,不用一個(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ù)組的對象都有一個(gè)length屬性,所以就5了???)
    
  • 數(shù)值和布爾值的解構(gòu)賦值

    解構(gòu)賦值時(shí),如果等號右邊是數(shù)值或布爾值,則會先轉(zhuǎn)為對象,(undefined和null無法轉(zhuǎn)為對象,所以對他們解構(gòu)賦值會出錯(cuò))

  • 函數(shù)形式參數(shù)的解構(gòu)賦值
  • 變量的解構(gòu)賦值的用途
    1. 交換變量的值
    [x,y] = [y,x]//數(shù)組的解構(gòu)是嚴(yán)格按照順序的
    
    1. 從函數(shù)返回多個(gè)值:函數(shù)一次只能返回一個(gè)值,如果要返回多個(gè)值,只能將她們放在數(shù)組或?qū)ο罄锓祷?,有了解?gòu)賦值,可以很方便的取出這些值
    function example(){
      return [1,2,3]
    }
    var [a,b,c] = example()//這樣就賦值了,多方便??
    
    1. 函數(shù)參數(shù)的定義
    function f([x,y,z]){....}
    f([1,2,3])
    
    1. 提取JSON數(shù)據(jù)
    var jsonData = {
     id:42,
     status:"ok",
     data:[22,3]
    }
    let { id, status, data:number } = jsonData;
    
    1. 遍歷Map結(jié)構(gòu)
    2. 輸入模塊的指定方法

  • 字符串的擴(kuò)展(這節(jié)好深奧,先放下??
    • 字符的Unicode表示法,用\uxxxx形式來表示一個(gè)字符,其中xxxx表示字符的碼點(diǎn)
  • 正則的擴(kuò)展
  • 數(shù)值的擴(kuò)展

  • 數(shù)組的拓展

    • Array.from(),用于將兩類對象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對象和可遍歷的對象。
    let arrayLike = {
      '0':'a',
      '1':'b',
      '2':'c',
      length:3
    };//類似數(shù)組的對象
    let arr = Array.from(arrayLike);//['a','b','c']
    
    • 實(shí)際應(yīng)用中,常見的類似數(shù)組的對象是DOM操作返回的NodeList集合,以及函數(shù)內(nèi)部的arguments對象。(所謂類似數(shù)組的對象本質(zhì)特征只有一點(diǎn),即必須有l(wèi)ength屬性,任何有l(wèi)ength屬性的對象,都可以通過Array.from方法轉(zhuǎn)為數(shù)組)
    • Array.of(),用于將一組值轉(zhuǎn)換為數(shù)組,沒有參數(shù)的時(shí)候返回一個(gè)空數(shù)組
    Array.of(1,2,4)//【1,2,4】
    
    • copyWithin(),在當(dāng)前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置(會覆蓋原有成員),然后返回當(dāng)前數(shù)組,也就是會修改當(dāng)前數(shù)組。
    Array.prototype.copyWith(target,start,end)//接受三個(gè)參數(shù),其中target是必需的,target代表從該位置開始替換數(shù)據(jù),start表示從該位置開始讀取數(shù)據(jù),默認(rèn)為0,負(fù)數(shù)則表示倒數(shù),end表示到該位置前停止讀取數(shù)據(jù),默認(rèn)等于數(shù)組長度,負(fù)數(shù)則表示倒數(shù)
    [1,2,3,4].copyWithin(0,3)//[4,4,4,4],從0開始用3位置上(也就是4這個(gè)數(shù)字到末尾的0來替換0
    
    • 數(shù)組實(shí)例的find()和findIndex()

    find方法用于找出第一個(gè)符合條件的數(shù)組成員,參數(shù)是一個(gè)回調(diào)函數(shù),所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù),直到找出第一個(gè)返回值為true的成員,然后返回該成員。如果沒有符合條件的成員,則返回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ù),用來綁定回調(diào)函數(shù)的this對象。
    
    • 數(shù)組實(shí)例的fill()

    fill方法使用給定值,填充一個(gè)數(shù)組。如果數(shù)組中已有元素,則會全部被抹去。參數(shù)和copyWithin函數(shù)的參數(shù)是一致的。

    ['a','b','c'].fill(7)//返回一個(gè)[7,7,7]
    
    • 數(shù)組實(shí)例的entries(),keys()和values()----遍歷數(shù)組的函數(shù)
    ------對鍵名的遍歷
    for(let index of ['a','b'].keys()){
         console.log(index);
     }//結(jié)果如下
     //0
     //1
    ------對鍵值的遍歷
     for(let elem of ['a','b'].values()){
         console.log(elem);
     }//結(jié)果如下
     //'a'
     //'b'
     ------對鍵值對的遍歷
     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,所以返回true
    
    Map結(jié)構(gòu)的has方法,是用來查找鍵名的
    Set結(jié)構(gòu)的has方法,是用來查找值的
    
    • 數(shù)組的空位

    數(shù)組的空位是指,數(shù)組的某一個(gè)位置沒有任何值,es6明確的將空位轉(zhuǎn)為undefined。以上數(shù)組的擴(kuò)展方法都會把空位考慮進(jìn)去,而不是忽略。

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

    • 函數(shù)參數(shù)的默認(rèn)值
    function log(x, y = 'world'){
    ...}
    
    • 與解構(gòu)賦值默認(rèn)值結(jié)合使用(沒看懂??
    • 參數(shù)默認(rèn)值的位置

    非尾部的參數(shù)如果設(shè)置了默認(rèn)值,那么這個(gè)參數(shù)是不能夠省略的!

    • 函數(shù)的length屬性

    指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個(gè)數(shù),也就是說,指定了默認(rèn)值以后,length屬性將失真。失真也就是不算它。

    (function (a,b=2){}).length
    //1
    
    • 作用域---大爺

      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)來的x的值,如果沒有,
      才是全局變量中的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不存在,就會報(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ù)的作
      用域還沒有形成,所以匿名函數(shù)里面的foo指向外層作用域來的foo,輸出的是outer
      ????
      

      2.rest參數(shù)

      rest參數(shù)形式為"...變量名",用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對象了,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)為用逗號分隔的參數(shù)序列。注意,擴(kuò)展運(yùn)算符針對的是數(shù)組數(shù)組數(shù)組??也就是把一個(gè)數(shù)組相當(dāng)于給拆開了。

    console.log(...[1,2,3])
    //1 2 3
    
    function 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接口的對象,任何Iterator接口的對象,都可以用擴(kuò)展運(yùn)算符轉(zhuǎn)為真正的數(shù)組。
      let arrayLike = {
       '0':'a',
       '1':'b',
       '2':'c',
       length:3
      };
      let arr = [...arrayLike]//TypeError
      //arrayLike是一個(gè)類似數(shù)組的對象,但是沒有部署Iterator接口,擴(kuò)展運(yùn)算符就會報(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接口的對象,都可以使用擴(kuò)展運(yùn)算符。

    4.嚴(yán)格模式use strict

    es6規(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è)圓括號代表參數(shù)部分。
    • 如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號將他們括起來,并且使用return語句返回
    • 如果要返回一個(gè)對象,外面要用小括號包起來,因?yàn)榇罄ㄌ柋唤忉尀榇a塊,所以必須在對象外面加上括號
    • 函數(shù)體內(nèi)的this對象,就是定義時(shí)所在的對象,而不是使用時(shí)所在的對象,在箭頭函數(shù)中,this是固定的。因?yàn)榧^函數(shù)沒有自己的this,他們的this其實(shí)都是外層對象(也就是函數(shù))的this。所以bind(),call(),apply()這些方法無法改變this的指向。
    • 不可以當(dāng)做構(gòu)造函數(shù),也就是不能用new操作符
    • 不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在,如果要用,可以用rest參數(shù)代替
    • 不可以使用yield命令,因此箭頭函數(shù)不能用做generator函數(shù)

    7.綁定this::es7的一個(gè)題案,如果用的話需要babel轉(zhuǎn)碼器

    雙冒號左邊是一個(gè)對象,右邊是一個(gè)函數(shù),該運(yùn)算符會自動將左邊的對象,作為上下文環(huán)境(即this對象)綁定到右邊的函數(shù)上面,如果雙冒號左邊為空,右邊是一個(gè)對象的方法,則等于將該方法綁定在該對象上面。

    8.尾調(diào)用優(yōu)化??看不懂??10.27

    尾調(diào)用是函數(shù)式編程的一個(gè)重要概念,指的是某個(gè)函數(shù)的最后一步是調(diào)用另一個(gè)函數(shù)

  • 對象的擴(kuò)展

    • 屬性的簡潔表示法
    情況一:
    var foo = 'a';
    var baz = {foo};
    //以往寫對象的時(shí)候要屬性名、屬性值成對出現(xiàn),es6允許在對象中,只寫屬性名,
    不寫屬性值,這時(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返回對象的時(shí)候就是這樣寫的?。?!??
    // 等同于hello: function ()...
    hello() { console.log('我的名字是', this.name); }
    };
    
    • 屬性名表達(dá)式??
    • Object.js()

    比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符:相等運(yùn)算符==和嚴(yán)格相等運(yùn)算符===,前者會自動轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。Object.is用來比較兩個(gè)值是否嚴(yán)格相等,彌補(bǔ)了===的缺點(diǎn)。

    • Object.assign()

    Object.assign()用于對象的合并,將源對象的所有可枚舉屬性,復(fù)制到目標(biāo)對象。

    Object.assign(target,source1,source2...)
    //第一個(gè)參數(shù)是目標(biāo)對象,也就是最終的,后面都是源對象。如果只有一個(gè)參數(shù)那就直接返回
    //????????如果目標(biāo)對象與源對象有同名屬性,或者多個(gè)源對象有同名屬性,則后面的屬性會
    覆蓋前面的屬性
    ??undefined和null不能放在目標(biāo)對象的位置(放,報(bào)錯(cuò),不放也就是放在別的位置會被跳過)
    ??字符串可以作為源對象,復(fù)制到目標(biāo)對象里會是數(shù)組的形式,布爾值和數(shù)值都不能作為源對象,
    雖然不報(bào)錯(cuò),但是會跳過
    
    ??注意點(diǎn)
    1.Object.assign是淺拷貝,如果源對象某個(gè)屬性的值是對象,如果源對象某個(gè)屬性的值是對象,
    那么目標(biāo)對象拷貝得到的是這個(gè)對象的引用。
    2.Object.assign也可以處理數(shù)組,但是也是將數(shù)組視為對象。
    
    - Object.assign常見用途
      - 為對象添加屬性
      - 為對象添加方法,目標(biāo)對象就是xxx.prototype,然后源對象就是用大括號包裹的函數(shù)
      - 克隆對象
      - 合并多個(gè)對象
      - 為屬性指定默認(rèn)值(可以將屬性的默認(rèn)值為一個(gè)對象,用戶輸入的為另一個(gè)對象,兩個(gè)對象作為源對象復(fù)制給目標(biāo)對象,因?yàn)橛脩糨斎氲姆旁诤竺嫠詴采w掉默認(rèn)值對象的值,so~)
    
    • 屬性的可枚舉性

    對象的每個(gè)屬性都有一個(gè)描述對象(Descriptor),用來控制該屬性的行為。Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對象

    let obj = {foo:123};
    Object.getOwnPropertyDescriptor(obj,'foo')
    //{
    //    value:123,
    //    writable:true,
    //    enumerable:true,是否可以枚舉
    //    configurable:true
    //}
    
    • 屬性的遍歷
      1. for...in,遍歷對象自身的和繼承的可枚舉屬性(不包含Symbol屬性)
      2. Object.keys(obj),返回一個(gè)數(shù)組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。
      3. Object.getOwnPropertyNames(obj),返回一個(gè)數(shù)組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。
      4. Object.getOwnPropertySymbols(obj),返回一個(gè)數(shù)組,包含對象自身的所有Symbol屬性
      5. Reflect.ownKeys(obj),返回一個(gè)數(shù)組,包含對象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可以枚舉。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容