Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在ES6中,如何重写超类中的私有方法?_Javascript_Ecmascript 6_Symbols_Es6 Class - Fatal编程技术网

Javascript 在ES6中,如何重写超类中的私有方法?

Javascript 在ES6中,如何重写超类中的私有方法?,javascript,ecmascript-6,symbols,es6-class,Javascript,Ecmascript 6,Symbols,Es6 Class,我正在学习ES6课程 我希望以某种形式使用私有属性,以便只能从类的实例调用某些方法 例如使用符号 /* A.js */ const _privateMethod = Symbol('_privateMethod') class A { [_privateMethod]() { return 'yup' } do() { return this[_privateMethod]() } } const a = new A() a.d

我正在学习ES6课程

我希望以某种形式使用私有属性,以便只能从类的实例调用某些方法

例如使用符号

/* A.js */

const _privateMethod = Symbol('_privateMethod')
class A {
    [_privateMethod]() {
        return 'yup'
    }
    do() {
        return this[_privateMethod]()
    }
}

const a = new A()
a.do() /* yup */
…_privateMethod无法直接调用。到目前为止还不错

但是,我想知道如何在继承自a的类中重写_privateMethod。例如,以下操作将不起作用:

/* B.js */

const _privateMethod = Symbol('_privateMethod')
class B extends A {
    [_privateMethod]() {
        return 'nope'
    }
}

const b = new B()
b.do() /* yup */
建议如何执行此操作

调用
符号(“u privateMethod”)
再次创建一个新的、不同的符号(即使它具有相同的描述)。您正在使用不同的键创建不同的方法,而不是覆盖原始方法

您需要使用完全相同的符号来定义子类中的方法。您可以从a.js中导出
\u privatMethod
符号作为常量,然后将其导入B.js中(与
类a
一起),或从中获取它。但是,如果您想使类具有可扩展性,我建议您完全不要使用符号。

您可以使用以下函数:

const A=(函数(){
常量privateMethod=符号(“privateMethod”)
返回A类{
[_privateMethod](){
返回“是”
}
do(){
返回此[\u privateMethod]()
}
}
}());
(功能(){
const_privateMethod=Object.getOwnPropertySymbols(A.prototype)
.find(x=>x.toString()=='Symbol(_privateMethod)'
B类扩展了A类{
[_privateMethod](){
返回“否”
}
}
常数b=新的b()
console.log(b.do());

}());您已经有了正确的答案,请检查此选项

const\u privateMethod=符号(“privateMethod”)
甲级{
[_privateMethod](){
返回“是”
}
do(){
返回此[\u privateMethod]()
}
}
常数a=新的a()
document.write(a.do()+“

”) B类扩展了A类{ [_privateMethod](){ 返回“否” } } 常数b=新的b()
document.write(b.do()+“

编程概念之所以在实践中使用,是因为它们为开发人员提供了一些好处,这也包括封装。如果它弊大于利,这意味着它不应该被应用,或者应用的方式是错误的

JavaScript没有提供封装作为语言特性。符号是一种可以接受的实现方法,但它有其特殊性,可能使其不适合该任务

用作私有(受保护)成员标识符的符号应始终与其所属的类一起导出:

export const _privateMethod = Symbol('_privateMethod');
export class A {
    [_privateMethod]() {/*...*/}
    /*...*/
}

...

import { _privateMethod, A } from './a';

class B extends A {
    [_privateMethod]() {/*...*/}
}
如果这是不可能或不实用的,这意味着符号不适合用于封装,因为它提供了缺点而没有任何实际好处

由于信息隐藏在JavaScript中不起安全作用(可以通过
对象.getOwnPropertySymbols
访问符号),因此封装机制的替代方法是使用匈牙利符号和/或JSDoc注释。它们为开发人员提供了有关公共接口的必要信息:

export class A {
    /** @protected */
    _privateMethod() {/*...*/}
    /*...*/
}

仍然可以直接调用
[\u privateMethod]
的可能副本。您希望将方法设置为私有的原因是什么?@Cruiser我看不出这个问题(关于如何重写由符号标识的类方法)与您建议的方法有什么相似之处。请注意,您并没有真正的私有方法。例如,您可以使用
a[Object.getOwnPropertySymbols(Object.getPrototypeOf(a))[0]]()
从另一个无法直接访问
\u privateMethod
的文件调用
a[\u privateMethod]
。OOP最佳实践是为了帮助开发人员,而不是被虔诚地观察和攻击。如果好处不清楚,那就不值得了。谢谢,这很有道理!(我开始认为使用所有公共方法更简单,命名约定使用下划线)