<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [toc] 為了更好的學習本章節的內容,我們先來重溫一下之前學過的知識。 ### [回顧]屬性描述符 #### 什么是屬性描述符 該節中回顧的內容并非ES6中的知識,而是在ES6之前就已存在的JS知識。 Property Descriptor 屬性描述符:是一個普通對象,相當于一個對象中某個屬性的一些描述信息的集合,用于描述一個屬性的相關信息 #### 如何獲取一個對象的屬性描述符? 通過```Object.getOwnPropertyDescriptor(對象, 屬性名)```可以得到一個對象的某個屬性的屬性描述符 - value:屬性值 - configurable:該屬性的描述符是否可以修改 - enumerable:該屬性是否可以被枚舉 - writable:該屬性是否可以被重新賦值,即該屬性的value屬性值是否可以被修改。 > ```Object.getOwnPropertyDescriptors(對象)```可以得到某個對象的所有屬性描述符 #### 如何修改對象的屬性描述符? 如果需要為某個對象添加屬性時 或 修改屬性時, 配置其屬性描述符,可以使用下面的代碼: ```js const obj = { a:33, b:44 } // Object.defineProperty(對象, 屬性名, 描述符);設置對象的某個屬性的屬性描述符內容 Object.defineProperty(obj, 'b', { value: 100, //執行完該條語句后對象obj的屬性b的值變為100 writable: false //執行完該條語句后value的值就不能再被修改了 }) obj.b = 80 //因為上面設置了屬性描述符writable為false,所以該條語句執行會報錯。 //Object.defineProperties(對象, 多個屬性的描述符);可以同時設置對象內多個屬性的屬性描述符 Object.defineProperties(obj,{ a:{ value:55, writable: true }, b:{ value:100, writable: true } }) ``` #### 存取器屬性-屬性描述符中較特殊的屬性 屬性描述符中,如果配置了 get 和 set 中的任何一個,則該屬性,不再是一個普通屬性,而變成了存取器屬性。 get 和 set配置均為函數,如果一個屬性是存取器屬性,則讀取該屬性時,會運行get方法,將get方法得到的返回值作為屬性值;如果給該屬性賦值,則會運行set方法。 存取器屬性實例應用: ```js //應用場景,假設有一個學生信息記錄系統,要求年齡輸入時如果小于8歲或大于14歲就會提示輸入錯誤,可以使用存取器來實現 const student = { name: 'abc' } Object.defineProperty(student, 'age', { //此時我們將age屬性定義為存取器屬性 set(val){ //age屬性設置了set以后,每次給age屬性賦值時就會執行該函數 if(val >=8 || val <= 14){ student._age = val //因為存取器屬性的特殊性,我們在賦值的時候用_age屬性來代替age屬性。 }else{ console.log('請輸入年齡在8-14歲之間的值') } }, get(){ //age屬性設置了get以后,每次讀取age的值的時候會持行該函數 return student._age //同樣在讀取age的值的時候我們也用_age屬性的值來代替,相當于用age存取器set和get函數來操作_age屬性的值。 } } student.age = -100; //給age屬性賦值會調用set函數,此時檢測到-100小于8,根據set代碼執行結果:系統會顯示提示信息。運用此方法還可以判斷數據類型的輸入是否正確或增加更多的操作功能。 ``` >存取器屬性最大的意義,在于可以控制屬性的讀取和賦值。很多DOM元素中的屬性使用的都是存取器屬性,例如innerHTML ### Reflect #### Reflect是什么? Reflect是一個內置的JS對象,它提供了一系列方法,可以讓開發者通過調用這些方法,訪問一些JS底層功能 由于它類似于其他語言的**反射**,因此取名為Reflect #### 它可以做什么? 使用Reflect可以實現諸如 屬性的賦值與取值、調用普通函數、調用構造函數、判斷屬性是否存在與對象中 等等功能 #### 為什么需要用Reflect實現? 有一個重要的理念,在ES5就被提出:減少魔法、讓代碼更加純粹 這種理念很大程度上是受到函數式編程的影響 ES6進一步貫徹了這種理念,它認為,對屬性內存的控制、原型鏈的修改、函數的調用等等,這些都屬于底層實現,屬于一種魔法,因此,需要將它們提取出來,形成一個正常的API,并高度聚合到某個對象中,于是,就造就了Reflect對象 因此,你可以看到Reflect對象中有很多的API都可以使用過去的某種語法或其他API實現。 #### Reflect提供了哪些API? - Reflect.set(target, propertyKey, value): 設置對象target的屬性propertyKey的值為value,等同于給對象的屬性賦值 - Reflect.get(target, propertyKey): 讀取對象target的屬性propertyKey,等同于讀取對象的屬性值 - Reflect.apply(target, thisArgument, argumentsList):調用一個指定的函數,并綁定this和參數列表。等同于函數調用 - Reflect.deleteProperty(target, propertyKey):刪除一個對象的屬性 - Reflect.defineProperty(target, propertyKey, attributes):類似于Object.defineProperty,不同的是如果配置出現問題,返回false而不是報錯 - Reflect.construct(target, argumentsList):用構造函數的方式創建一個對象 - Reflect.has(target, propertyKey): 判斷一個對象是否擁有一個屬性 - 更多Reflect的API查閱:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect ### Proxy 代理 代理的功能:提供了修改底層實現的方式 如何建立一個對象的代理 ```js //代理一個目標對象 //target:目標對象 //handler:是一個普通對象,其中可以重寫底層實現 //返回一個代理對象 const proxy = new Proxy(target, handler); ``` 代理是將target目標對象包裹了一層返回一個新的對象,這樣所有針對目標對象的操作需要通過代理對象來實現。(有點類似于當事人和律師的關系,各類詢問均與律師交流,律師再將相關的結果轉告當事人) 建立代理對象的handler參數是一個對象,對象中可以設置一些方法,用來改變操作對象的一些規則。Proxy代理在handler中可以改變Reflect反射中的各種底層實現。 例如,有這樣一個需求:在使用代理來讀取一個對象的某個屬性值時,如果對象具有該屬性,則返回屬性值,如果不具有該屬性返回false。我們就可以用代理來實現。 ```js const student = { name:'aaa', age: 20, class: 3 } const std = new Proxy (student, { get(target, propertyKey) { //在代理的handler中新建一個get方法 if (Reflect.has(target, propertyKey)) { //handler中盡量使用Reflect反射中底層方法來實現,方便代碼閱讀。本條語句用Reflect來判斷對象是否具有該屬性,相當于(propertyKey in target) return Reflect.get(target, propertyKey); //如果存在屬性,用Reflect的get方法返回屬性值 } else { return false; //若不存在返回false } }, }) //用了代理以后,我們針對student對象操作屬性時使用std代理對象來操作。 console.log(std.age); //返回20 console.log(std.address); //返回false ``` >靈活運用代理,可以為操作對象制定很多更加靈活的規則。其功能類似于屬性描述符的存取器屬性。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看