2017-08-08 36 views
0

這是我通常用來防止覆蓋name屬性的方法。如何防止es6中的函數覆蓋?

let _name = Symbol('name'); 
 

 
class Cat { 
 
    constructor(name) { 
 
     this[_name] = name; 
 
    } 
 
    set name(newName) { 
 
     return this[_name]; 
 
    } 
 
    get name() { 
 
    \t return this[_name]; 
 
    } 
 
} 
 

 
// default name 
 
let cat = new Cat('Hermione'); 
 

 
// new name 
 
cat.name = 'Voldermort'; 
 

 
// testing 
 
console.log(cat.name);

我的想法:name屬性的值保存到另一個變量。

但是,如果我有多個類的屬性,就像這樣:

1

將被浪費創造了很多的變數保存。

let _Min = Symbol('Min'), _Max = Symbol('Max'); // and so on 

是否有另一種方法來實現這一目標?謝謝!

+1

有什麼辦法,你可以得到所有屬性的數組,比如'名字','Min','Where'等等?然後你可以使用'Proxy'並攔截set屬性操作。 – Li357

+1

聽起來好像你會受益於[**類繼承**](https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)。然後,您可以定義要在基類中使用的變量,並只覆蓋子類中所需的變量。 –

+1

你想讓對象不可變嗎?像['Object.freeze'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)? – 4castle

回答

2

爲了只讀,屬性應該沒有set訪問:

class Foo { 
    get bar() { 
    return 'bar'; 
    } 
} 

如果屬性應該是在建設定義,描述符可以過定義:

class Cat { 
    constructor(name) { 
    Object.defineProperty(this, name, { 
     get:() => name, 
     configurable: true 
    }); 
    } 
} 

或者

class Cat { 
    constructor(name) { 
    Object.defineProperty(this, name, { 
     value: name, 
     writable: false, 
     configurable: true 
    }); 
    } 
} 
+0

謝謝!但是在構造函數中使用'Object.defineProperty'是很奇怪的。我之前沒有閱讀過任何文檔。 – Vayne

+0

沒有什麼奇怪的。這是核心JS功能。文檔不必明確地說Object.defineProperty可以在構造函數中使用,也可以在循環中使用,或者使用其他語言構造。如果需要的話,這是必要的。 'get'和'set'類方法只是Object.defineProperty的語法糖(你可以查看它在Babel/Typescript轉換代碼中的工作方式),但如果它們不適合這種情況,它們就不那麼好了。 – estus