日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ES6-8 - 函数名/对象拓展、描述符、getter/setter

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ES6-8 - 函数名/对象拓展、描述符、getter/setter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數名

有兩種特殊情況:bind方法創造的函數,name屬性返回bound加上原函數的名字;Function構造函數創造的函數,name屬性返回anonymous。

  • bind函數名
// 以bound開頭 function foo() { } const fnName = foo.bind().name console.log(fnName) // bound foo
  • getter setter

如果對象的方法使用了取值函數(getter)和存值函數(setter),則name屬性不是在該方法上面,而是該方法的屬性的描述對象的get和set屬性上面,返回值是方法名前加上get和set。

const obj = {get foo() {},set foo(x) {} };obj.foo.name // TypeError: Cannot read property 'name' of undefinedconst descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');descriptor.get.name // "get foo" descriptor.set.name // "set foo"

對象方法的簡寫

const o = {method() {return "Hello!";} };
  • node common.js寫法+

屬性名表達式

ES6 允許字面量定義對象時,用方法二(表達式)作為對象的屬性名,即把表達式放在方括號內。

let propKey = 'foo';let obj = {[propKey]: true,['a' + 'bc']: 123 }; let obj = {['h' + 'ello']() {return 'hi';} };obj.hello() // hi
  • 屬性名可以重復,重復則覆蓋
let b = 'b' let obj = {['a' + 'b'] : undefined,['a' + b] : 1, // 屬性名和上面重復,永遠取最后的,obj最后依然只有一個鍵‘ab’ } 屬性名表達式如果是一個對象,默認情況下會自動將對象轉為字符串[object Object],這一點要特別小心。 const keyA = {a: 1}; const keyB = {b: 2};const myObject = {[keyA]: 'valueA',[keyB]: 'valueB' };myObject // Object {[object Object]: "valueB"} // 1. 屬性名相同覆蓋 // 2. 將一切js變量轉為字符串,作為屬性名
  • 一個對象的屬性名可以是任何有效的 JavaScript 字符串,或者可以被轉換為字符串的任何類型,包括空字符串。然而,一個屬性的名稱如果不是一個有效的 JavaScript 標識符(例如,一個由空格或連字符,或者以數字開頭的屬性名),就只能通過方括號標記訪問。這個標記法在屬性名稱是動態判定(屬性名只有到運行時才能判定)時非常有用。
  • JavaScript中的對象只能使用String類型作為鍵類型。
  • 屬性描述符

    • getOwnPropertyDescriptor是構造器上的方法
    • 方法返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)若無返回undefined
    • Object.getOwnPropertyDescriptor(obj, prop)

    一個屬性描述符是一個記錄,由下面屬性當中的某些組成的:

  • value
    該屬性的值(僅針對數據屬性描述符有效)
  • writable
    當且僅當屬性的值可以被改變時為true。(僅針對數據屬性描述有效)
    重新賦值,不包括刪除!
  • get
    獲取該屬性的訪問器函數(getter)。如果沒有訪問器, 該值為undefined。(僅針對包含訪問器或設置器的屬性描述有效)
  • set
    獲取該屬性的設置器函數(setter)。 如果沒有設置器, 該值為undefined。(僅針對包含訪問器或設置器的屬性描述有效)
  • configurable
    當且僅當指定對象的屬性描述可以被改變或者屬性可被刪除時,為true。
    delete obj.a
  • enumerable
    當且僅當指定對象的屬性可以被枚舉出時,為 true。
  • Object.defineProperty(o, "baz", {value: 8675309,writable: false, // 重寫baz屬性會靜默失敗;而嚴格模式重寫則報錯enumerable: false });
    • 注意:在 ES5 中,如果該方法的第一個參數不是對象(而是原始類型),那么就會產生出現 TypeError。而在 ES2015,第一個的參數不是對象的話就會被強制轉換為對象。
    Object.getOwnPropertyDescriptor('foo', 0); // 類型錯誤: "foo" 不是一個對象 // ES5 codeObject.getOwnPropertyDescriptor('foo', 0); // Object returned by ES2015 code: { // configurable: false, // enumerable: true, // value: "f", // writable: false // }

    getter、setter在對象上

    使用Object.defineProperties的方法,同樣也可以對一個已創建的對象在任何時候為其添加getter或setter方法。這個方法的第一個參數是你想定義getter或setter方法的對象,第二個參數是一個對象,這個對象的屬性名用作getter或setter的名字,屬性名對應的屬性值用作定義getter或setter方法的函數。

    • set必須要有參數,否則報錯Uncaught SyntaxError: Setter must have exactly one formal parameter.
    var o = {a: 7,get b() { return this.a + 1;},set c(x) {this.a = x / 2} };console.log(o.a); // 7 console.log(o.b); // 8 注意訪問方式 get直接讀 o.c = 50; // set要賦值 console.log(o.a); // 25 var language = {set add(name){this.ln.push(name)},ln: [] } language.add = 'EN' language.add = 'FN' console.log(language.ln) // ["EN","FN"]

    mdn getter
    mdn setter

    • a也是o的屬性,只是用getter、setter劫持了
    • 如果getter和屬性重名,會報錯 Uncaught RangeError: Maximum call stack size exceeded

    不可能同時將一個 getter 綁定到一個屬性并且該屬性實際上具有一個值。
    使用get語法時,不能與另一個 get 或具有相同屬性的數據條目同時出現在一個對象字面量中。
    不允許使用 { get x() { }, get x() { } } 和 { x: …, get x() { } })。
    在對象字面量中,不能為一個已有真實值的變量使用 set ,也不能為一個屬性設置多個 set。
    ( { set x(v) { }, set x(v) { } } 和 { x: …, set x(v) { } } 是不允許的 )

    var o = {_a: 7,get a() { return this._a + 1;},set a(x) {this._a = x / 2} };console.log(o.a); // 8 o.a = 10 console.log(o.a); // 6 console.log(Object.keys(o)) // ["_a","a"]

    • Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
    var obj = {get a(){return 2} } // 注意:這里也不能再為已有的對象屬性,使用defineProperty Object.defineProperty(obj, 'b', {get: function(){return this.a + 100},// value: 2 寫了get不能再寫value/writable,否則報錯 }) console.log(obj.a) // 2 console.log(obj.b) // 102
    • get和set一般是成對出現的,并且不應寫死,不然沒有意義

    getter/setter → 偽屬性

    • Object.defineProperty與創建對象時定義getter/setter的區別
    • Object.defineProperty的getter/setter/其余普通屬性不可枚舉、不可配置
    const obj = {a: 2 } Object.defineProperty(obj, 'b', {set: function (x) {this.a = x} }) const res = Object.getOwnPropertyDescriptor(obj, 'b') console.log(res) console.log(Object.keys(obj))const obj2 = {_a: 2,get a() {return this._a},set a(val) {this._a = val} } const res2 = Object.getOwnPropertyDescriptor(obj2, 'a') console.log(res2) console.log(res2.get.name) // get a console.log(res2.set.name) // set a console.log(Object.keys(obj2))


    總結

    以上是生活随笔為你收集整理的ES6-8 - 函数名/对象拓展、描述符、getter/setter的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。