I'm learning about classes in ES6...
I'd like to use private properties, in some form, so that only certain methods can be called from an instance of a class.
For example using Symbol...
/* A.js */
const _privateMethod = Symbol('_privateMethod')
class A {
[_privateMethod]() {
return 'yup'
}
do() {
return this[_privateMethod]()
}
}
const a = new A()
a.do() /* yup */
..._privateMethod cannot be called directly. So far so good.
However, I am wondering how to then go about overriding _privateMethod in a class that inherits from A. For example, the following will not work:
/* B.js */
const _privateMethod = Symbol('_privateMethod')
class B extends A {
[_privateMethod]() {
return 'nope'
}
}
const b = new B()
b.do() /* yup */
How is it remended to do this?
I'm learning about classes in ES6...
I'd like to use private properties, in some form, so that only certain methods can be called from an instance of a class.
For example using Symbol...
/* A.js */
const _privateMethod = Symbol('_privateMethod')
class A {
[_privateMethod]() {
return 'yup'
}
do() {
return this[_privateMethod]()
}
}
const a = new A()
a.do() /* yup */
..._privateMethod cannot be called directly. So far so good.
However, I am wondering how to then go about overriding _privateMethod in a class that inherits from A. For example, the following will not work:
/* B.js */
const _privateMethod = Symbol('_privateMethod')
class B extends A {
[_privateMethod]() {
return 'nope'
}
}
const b = new B()
b.do() /* yup */
How is it remended to do this?
Share Improve this question edited Jan 29, 2018 at 20:44 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Jan 29, 2018 at 20:13 user1031947user1031947 6,68417 gold badges65 silver badges91 bronze badges 6- Possible duplicate of how to override a javascript function – Cruiser Commented Jan 29, 2018 at 20:27
-
[_privateMethod]
can still be called directly. What is the reason why you want to make the method private? – t.niese Commented Jan 29, 2018 at 20:28 - 1 @Cruiser I don't see how this question (about how to override a class method identified by a symbol) is at all similar to your proposed duplicate – apsillers Commented Jan 29, 2018 at 20:28
-
2
Note that you do not truly have private methods. You could, for example, use
a [ Object.getOwnPropertySymbols(Object.getPrototypeOf(a))[0] ]()
to calla[_privateMethod]
from another file that can't access_privateMethod
directly. – Paul Commented Jan 29, 2018 at 20:33 - 1 OOP best practices are there to help a developer, not to be observed religiously and shoot in the foot. If the benefits are unclear, it's not worth it. – Estus Flask Commented Jan 29, 2018 at 21:00
4 Answers
Reset to default 3Calling Symbol('_privateMethod')
again creates a new, distinct symbol (even if it has the same description). You are creating a different method with a different key, not overwriting the original one.
You will need to use the exact same symbol to define the method in the subclass. You can either get it from Object.getOwnPropertySymbols(A.prototype)
or by exporting the _privatMethod
symbol as a constant from A.js and importing it in B.js (together with the class A
). However, if you want to make the class extensible, I would remend to simply not use symbols at all.
The reason why programming concepts are used in practice is because they provide some benefits to a developer, this includes encapsulation, too. If it provides more disadvantages than benefits, this means that it shouldn't be applied, or the way it was applied was wrong.
JavaScript doesn't have provide encapsulation as language feature. Symbol is an acceptable way to implement it, but it has its specificity that can make it unsuitable for the task.
A symbol that serves as an identifier for private (protected) member should always be exported together with a class it belongs to:
export const _privateMethod = Symbol('_privateMethod');
export class A {
[_privateMethod]() {/*...*/}
/*...*/
}
...
import { _privateMethod, A } from './a';
class B extends A {
[_privateMethod]() {/*...*/}
}
If this is not possible or practical, this means that a symbol is inappropriate choice for encapsulation, because it provides disadvantages without any real benefits.
Since information hiding doesn't serve security purposes in JavaScript (symbols are accessible with Object.getOwnPropertySymbols
), the alternative to encapsulation mechanism is the use of Hungarian notation and/or JSDoc annotations. They provide a developer with necessary information about public interface:
export class A {
/** @protected */
_privateMethod() {/*...*/}
/*...*/
}
You can use the Object.getOwnPropertySymbols()
function:
const A = (function() {
const _privateMethod = Symbol('_privateMethod')
return class A {
[_privateMethod]() {
return 'yup'
}
do() {
return this[_privateMethod]()
}
}
}());
(function() {
const _privateMethod = Object.getOwnPropertySymbols(A.prototype)
.find(x => x.toString() === 'Symbol(_privateMethod)')
class B extends A {
[_privateMethod]() {
return 'nope'
}
}
const b = new B()
console.log(b.do());
}());
you already has the right answer, check this
const _privateMethod = Symbol('_privateMethod')
class A {
[_privateMethod]() {
return 'yup'
}
do() {
return this[_privateMethod]()
}
}
const a = new A()
document.write(a.do()+ "<br><br>" )
class B extends A {
[_privateMethod]() {
return 'nope'
}
}
const b = new B()
document.write(b.do()+ "<br><br>")
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744373117a4571054.html
评论列表(0条)