Gle*_*ift 134 javascript class ecmascript-5 ecmascript-6 traceur
我现在使用Traceur Compiler来获得ES6功能.
我想从ES5实现这些东西:
function Animal() {
var self = this,
sayHi;
sayHi = function() {
self.hi();
};
this.hi = function() {/* ... */}
}
Run Code Online (Sandbox Code Playgroud)
目前traceur不支持private
和public
关键字(来自和谐).ES6类语法不允许在类体中使用简单var
(或let
)语句.
我找到的唯一方法是在类声明之前模拟私有.就像是:
var sayHi = function() {
// ... do stuff
};
class Animal {
...
Run Code Online (Sandbox Code Playgroud)
没有什么比通过预期的更好,this
没有apply
-ing或bind
-ing它每次都不能将正确的方法传递给私有方法.
那么,是否有可能在ES6类中使用与traceur编译器兼容的私有数据?
ale*_*ods 212
有没有private
,public
或者protected
在现有的关键字的ECMAScript 6规范.
所以Traceur不支持private
和public
.6to5(目前它被称为"Babel")实现了这个提议用于实验目的(另见本讨论).但毕竟这只是提案.
所以现在你可以通过模拟私人财产WeakMap
(见这里).另一种选择是Symbol
- 但它不提供实际的隐私,因为可以通过该属性轻松访问Object.getOwnPropertySymbols
.
恕我直言,此时最好的解决方案 - 只使用伪隐私.如果您经常使用apply
或call
使用您的方法,则此方法非常特定于对象.因此,只需使用下划线前缀在您的类中声明它是值得的:
class Animal {
_sayHi() {
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
Max*_*Max 70
您始终可以使用常规功能:
function myPrivateFunction() {
console.log("My property: " + this.prop);
}
class MyClass() {
constructor() {
this.prop = "myProp";
myPrivateFunction.bind(this)();
}
}
new MyClass(); // 'My property: myProp'
Run Code Online (Sandbox Code Playgroud)
Mar*_*oni 53
虽然目前无法将方法或属性声明为私有,但ES6模块不在全局命名空间中.因此,您在模块中声明但不导出的任何内容都不会对程序的任何其他部分可用,但在运行时仍可供模块使用.因此,你有私有属性和方法:)
这是一个例子(在test.js
文件中)
function tryMe1(a) {
console.log(a + 2);
}
var tryMe2 = 1234;
class myModule {
tryMe3(a) {
console.log(a + 100);
}
getTryMe1(a) {
tryMe1(a);
}
getTryMe2() {
return tryMe2;
}
}
// Exports just myModule class. Not anything outside of it.
export default myModule;
Run Code Online (Sandbox Code Playgroud)
在另一个文件中
import MyModule from './test';
let bar = new MyModule();
tryMe1(1); // ReferenceError: tryMe1 is not defined
tryMe2; // ReferenceError: tryMe2 is not defined
bar.tryMe1(1); // TypeError: bar.tryMe1 is not a function
bar.tryMe2; // undefined
bar.tryMe3(1); // 101
bar.getTryMe1(1); // 3
bar.getTryMe2(); // 1234
Run Code Online (Sandbox Code Playgroud)
Max*_*mus 22
你可以使用Symbol
var say = Symbol()
function Cat(){
this[say]() // call private methos
}
Cat.prototype[say] = function(){ alert('im a private') }
Run Code Online (Sandbox Code Playgroud)
PS alexpods不正确.他得到保护而不是私人,因为继承是名称冲突
实际上你可以使用var say = String(Math.random())
Symbol代替
在ES6中:
var say = Symbol()
class Cat {
constructor(){
this[say]() // call private
}
[say](){
alert('im private')
}
}
Run Code Online (Sandbox Code Playgroud)
Son*_*gHo 14
我希望这会有所帮助.:)
I.声明vars,IIFE内部的函数(立即调用函数表达式),这些函数只能在匿名函数中使用.(当您需要更改ES6的代码时,不使用'var'就可以使用"let,const"关键字.)
let Name = (function() {
const _privateHello = function() {
}
class Name {
constructor() {
}
publicMethod() {
_privateHello()
}
}
return Name;
})();
Run Code Online (Sandbox Code Playgroud)
II.WeakMap对象可以很好地解决内存漏洞问题.
将删除实例时,将删除WeakMap中的存储变量.看看这篇文章.(管理ES6类的私有数据)
let Name = (function() {
const _privateName = new WeakMap();
})();
Run Code Online (Sandbox Code Playgroud)
III.让我们把所有的东西放在一起.
let Name = (function() {
const _privateName = new WeakMap();
const _privateHello = function(fullName) {
console.log("Hello, " + fullName);
}
class Name {
constructor(firstName, lastName) {
_privateName.set(this, {firstName: firstName, lastName: lastName});
}
static printName(name) {
let privateName = _privateName.get(name);
let _fullname = privateName.firstName + " " + privateName.lastName;
_privateHello(_fullname);
}
printName() {
let privateName = _privateName.get(this);
let _fullname = privateName.firstName + " " + privateName.lastName;
_privateHello(_fullname);
}
}
return Name;
})();
var aMan = new Name("JH", "Son");
aMan.printName(); // "Hello, JH Son"
Name.printName(aMan); // "Hello, JH Son"
Run Code Online (Sandbox Code Playgroud)
正如alexpods所说,在ES6中没有专门的方法来做到这一点.但是,对于那些感兴趣的人,还有一个绑定运算符的提议,它启用了这种语法:
function privateMethod() {
return `Hello ${this.name}`;
}
export class Animal {
constructor(name) {
this.name = name;
}
publicMethod() {
this::privateMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
再一次,这只是一个提案.你的旅费可能会改变.
你考虑过使用工厂功能吗?它们通常是Javascript中类或构造函数的更好的替代品.以下是它的工作原理示例:
function car () {
var privateVariable = 4
function privateFunction () {}
return {
color: 'red',
drive: function (miles) {},
stop: function() {}
....
}
}
Run Code Online (Sandbox Code Playgroud)
由于闭包,您可以访问返回对象内的所有私有函数和变量,但您无法从外部访问它们.
我想出了我认为更好的解决方案,允许:
不需要“this._”、that/self、weakmaps、symbols 等。清晰直接的“类”代码
私有变量和方法是真正私有的,并且具有正确的“this”绑定
根本不使用“this”,这意味着代码清晰,不易出错
公共接口清晰,并且作为私有方法的代理与实现分离
允许轻松组合
有了这个,你可以这样做:
function Counter() {
// public interface
const proxy = {
advance, // advance counter and get new value
reset, // reset value
value // get value
}
// private variables and methods
let count=0;
function advance() {
return ++count;
}
function reset(newCount) {
count=(newCount || 0);
}
function value() {
return count;
}
return proxy;
}
let counter=Counter.New();
console.log(counter instanceof Counter); // true
counter.reset(100);
console.log('Counter next = '+counter.advance()); // 101
console.log(Object.getOwnPropertyNames(counter)); // ["advance", "reset", "value"]
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.rawgit.com/kofifus/New/7987670c/new.js"></script>
Run Code Online (Sandbox Code Playgroud)
请参阅新代码和更详细的示例,包括构造函数和组合
归档时间: |
|
查看次数: |
185223 次 |
最近记录: |