2017-08-08 93 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