ES6中的访问修饰符(私有,受保护) [英] Access Modifiers (Private, Protected) in ES6

查看:1319
本文介绍了ES6中的访问修饰符(私有,受保护)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我已经通过了以下关于符号,WeekMaps和Maps,请在投票前阅读完整的问题: JavaScript ES6类中的私有属性

文章: https://esdiscuss.org/topic/es7-property-initializers


以下是我的简单类其中包含私有,公共和受保护的属性和方法。



 'use strict'; class MyClass {constructor(){this.publicVar ='This is Public Variable'; this.privateVar ='这是私有变量'; this.protectedVar ='这是受保护的变量'; } //公共构造方法。 publicMethod(){console.log('accessing this.publicVar:',this.publicVar); console.log('accessing this.privateVar:',this.privateVar); console.log('accessing this.protectedVar:',this.protectedVar); return'它的公共方法'} //公共方法。 privateMethod(){return'它的私有方法'} //私有方法。 protectedMethod(){return'Its Protected Method'} //受保护的方法。 foo(){this.publicMethod(); this.privateMethod(); this.protectedMethod(); } //公共方法} // end class  



实例化对象并调用正常工作的公共方法。

 让MyObject = new MyClass; 
MyObject.foo(); // 工作正常。
console.log(MyObject.publicVar); // Works
console.log(MyObject.publicMethod()); // Works




按预期工作。


现在我的问题。我知道几个像Symbol在ES6规范中的东西,目前在ES6类上获得受保护和私有变量/方法的方法是什么?

  console.log(MyObject.privateVar); // Works 
console.log(MyObject.privateMethod()); // Works




我希望此属性和方法仅在自己的类。




  console.log(MyObject.protectedVar); // Works 
console.log(MyObject.protectedMethod()); // Works




我希望此属性和方法在其中可见自己的类和内部类扩展它。


解决方法/更好的解决方案来实现这种行为是欣赏

解决方案

私有属性



在ES6(和之前)实施依赖于关闭



人们一直在做这个,甚至在JavaScript有版本之前。
WeakMap只是一种变体,可以以访问速度为代价消除对每个新对象的新范围和新功能的需求。



符号是ES6变体它隐藏了常见操作的属性,例如简单的属性访问或中的



  var MyClass;(()=> {//定义私有属性的作用域符号A. const PropA = Symbol('A'); //定义类一旦我们有所有符号MyClass = class {someFunction(){return我可以读+这个[PropA]; //访问私有属性}} MyClass.prototype [PropA] ='私有属性或方法';}) ); //函数中的闭包可以访问私有的property.var myObject = new MyClass(); alert(myObject.someFunction()); //但是我们不能重新创建外部的符号。 (myObject [Symbol('A')]); // undefined //但是如果有人*真的必须访问它... var symbols = Object.getOwnPropertySymbols(myObject .__ proto__); alert(myObject [symbols [0]]);  



如上所述,它可以通过 Object.getOwnPropertySymbols()
尽管存在,我总是在WeakMap上选择符号。
代码更干净,更简单,更少gc工作,(我认为)更有效率。


我个人避免 class 也是。 Object.create 简单得多。但是这超出了范围。







受保护的属性



受保护的属性本质上要求执行函数来知道调用代码的对象,以判断是否应该被允许访问。



这在JS中是不可能的,而不是因为ES6具有没有真正的类,但是因为调用者上下文根本不可用



由于各种 特殊 natures of JavaSc ript,在可预见的未来保护财产仍然是不可能的。



另外...








某些语言具有半保护属性,有时称为包私有,其中可以在同一模块/包中的成员访问方法/属性。



ES6可以实现它关闭。
它与上面的私有属性代码完全相同 - 只是分享了多个原型的范围和符号。



但这是不切实际的,因为这需要整个模块在相同的封闭范围内定义,即在单个文件中。
但是这是一个选择。


Note: I already went through the below SO Question and 7 Answers (as of now) about Symbols, WeekMaps and Maps, Please read the full question before you vote: Private properties in JavaScript ES6 classes
Article: https://esdiscuss.org/topic/es7-property-initializers

Below is my Simple Class which contains Private, Public and Protected Properties and Methods.

  'use strict';
  class MyClass {
    constructor () {
      this.publicVar = 'This is Public Variable';
      this.privateVar = 'This is Private Variable';
      this.protectedVar = 'This is Protected Variable';
    } // Public Constructor Method.
    
    publicMethod () {
      console.log('   Accessing this.publicVar: ', this.publicVar);
      console.log('   Accessing this.privateVar: ', this.privateVar);
      console.log('   Accessing this.protectedVar: ', this.protectedVar);
      return 'Its Public Method'
    } // Public Method.

    privateMethod () {return 'Its Private Method'} // Private Method.
    protectedMethod () {return 'Its Protected Method'} // Protected Method.

    foo () {
      this.publicMethod();
      this.privateMethod();
      this.protectedMethod();
    } // Public Method
  } // end class

I'm instantiating the Object and calling the public method which is working as expected.

let MyObject = new MyClass;
MyObject.foo(); // Works fine.
console.log( MyObject.publicVar ); // Works
console.log( MyObject.publicMethod() ); // Works

Working as expected.

Now my question. I'm aware few things like Symbol are in the ES6 specification, what is the current workaround to get protected and private variables/methods working on ES6 classes.

console.log( MyObject.privateVar ); // Works
console.log( MyObject.privateMethod() ); // Works

I want this property and method to be visible only in its own class.

console.log( MyObject.protectedVar ); // Works
console.log( MyObject.protectedMethod() ); // Works

I want this property and method to be visible in its own class and inside classes extending it.

Workaround / better solution to achieve this behavior is appreciated

解决方案

Private properties

In ES6 (and before), all private property implementations rely on closure.

People have been doing it even before JavaScript has versions. WeakMap is just a variation that removes the need of new scope and new functions for each new object, at cost of access speed.

Symbol is a ES6 variation that hides the attribute from common operations, such as simple property access or for in.

var MyClass;
( () => {
  // Define a scoped symbol for private property A.
  const PropA = Symbol( 'A' );
  // Define the class once we have all symbols
  MyClass = class {
    someFunction () {
      return "I can read " + this[ PropA ]; // Access private property
    }
  }
  MyClass.prototype[ PropA ] = 'Private property or method';
})();

// function in the closure can access the private property.
var myObject = new MyClass();
alert( myObject.someFunction() );

// But we cannot "recreate" the Symbol externally.
alert( myObject[ Symbol( 'A' ) ] ); // undefined

// However if someone *really* must access it...
var symbols = Object.getOwnPropertySymbols( myObject.__proto__ );
alert( myObject[ symbols[ 0 ] ] );

As seen above, it can be worked around by Object.getOwnPropertySymbols(). Despite its existence, I always choice symbol over WeakMap. The code is cleaner, simpler, less gc work, and (I think) more efficient.

I personally avoid class, too. Object.create is much simpler. But that is out of scope.


Protected properties

Protected properties, by its nature, requires executing function to know the object of the calling code, to judge whether it should be granted access.

This is impossible in JS, not because ES6 has no real class, but because caller context is simply unavailable.

Due to various special natures of JavaScript, for the foreseeable future protected properties shall remain impossible.

Alternatively...


Package properties

Some languages have semi-protected properties, sometimes called "package private", where the method / property is accessible to members in the same module / package.

ES6 can implement it with closure. It is exactly the same as the private property code above - just share the scope and its symbols with multiple prototypes.

But this is impractical, since this requires that the whole module be defined under same closed scope, i.e. in a single file. But it is an option nonetheless.

这篇关于ES6中的访问修饰符(私有,受保护)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆