জাভাস্ক্রিপ্ট ES6 ক্লাসে ব্যক্তিগত সম্পত্তি


444

ES6 ক্লাসে ব্যক্তিগত সম্পত্তি তৈরি করা কি সম্ভব?

এখানে একটি উদাহরণ। আমি কীভাবে অ্যাক্সেস রোধ করতে পারি instance.property?

class Something {
  constructor(){
    this.property = "test";
  }
}

var instance = new Something();
console.log(instance.property); //=> "test"

5
বাস্তবে এমন কোনো পর্যায় 3 প্রস্তাব এই বৈশিষ্ট্যের জন্য হয় - tc39.github.io/proposal-class-fields github.com/tc39/proposal-class-fields
Arty

@arty আমি উদাহরণগুলির সাথে এর জবাব দিয়েছি: stackoverflow.com/a/52237988/1432509
11:20

উত্তর:


165

ইসিএমএ স্ট্যান্ডার্ডে ব্যক্তিগত ক্ষেত্রগুলি (এবং পদ্ধতি) প্রয়োগ করা হচ্ছে । আপনি আজ এগুলিকে ব্যাবেল 7 এবং স্টেজ 3 প্রিসেট দিয়ে ব্যবহার শুরু করতে পারেন ।

class Something {
  #property;

  constructor(){
    this.#property = "test";
  }

  #privateMethod() {
    return 'hello world';
  }

  getPrivateMessage() {
      return this.#privateMethod();
  }
}

const instance = new Something();
console.log(instance.property); //=> undefined
console.log(instance.privateMethod); //=> undefined
console.log(instance.getPrivateMessage()); //=> hello world

আমি ভাবছি কীভাবে এই শ্রেণীর ক্ষেত্রগুলি কাজ করতে পারে। আপনি thisকল করার আগে আপনি বর্তমানে কনস্ট্রাক্টর ব্যবহার করতে পারবেন না super()। তবুও বাবেল তাদের সুপারের সামনে রাখে।
সন্ধানকারী_আফ_ব্যাকন

#privateCrapসিনট্যাক্সের অনুমতি দেওয়ার জন্য কীভাবে ESLint কনফিগার করবেন ?
মেরেকি

6
আর এসলিন্টের কী হবে? আমি সমান চিহ্নতে পার্সার ত্রুটি পেয়েছি। ব্যাবেল কাজ করছে, কেবল এসলিন্ট এই নতুন জেএস সিনট্যাক্সটিকে পার্স করতে পারে না।
মার্টনক্স

6
বাহ এটা খুব কুরুচিপূর্ণ। হ্যাশট্যাগ একটি বৈধ চরিত্র। সম্পত্তিটি কি আসলেই ব্যক্তিগত নয়, নাকি? ..আমি এটি টাইপস্ক্রিপ্টে পরীক্ষা করেছি। ব্যক্তিগত সদস্যরা ব্যক্তিগত বা পঠনযোগ্য (কেবল বাইরে থেকে) সংকলিত হয় না। সবেমাত্র অন্য (জন) সম্পত্তি হিসাবে ঘোষিত। (ES5)।
ডোমিনিক

2
এটি দিয়ে আপনি কীভাবে ব্যক্তিগত পদ্ধতি লিখবেন ? আমি এই কাজ করতে পারে না: #beep() {}; এবং এই async #bzzzt() {}:?
Ван

277

সংক্ষিপ্ত উত্তর, না, ES6 ক্লাস সহ ব্যক্তিগত সম্পত্তিগুলির জন্য কোনও দেশীয় সমর্থন নেই।

তবে আপনি সেই আচরণটি নতুন বস্তুর সাথে সংযুক্ত না করে ক্লাস কন্সট্রাক্টরের ভিতরে রেখে, এবং গোপনীয় বৈশিষ্ট্যগুলিতে পৌঁছানোর জন্য গেটর এবং সেটটার ব্যবহার করে নকল করতে পারেন। নোট করুন যে গেটার এবং সেটটাররা ক্লাসের প্রতিটি নতুন ইভেন্টে নতুন সংজ্ঞা দেয়।

ES6

class Person {
    constructor(name) {
        var _name = name
        this.setName = function(name) { _name = name; }
        this.getName = function() { return _name; }
    }
}

ES5

function Person(name) {
    var _name = name
    this.setName = function(name) { _name = name; }
    this.getName = function() { return _name; }
}

1
আমি এই সমাধানটি সবচেয়ে পছন্দ করি। আমি সম্মত হই যে এটি স্কেলিংয়ের জন্য ব্যবহার করা উচিত নয় তবে এটি এমন ক্লাসগুলির জন্য উপযুক্ত যা সাধারণত অন্তর্ভুক্ত অন্তর্ভুক্ত একবার একবার ইনস্ট্যান্ট করা হবে।
ব্লেক রেগালিয়া

2
এছাড়াও প্রতিবার নতুন তৈরি হওয়ার সময় আপনি এই শ্রেণীর প্রতিটি উপাদানকে নতুন করে সংজ্ঞায়িত করছেন।
কোয়ান্টিন রায়

10
এটি খুব অস্বাভাবিক! ES6 এ আপনি ES6 এর চেয়ে বেশি "ক্লোজার পিরামিড" তৈরি করছেন! উপরোক্ত ES5 উদাহরণের চেয়ে কোনও কনস্ট্রাক্টরের সাথে কার্যকারিতা সংজ্ঞায়িত করা দেখতে আরও খারাপ দেখায়।
কোকোডোকো

1
যেহেতু ওপি বিশেষত ES6 ক্লাস সম্পর্কে জিজ্ঞাসা করে, আমি ব্যক্তিগতভাবে মনে করি এটি প্রযুক্তিগতভাবে কাজ করা সত্ত্বেও এটি একটি দুর্বল সমাধান। প্রধান সীমাবদ্ধতা হ'ল এখন প্রতিটি শ্রেণিবদ্ধতি যা প্রাইভেট ভেরিয়েবল ব্যবহার করে তা অবশ্যই কনস্ট্রাক্টরের অভ্যন্তরে ঘোষণা করতে হবে, classসিন্টেক্সের প্রথম স্থানে থাকা সুবিধারগুলি গুরুতরভাবে ক্ষুন্ন করে ।
ন্যানো উইজার্ড

10
এই সমস্ত কাজ ইন্ডিয়ারেশন পরিচয় করিয়ে দেওয়া হয়। এখন আপনি কীভাবে সম্পত্তি getNameএবং setNameসম্পত্তি ব্যক্তিগত করবেন?
এআইজ

195

@ লোগানফস্মিথের উত্তরে প্রসারিত করতে:

জাভাস্ক্রিপ্টের একমাত্র সত্যিকারের ব্যক্তিগত ডেটা এখনও স্কেপড ভেরিয়েবল। অভ্যন্তরীণভাবে পাবলিক প্রোপার্টি হিসাবে একইভাবে অ্যাক্সেস করা সম্পত্তি হিসাবে আপনি ব্যক্তিগত সম্পত্তি রাখতে পারবেন না তবে আপনি ব্যক্তিগত ডেটা সঞ্চয় করতে স্কোপড ভেরিয়েবল ব্যবহার করতে পারেন।

স্কোপড ভেরিয়েবল

এখানে পদ্ধতিরটি হ'ল কনস্ট্রাক্টর ফাংশনের স্কোপটি প্রাইভেট ডেটা সংরক্ষণ করার জন্য ব্যবহার করা। পদ্ধতিগুলিতে এই ব্যক্তিগত ডেটাতে অ্যাক্সেস পাওয়ার জন্য সেগুলি অবশ্যই নির্মাণকারীর মধ্যেই তৈরি করতে হবে, অর্থাত আপনি তাদের প্রতিটি ইভেন্টের সাথে পুনরায় তৈরি করছেন। এটি একটি পারফরম্যান্স এবং মেমরির জরিমানা, তবে কেউ কেউ বিশ্বাস করেন যে এই দণ্ডটি গ্রহণযোগ্য। প্রোটোটাইপটিতে যথারীতি যুক্ত করে ব্যক্তিগত ডেটাতে অ্যাক্সেসের প্রয়োজন না এমন পদ্ধতির জন্য জরিমানা এড়ানো যেতে পারে।

উদাহরণ:

function Person(name) {
  let age = 20; // this is private
  this.name = name; // this is public

  this.greet = function () {
    // here we can access both name and age
    console.log(`name: ${this.name}, age: ${age}`);
  };
}

let joe = new Person('Joe');
joe.greet();

// here we can access name but not age

Scoped WeakMap

পূর্ববর্তী পদ্ধতির কর্মক্ষমতা এবং মেমরির জরিমানা এড়াতে একটি WeakMap ব্যবহার করা যেতে পারে। WeakMaps অবজেক্টের সাথে ডেটা সংযুক্ত করে (এখানে উদাহরণস্বরূপ) যাতে কেবলমাত্র সেই WeakMap ব্যবহার করে অ্যাক্সেস করা যায়। সুতরাং, আমরা একটি ব্যক্তিগত ওয়েকম্যাপ তৈরি করতে স্কোপযুক্ত ভেরিয়েবল পদ্ধতিটি ব্যবহার করি, তারপরে এর সাথে সম্পর্কিত ব্যক্তিগত ডেটা পুনরুদ্ধারে সেই WeakMap ব্যবহার করি this। এটি স্কোপড ভেরিয়েবল পদ্ধতির চেয়ে দ্রুততর কারণ আপনার সমস্ত দৃষ্টান্ত একটি একক উইকম্যাপ ভাগ করে নিতে পারে, তাই কেবল তাদের নিজস্ব ওয়েকম্যাপগুলিতে অ্যাক্সেস তৈরি করার জন্য আপনাকে পদ্ধতিগুলি পুনরায় তৈরি করতে হবে না।

উদাহরণ:

let Person = (function () {
  let privateProps = new WeakMap();

  class Person {
    constructor(name) {
      this.name = name; // this is public
      privateProps.set(this, {age: 20}); // this is private
    }

    greet() {
      // Here we can access both name and age
      console.log(`name: ${this.name}, age: ${privateProps.get(this).age}`);
    }
  }

  return Person;
})();

let joe = new Person('Joe');
joe.greet();

// here we can access joe's name but not age

এই উদাহরণটি একাধিক ব্যক্তিগত সম্পত্তিগুলির জন্য একটি ওয়েকম্যাপ ব্যবহার করতে একটি অবজেক্ট ব্যবহার করে; আপনি একাধিক WeakMaps ব্যবহার করতে পারেন এবং তাদের পছন্দ মতো ব্যবহার করতে পারেন age.set(this, 20), বা একটি ছোট মোড়ক লিখতে এবং এটি অন্যভাবে ব্যবহার করতে পারেন, পছন্দ করুন privateProps.set(this, 'age', 0)

এই পদ্ধতির গোপনীয়তা তাত্ত্বিকভাবে গ্লোবাল WeakMapঅবজেক্টের সাথে হস্তক্ষেপের মাধ্যমে লঙ্ঘন হতে পারে । এটি বলেছিল যে সমস্ত জাভাস্ক্রিপ্ট ম্যাংড গ্লোবালগুলি দ্বারা ভেঙে যেতে পারে। আমাদের কোডটি ইতিমধ্যে এই ধারনাটিতে তৈরি করা হয়েছে যে এটি হচ্ছে না।

(এই পদ্ধতিটি দিয়েও করা যেতে পারে Mapতবে WeakMapএটি আরও ভাল কারণ Mapআপনি খুব যত্নবান না হলে মেমরি ফাঁস তৈরি করবে এবং এই উদ্দেশ্যে দুটি অন্যথায় আলাদা না হয় different)

অর্ধ-উত্তর: স্কোপড প্রতীকগুলি

একটি প্রতীক একটি ধরণের আদিম মান যা কোনও সম্পত্তির নাম হিসাবে পরিবেশন করতে পারে। আপনি একটি ব্যক্তিগত প্রতীক তৈরি করতে স্কোপযুক্ত ভেরিয়েবল পদ্ধতিটি ব্যবহার করতে পারেন, তারপরে ব্যক্তিগত ডেটা সঞ্চয় করতে পারেন this[mySymbol]

এই পদ্ধতির গোপনীয়তাটি ব্যবহার করে লঙ্ঘন করা যায় Object.getOwnPropertySymbolsতবে এটি করা কিছুটা বিশ্রী।

উদাহরণ:

let Person = (function () {
  let ageKey = Symbol();

  class Person {
    constructor(name) {
      this.name = name; // this is public
      this[ageKey] = 20; // this is intended to be private
    }

    greet() {
      // Here we can access both name and age
      console.log(`name: ${this.name}, age: ${this[ageKey]}`);
    }
  }

  return Person;
})();

let joe = new Person('Joe');
joe.greet();

// Here we can access joe's name and, with a little effort, age. ageKey is
// not in scope, but we can obtain it by listing all Symbol properties on
// joe with `Object.getOwnPropertySymbols(joe)`.

অর্ধ-উত্তর: বোঝে

পুরানো ডিফল্ট, কেবল একটি আন্ডারস্কোর উপসর্গ সহ একটি সর্বজনীন সম্পত্তি ব্যবহার করুন। যদিও কোনও উপায়ে ব্যক্তিগত সম্পত্তি না হলেও এই সম্মেলনটি যথেষ্ট প্রচলিত যে এটি একটি ভাল কাজ করে যা পাঠকদের সেই সম্পত্তিটিকে ব্যক্তিগত হিসাবে বিবেচনা করা উচিত, যা প্রায়শই কাজটি হয়ে যায়। এই ল্যাপসটির বিনিময়ে, আমরা এমন একটি পন্থা পাই যা পড়া সহজ, টাইপ করা সহজ এবং দ্রুত।

উদাহরণ:

class Person {
  constructor(name) {
    this.name = name; // this is public
    this._age = 20; // this is intended to be private
  }

  greet() {
    // Here we can access both name and age
    console.log(`name: ${this.name}, age: ${this._age}`);
  }
}

let joe = new Person('Joe');
joe.greet();

// Here we can access both joe's name and age. But we know we aren't
// supposed to access his age, which just might stop us.

উপসংহার

ES2017 হিসাবে, এখনও ব্যক্তিগত সম্পত্তিগুলি করার কোনও সঠিক উপায় নেই। বিভিন্ন পদ্ধতির বিভিন্ন উপকারিতা রয়েছে cons স্কোপড ভেরিয়েবলগুলি সত্যই ব্যক্তিগত; স্কোপড ওয়েকম্যাপগুলি স্কোপড ভেরিয়েবলের চেয়ে খুব ব্যক্তিগত এবং আরও ব্যবহারিক; স্কোপযুক্ত প্রতীকগুলি যথাযথভাবে ব্যক্তিগত এবং যুক্তিসঙ্গতভাবে ব্যবহারিক; আন্ডারস্কোরগুলি প্রায়শই যথেষ্ট ব্যক্তিগত এবং খুব ব্যবহারিক।


7
প্রথম উদাহরণ স্নিপেট ("স্কোপড ভেরিয়েবল") একটি মোট অ্যান্টিপ্যাটার্ন - প্রতিটি প্রত্যাবর্তিত বস্তুর আলাদা ক্লাস থাকবে have এটা করবেন না। যদি আপনি সুবিধাপ্রাপ্ত পদ্ধতিগুলি চান তবে সেগুলি কনস্ট্রাক্টারে তৈরি করুন।
বার্জি

1
কোনও ফাংশনের অভ্যন্তরে কোনও শ্রেণি আবদ্ধ করা প্রথম শ্রেণিতে ক্লাস ব্যবহারের পুরো উদ্দেশ্যকে পরাস্ত করে বলে মনে হচ্ছে। আপনি যদি ইতিমধ্যে কোনও দৃষ্টান্ত তৈরি করতে এই ফাংশনটি ব্যবহার করেন তবে আপনি আপনার সমস্ত প্রাইভেট / পাবলিক সদস্যকে সেই ফাংশনের ভিতরেও রেখে দিতে পারেন এবং পুরো শ্রেণীর কীওয়ার্ডটি ভুলে যেতে পারেন।
কোকোডোকো

2
@ বার্গি @ কোকোডোকো আমি স্কোপড ভেরিয়েবল পদ্ধতির সম্পাদনা করেছি যাতে কিছুটা দ্রুত হয় এবং না ব্রেক instanceof। আমি স্বীকার করি যে আমি সেই পদ্ধতির কথা ভাবছিলাম যেহেতু কেবলমাত্র সম্পূর্ণতার জন্যই অন্তর্ভুক্ত ছিল এবং এটি আসলে কতটা সক্ষম তা নিয়ে আরও চিন্তা করা উচিত ছিল।
ত্রিস্তান

1
দুর্দান্ত ব্যাখ্যা! আমি এখনও অবাক হয়েছি যে ES6 আসলে একটি প্রাইভেট ভেরিয়েবল সিমুলেট করা আরও শক্ত করে তোলে, যেখানে ES5 এ আপনি প্রাইভেট এবং পাবলিক সিমুলেট করার জন্য একটি ফাংশনের ভিতরে কেবল ভের এবং এটি ব্যবহার করতে পারেন।
কোকোডোকো

2
@ কোকোডোকো যদি আপনি ক্লাসটি সরবরাহ করেন এবং সবকিছুতে ফাংশনটিতে রাখেন তবে আপনাকে প্রোটোটাইপ পদ্ধতি ব্যবহার করে উত্তরাধিকার বাস্তবায়নেও ফিরে যেতে হবে। ক্লাসে প্রসারিত ব্যবহার করা এখন পর্যন্ত একটি পরিষ্কার পদ্ধতি, সুতরাং কোনও ফাংশনের অভ্যন্তরে একটি শ্রেণি ব্যবহার করা সম্পূর্ণ গ্রহণযোগ্য।
অ্যান্ড্রয়েড ডেভ

117

আপডেট: ভাল সিনট্যাক্স সহ একটি প্রস্তাব চলেছে । অবদানসমূহ স্বাগত।


হ্যাঁ, অবজেক্টগুলিতে স্কোপড অ্যাক্সেসের জন্য রয়েছে - ES6 Symbols এর প্রবর্তন করে

প্রতীকগুলি অনন্য, আপনি প্রতিবিম্ব ছাড়া (বাইরে জাভা / সি # তে বেসরকারীদের মতো) বাইরে থেকে একটিতে অ্যাক্সেস অর্জন করতে পারবেন না তবে যার অভ্যন্তরে কোনও প্রতীক অ্যাক্সেস রয়েছে সে কী কী অ্যাক্সেসের জন্য এটি ব্যবহার করতে পারে:

var property = Symbol();
class Something {
    constructor(){
        this[property] = "test";
    }
}

var instance = new Something();

console.log(instance.property); //=> undefined, can only access with access to the Symbol

6
আপনি ব্যবহার করতে পারবেন না Object.getOwnPropertySymbols? ;)
কোয়ান্টাস 94 ভারী

41
: @BenjaminGruenbaum: দৃশ্যত প্রতীক আর সত্য গোপনীয়তা নিশ্চিত stackoverflow.com/a/22280202/1282216
D13

28
@ থ্রস্ক্র্ট থ্রিজ কী দিয়ে? না? প্রতীকগুলির মাধ্যমে? হ্যাঁ. ব্যক্তিগত ক্ষেত্রগুলিতে অ্যাক্সেস করতে আপনি কীভাবে সি # এবং জাভা এর মতো ভাষাগুলিতে প্রতিবিম্বটি ব্যবহার করতে পারেন তা খুব পছন্দ। অ্যাক্সেস মডিফায়ারগুলি সুরক্ষা সম্পর্কে নয় - এগুলি উদ্দেশ্যটির স্পষ্টতা সম্পর্কে।
বেনিয়ামিন গ্রুইনবাউম

9
দেখে মনে হচ্ছে সিম্বলগুলি ব্যবহার করাও একই রকম const myPrivateMethod = Math.random(); Something.prototype[''+myPrivateMethod] = function () { ... } new Something()[''+myPrivateMethod]();traditional আমি "ব্যক্তিগত" জাভাস্ক্রিপ্ট বিবেচনা করব ভেরিয়েবলগুলি encapsulate করতে ক্লোজার ব্যবহার করে বোঝাতে। সেই পরিবর্তনগুলি প্রতিবিম্বের মাধ্যমে অ্যাক্সেসযোগ্য নয়।
trusktr

13
এছাড়াও, আমি মনে করি ব্যবহার privateএবং protectedকীওয়ার্ড চেয়ে এত ক্লিনার হবে Symbolবা Name। আমি বন্ধনী চিহ্নিতকরণের চেয়ে ডট স্বরলিপি পছন্দ করি। আমি ব্যক্তিগত জিনিসগুলির জন্য একটি বিন্দু ব্যবহার চালিয়ে যেতে চাই। this.privateVar
trusktr

33

উত্তরটি "না"। তবে আপনি এই জাতীয় বৈশিষ্ট্যে ব্যক্তিগত অ্যাক্সেস তৈরি করতে পারেন:

  • মডিউল ব্যবহার করুন। মূলশব্দটি ব্যবহার করে সর্বজনীন না করা হলে মডিউলের সমস্ত কিছু ব্যক্তিগত export
  • মডিউলগুলির অভ্যন্তরে, ফাংশন বন্ধ ব্যবহার করুন : http://www.kirupa.com/html5/closures_in_javascript.htm

(গোপনীয়তা নিশ্চিত করতে সিম্বলগুলি ব্যবহার করা যেতে পারে এমন পরামর্শ ES6 টি অনুমানের পূর্ববর্তী সংস্করণে সত্য ছিল তবে এটি আর নেই: https://mail.mozilla.org/pipermail/es-discuss/2014- জানুয়ারী/035604 । এইচটিএমএল এবং https://stackoverflow.com/a/22280202/1282216 । চিহ্ন এবং গোপনীয়তা সম্পর্কে দীর্ঘ আলোচনার জন্য দেখুন: https://curiosity-driven.org/private-properties-in-javascript )


6
-1, এটি আপনার প্রশ্নের সত্যই উত্তর দেয় না। (আপনি ES5 তে IIFE এর সাথে ক্লোজারগুলিও ব্যবহার করতে পারেন)। বেশিরভাগ ভাষায় (জাভা, সি # ইত্যাদি) প্রতিবিম্বের মাধ্যমে ব্যক্তিগত সম্পত্তিগুলি গণনাযোগ্য। ব্যক্তিগত সম্পত্তিগুলির বিষয়টি হ'ল অন্যান্য অগ্রগামীদের উদ্দেশ্যে অভিপ্রায় জানানো এবং সুরক্ষা কার্যকর করা নয়।
বেনিয়ামিন গ্রুইনবাউম

1
@ বেঞ্জামিন গ্রুয়েনবাউম, আমি জানি, আমি আশা করি আমার আরও ভাল উত্তর পেলে আমিও এতে খুশি নই।
d13

আমি মনে করি প্রোগ্রামিং পরিবেশে থাকা অবস্থায় অ্যাক্সেসযোগ্য সদস্যদের অর্জনের জন্য চিহ্নগুলি এখনও একটি বৈধ উপায়। হ্যাঁ, আপনি যদি রিয়েললি চান তবে সেগুলি এখনও পাওয়া যাবে, তবে এটি কি তা নয়? আপনার এতে সংবেদনশীল তথ্য সংরক্ষণ করা উচিত নয়, তবে ক্লায়েন্ট-সাইড কোডে আপনার এটি করা উচিত নয়। তবে এটি কোনও বহিরাগত শ্রেণি থেকে সম্পত্তি বা পদ্ধতি লুকানোর উদ্দেশ্যে কাজ করে works
কোকোডোকো

শ্রেণীর ব্যক্তিগত সম্পত্তিগুলির বিকল্প হিসাবে মডিউলের স্তরে স্কোপযুক্ত ভেরিয়েবলগুলি ব্যবহার করা একক একক আচরণ করবে বা স্ট্যাটিক বৈশিষ্ট্যের সাথে আচরণের অনুরূপ behavior
অ্যাড্রিয়ান মোইসা

30

জেএসে সত্যিকারের গোপনীয়তা পাওয়ার একমাত্র উপায় হ'ল স্কোপিংয়ের মাধ্যমে, তাই এমন কোনও সম্পত্তি রাখার উপায় নেই যা এর সদস্য এটি thisকেবলমাত্র উপাদানটির ভিতরে প্রবেশযোগ্য হবে। ES6- এ সত্যই ব্যক্তিগত ডেটা সঞ্চয় করার সর্বোত্তম উপায় হ'ল একটি উইকম্যাপ।

const privateProp1 = new WeakMap();
const privateProp2 = new WeakMap();

class SomeClass {
  constructor() {
    privateProp1.set(this, "I am Private1");
    privateProp2.set(this, "I am Private2");

    this.publicVar = "I am public";
    this.publicMethod = () => {
      console.log(privateProp1.get(this), privateProp2.get(this))
    };        
  }

  printPrivate() {
    console.log(privateProp1.get(this));
  }
}

স্পষ্টতই এটি সম্ভবত ধীর এবং নিশ্চিতভাবেই কুৎসিত তবে এটি গোপনীয়তা সরবরাহ করে।

মনে রাখবেন যে এটি কখনই নিখুঁত নয়, কারণ জাভাস্ক্রিপ্টটি এতটাই গতিশীল। কেউ এখনও করতে পারে

var oldSet = WeakMap.prototype.set;
WeakMap.prototype.set = function(key, value){
    // Store 'this', 'key', and 'value'
    return oldSet.call(this, key, value);
};

মানগুলি যেমন সংরক্ষণ করা থাকে সেগুলি ধরার জন্য, তাই যদি আপনি অতিরিক্ত সতর্কতা অবলম্বন করতে চান তবে আপনাকে ওভারডেবল প্রোটোটাইপের উপর নির্ভর করার পরিবর্তে একটি স্থানীয় রেফারেন্স ক্যাপচার করতে হবে .setএবং .getস্পষ্টভাবে ব্যবহার করতে হবে।

const {set: WMSet, get: WMGet} = WeakMap.prototype;

const privateProp1 = new WeakMap();
const privateProp2 = new WeakMap();

class SomeClass {
  constructor() {
    WMSet.call(privateProp1, this, "I am Private1");
    WMSet.call(privateProp2, this, "I am Private2");

    this.publicVar = "I am public";
    this.publicMethod = () => {
      console.log(WMGet.call(privateProp1, this), WMGet.call(privateProp2, this))
    };        
  }

  printPrivate() {
    console.log(WMGet.call(privateProp1, this));
  }
}

3
একটি পরামর্শ হিসাবে, আপনি সম্পত্তি হিসাবে মূল্য হিসাবে একটি বস্তু ব্যবহার করে একটি দুর্বল মানচিত্র ব্যবহার এড়াতে পারেন। এই পদ্ধতিতে আপনি getপ্রতি পদ্ধতিতে (যেমন const _ = privates.get(this); console.log(_.privateProp1);) মানচিত্রের সংখ্যা হ্রাস করতে পারেন ।
কোয়ান্টিন রায়

হ্যাঁ, এটিও পুরোপুরি একটি বিকল্প। আমি বেশিরভাগ ক্ষেত্রেই এর সাথে চলেছি যেহেতু এটি প্রকৃত বৈশিষ্ট্যগুলি ব্যবহার করার সময় কোনও ব্যবহারকারী কী লিখবে তা আরও সরাসরি মানচিত্র করে।
লোগানফস্মিথ

@loganfsmyth এর const myObj = new SomeClass(); console.log(privateProp1.get(myObj)) // "I am Private1"অর্থ আপনার সম্পত্তি ব্যক্তিগত বা না?
বারবু বার্বু

2
এটি কাজ করার জন্য, সম্পত্তিটিতে অ্যাক্সেস করার কোডটির জন্য ওয়েকম্যাপ অবজেক্টে অ্যাক্সেসের প্রয়োজন হবে যা সাধারণত মডিউলটির
ভিতরেই

22

লুকারগুলিতে অন্যের ভবিষ্যতের রেফারেন্সের জন্য, আমি এখন শুনছি যে ব্যক্তিগত ডেটা ধরে রাখতে WeakMaps ব্যবহার করার পরামর্শ দেওয়া হচ্ছে ।

এখানে আরও স্পষ্ট, কার্যকারী উদাহরণ:

function storePrivateProperties(a, b, c, d) {
  let privateData = new WeakMap;
  // unique object as key, weak map can only accept object as key, when key is no longer referened, garbage collector claims the key-value 
  let keyA = {}, keyB = {}, keyC = {}, keyD = {};

  privateData.set(keyA, a);
  privateData.set(keyB, b);
  privateData.set(keyC, c);
  privateData.set(keyD, d);

  return {
    logPrivateKey(key) {
      switch(key) {
      case "a":
        console.log(privateData.get(keyA));
        break;
      case "b":
        console.log(privateData.get(keyB));
        break;
      case "c":
        console.log(privateData.get(keyC));
        break;
      case "d":
        console.log(privateData.set(keyD));
        break;
      default:
        console.log(`There is no value for ${key}`)
      }
    }
  }
}

20
সচেতন থাকুন যে এই বৈশিষ্ট্যগুলি স্থিতিশীল।
মাইকেল থিয়েরিয়ট

8
আমি আপনাকে নিম্নচোটিত করি নি তবে আপনার দুর্বল চিত্রটি সম্পূর্ণ ভুল।
বেনিয়ামিন গ্রুইনবাউম

4
যথা - আপনি সমস্ত শ্রেণীর উদাহরণগুলির মধ্যে ডেটা ভাগ করছেন এবং উদাহরণ হিসাবে নয় - আমি কি কমপক্ষে এটি ঠিক করতে পারি?
বেনিয়ামিন গ্রুইনবাউম

1
প্রকৃতপক্ষে, দুর্বল মানচিত্রটি একটি নির্দিষ্ট দৃষ্টান্তের সাথে সংযুক্ত করা দরকার। উদাহরণস্বরূপ Fitzgeraldnick.com/weblog/53 দেখুন ।
অপরাহ্ন

2
এমডিএন অনুসারে, উইকম্যাপ কী হিসাবে সিম্বলসের মতো আদিম ডেটাগুলিকে অনুমোদিত নয়। MDN WeakMap ডকুমেন্টেশন
লিপওয়েল

12

আপনি যাকে জিজ্ঞাসা করেন তার উপর নির্ভর করে :-)

সর্বাধিক ন্যূনতম শ্রেণির প্রস্তাবনাতে কোনও privateসম্পত্তি সংশোধক অন্তর্ভুক্ত নেই যা মনে হয় এটি বর্তমান খসড়াতে তৈরি করেছে ।

তবে, ব্যক্তিগত নামগুলির জন্য সমর্থন থাকতে পারে , যা ব্যক্তিগত সম্পত্তিগুলিকে মঞ্জুরি দেয় - এবং সেগুলি সম্ভবত শ্রেণীর সংজ্ঞায়ও ব্যবহৃত হতে পারে।


3
এটা অত্যন্ত ES6 মধ্যে অসম্ভাব্য যে ব্যক্তিগত নাম করতে হবে, যেন তারা ES7 জন্য ব্যক্তিগত জিনিস কিছু ফর্ম নির্মাণ করে চলেছি চিন্তা।
কোয়ান্টাস 94 ভারী

@ কোয়ান্টাস 94 ব্যক্তিগত নাম এবং অনন্য স্ট্রিংয়ের মান উভয়ই আমি যা বুঝি তা থেকে প্রতীকগুলি ছাড়িয়ে যায়।
বেনিয়ামিন গ্রুইনবাউম

হ্যাঁ, এটি সম্ভবত প্রতীক হয়ে উঠবে। যাইহোক, আফকে বর্তমানে "স্পিডে থাকা" চিহ্নগুলি কেবলমাত্র [[প্রোটোটাইপ]] এর মতো অভ্যন্তরীণ বৈশিষ্ট্যগুলি বর্ণনা করতে ব্যবহৃত হয় এবং তাদের ব্যবহারকারীর কোডে তৈরি ও ব্যবহার করার কোনও উপায় নেই। আপনি কিছু ডক্স জানেন?
বার্গি

আমি কেবল বুঝতে পেরেছি যে গোপনীয়তা সেট করতে মডিউলগুলি ব্যবহার করা যেতে পারে। এমন প্রতীকগুলির সাথে একত্রিত যা আপনার প্রয়োজন হতে পারে এমন সমস্ত কিছু ...?
d13

1
@ কোডি: আপনার পুরো মডিউল কোডটির কোনওভাবেই ES6 এর নিজস্ব সুযোগ নেই, কোনও আইইএফইয়ের দরকার নেই। এবং হ্যাঁ, প্রতীকগুলি গোপনীয়তার জন্য নয়, স্বতন্ত্রতার জন্য (সংঘর্ষ-এড়ানো) for
বার্গি

10

ES6 মডিউল ব্যবহার (প্রাথমিকভাবে @ d13 দ্বারা প্রস্তাবিত) আমার পক্ষে ভাল কাজ করে। এটি ব্যক্তিগত সম্পত্তিগুলি নিখুঁতভাবে অনুকরণ করে না, তবে কমপক্ষে আপনি আত্মবিশ্বাসের সাথে বিশ্বাস রাখতে পারেন যে ব্যক্তিগত হওয়া সম্পত্তিগুলি আপনার শ্রেণির বাইরে ফুটো হবে না। এখানে একটি উদাহরণ:

something.js

let _message = null;
const _greet = name => {
  console.log('Hello ' + name);
};

export default class Something {
  constructor(message) {
    _message = message;
  }

  say() {
    console.log(_message);
    _greet('Bob');
  }
};

তারপরে গ্রাহক কোডটি দেখতে দেখতে এটি দেখতে পারেন:

import Something from './something.js';

const something = new Something('Sunny day!');
something.say();
something._message; // undefined
something._greet(); // exception

আপডেট (গুরুত্বপূর্ণ):

@ ড্যানিয়েল আয়েটকিন মন্তব্যে বর্ণিত হিসাবে, এই ব্যক্তিগত সম্পত্তিগুলি স্থিতিশীল, সুতরাং বিশ্বব্যাপী এর পরিধি। সিঙ্গলেটনের সাথে কাজ করার সময় তারা ভালভাবে কাজ করবে তবে ক্ষণস্থায়ী বস্তুর জন্য অবশ্যই যত্ন নেওয়া উচিত। উপরের উদাহরণটি প্রসারিত করা:

import Something from './something.js';
import Something2 from './something.js';

const a = new Something('a');
a.say(); // a

const b = new Something('b');
b.say(); // b

const c = new Something2('c');
c.say(); // c

a.say(); // c
b.say(); // c
c.say(); // c

4

@ ড্যানিয়েল আয়েটकिन: এটি একটি খুব ভাল বিষয়। এই ব্যক্তিগত সম্পত্তিগুলি স্থিতিশীল তাই বিশ্বব্যাপী। আমি এই প্রতিফলিত করতে আমার উত্তর আপডেট করেছি।
জনি ওশিকা

ফাংশনাল প্রোগ্রামিং (বিশেষত এলম এবং হাস্কেল) সম্পর্কে আমি যত বেশি শিখি ততই আমি বিশ্বাস করি যে জেএস প্রোগ্রামাররা ওওপি ক্লাস-ভিত্তিক না হয়ে মডিউল-ভিত্তিক "মডিউলারিটি" র পদ্ধতির মাধ্যমে উপকৃত হবে। যদি আমরা ES6 মডিউলগুলি অ্যাপ্লিকেশন তৈরির ভিত্তি হিসাবে মনে করি এবং ক্লাসগুলি সম্পূর্ণরূপে ভুলে যাই তবে আমি বিশ্বাস করি আমরা সামগ্রিকভাবে আরও অনেক ভাল অ্যাপ্লিকেশন দিয়ে শেষ করতে পারি। কোনও অভিজ্ঞ এলম বা হাস্কেল ব্যবহারকারী কি এই পদ্ধতির বিষয়ে মন্তব্য করতে পারেন?
d13

1
আপডেটে, দ্বিতীয়টি a.say(); // aহওয়া উচিতb.say(); // b
গ্রুককি

চেষ্টা করার let _message = nullউপায়, এত শীতল নয়, যখন কল কনস্ট্রাক্টরকে একাধিকবার কল করা হয়, তা গোলমাল হয়।
লিটল

9

@ ডি 13 এবং কমেন্টস @ জনি-ওশিকা এবং @ ড্যানিয়েল আয়েটকিনের মন্তব্য:

আমি অনুমান করি @ জহ্নি-ওশিকার দেওয়া উদাহরণে আমরা তীরের ফাংশনগুলির পরিবর্তে সাধারণ ফাংশন এবং তারপরে .bindবর্তমান অবজেক্ট প্লাস অবজেক্টের সাথে _privatesত্রি পরামিতি হিসাবে ব্যবহার করতে পারি:

something.js

function _greet(_privates) {
  return 'Hello ' + _privates.message;
}

function _updateMessage(_privates, newMessage) {
  _privates.message = newMessage;
}

export default class Something {
  constructor(message) {
    const _privates = {
      message
    };

    this.say = _greet.bind(this, _privates);
    this.updateMessage = _updateMessage.bind(this, _privates);
  }
}

main.js

import Something from './something.js';

const something = new Something('Sunny day!');

const message1 = something.say();
something.updateMessage('Cloudy day!');
const message2 = something.say();

console.log(message1 === 'Hello Sunny day!');  // true
console.log(message2 === 'Hello Cloudy day!');  // true

// the followings are not public
console.log(something._greet === undefined);  // true
console.log(something._privates === undefined);  // true
console.log(something._updateMessage === undefined);  // true

// another instance which doesn't share the _privates
const something2 = new Something('another Sunny day!');

const message3 = something2.say();

console.log(message3 === 'Hello another Sunny day!'); // true

আমি যে সুবিধাগুলি ভাবতে পারি:

  • আমাদের ব্যক্তিগত পদ্ধতি থাকতে পারে ( _greetএবং _updateMessageযতক্ষণ না আমরা exportউল্লেখগুলি না করি ততক্ষণ ব্যক্তিগত পদ্ধতির মতো কাজ করতে পারি )
  • যদিও তারা প্রোটোটাইপে নেই, উল্লিখিত পদ্ধতিগুলি স্মৃতি সংরক্ষণ করবে কারণ উদাহরণগুলি ক্লাসের বাইরে একবার তৈরি করা হয়েছে (কনস্ট্রাক্টারে তাদের সংজ্ঞায়নের বিপরীতে)
  • আমরা কোনও মডিউলের অভ্যন্তরে থাকায় কোনও গ্লোবাল ফাঁস করি না
  • বাইন্ডেড _privatesঅবজেক্টটি ব্যবহার করে আমাদের ব্যক্তিগত সম্পত্তিও থাকতে পারে

কিছু ত্রুটিগুলি যা আমি ভাবতে পারি:

  • স্বজ্ঞাত কম
  • ক্লাস সিনট্যাক্স এবং পুরাতন স্কুলের নিদর্শনগুলির মিশ্র ব্যবহার (অবজেক্ট বাইন্ডিং, মডিউল / ফাংশন স্কোপড ভেরিয়েবল)
  • হার্ড বাইন্ডিং - আমরা সর্বজনীন পদ্ধতিগুলি পুনরায় ফিরিয়ে আনতে পারি না (যদিও আমরা নরম বাইন্ডিং ব্যবহার করে এটি উন্নত করতে পারি ( https://github.com/getify/ You-Dont-Know-JS/blob/master/this%20%26% 20 অবজেক্ট% 20 প্রোটোটাইপস / সিএইচ 2.এমডি # সফ্টেনিং-বাইন্ডিং ))

একটি চলমান স্নিপেট এখানে পাওয়া যাবে: http://www.webpackbin.com/NJgI5J8lZ


8

হ্যাঁ - আপনি এনক্যাপসুলেটেড সম্পত্তি তৈরি করতে পারেন , তবে এটি অ্যাক্সেস পরিবর্তনকারী (সর্বজনীন | বেসরকারী) দিয়ে কমপক্ষে ES6 দিয়ে নয়।

এটি কীভাবে ES6 এর সাথে সম্পন্ন করা যায় তা এখানে একটি সাধারণ উদাহরণ:

1 শ্রেণীর শব্দ ব্যবহার করে শ্রেণি তৈরি করুন

2 এটির নির্মাণকারীর ভিতরে যাক বা কনট সংরক্ষিত শব্দগুলি ব্যবহার করে ব্লক-স্কোপড ভেরিয়েবল ঘোষণা করুন -> যেহেতু তারা ব্লক-স্কোপ হয় সেগুলি বাইরে থেকে অ্যাক্সেস করা যায় না (এনক্যাপসুলেটেড)

3 সেই ভেরিয়েবলগুলিতে কিছু অ্যাক্সেস কন্ট্রোল (সেটটার | গিটার) অনুমোদনের জন্য আপনি এর কনস্ট্রাক্টরের অভ্যন্তরে উদাহরণ পদ্ধতিটি ঘোষণা করতে পারেন: this.methodName=function(){}সিনট্যাক্স

"use strict";
    class Something{
        constructor(){
            //private property
            let property="test";
            //private final (immutable) property
            const property2="test2";
            //public getter
            this.getProperty2=function(){
                return property2;
            }
            //public getter
            this.getProperty=function(){
                return property;
            }
            //public setter
            this.setProperty=function(prop){
                property=prop;
            }
        }
    }

এখন এটি পরীক্ষা করে দেখুন:

var s=new Something();
    console.log(typeof s.property);//undefined 
    s.setProperty("another");//set to encapsulated `property`
    console.log(s.getProperty());//get encapsulated `property` value
    console.log(s.getProperty2());//get encapsulated immutable `property2` value

1
কনস্ট্রাক্টরে ঘোষিত সমস্ত পদ্ধতি শ্রেণীর প্রতিটি উদাহরণের জন্য পুনরায় ঘোষিত হওয়া সত্ত্বেও এটি (এখনের জন্য) এই সমস্যার একমাত্র সমাধান। পারফরম্যান্স এবং মেমরির ব্যবহার সম্পর্কে এটি বেশ খারাপ ধারণা। বর্গ পদ্ধতিগুলি কনস্ট্রাক্টরের সুযোগের বাইরে ঘোষণা করা উচিত।
ফ্রিজিস্টেম

@ ফ্রিজিস্টেম প্রথম: প্রথমটি হ'ল উদাহরণ পদ্ধতি (ক্লাস পদ্ধতি নয়)। দ্বিতীয় ও.পি. প্রশ্নটি ছিল: _ আমি কীভাবে দৃষ্টান্তের অ্যাক্সেসকে আটকাতে পারি? প্রপার্টি ?_ এবং আমার উত্তর: কীভাবে তার উদাহরণ ... তৃতীয় যদি আপনার আরও ভাল ধারণা থাকে - আসুন এটি শুনি
নিকিতা কার্টিন

1
আমি বলছিলাম না আপনি ভুল ছিলেন, আমি বলেছিলাম যে প্রতিটি বারের পদ্ধতির অনুলিপি আপনি যখনই কল করবেন প্রতি বারের পদ্ধতির একটি অনুলিপি তৈরি করা সত্ত্বেও আপনার সমাধানগুলি প্রাইভেট ভেরিয়েবল অর্জনের জন্য সর্বোত্তম সমঝোতা ছিল new Something();কারণ আপনার পদ্ধতিগুলি এগুলির অ্যাক্সেসের জন্য কনস্ট্রাক্টরে ঘোষণা করা হয়েছে despite ব্যক্তিগত ভেরিয়েবল। আপনি যদি আপনার ক্লাসের উদাহরণ তৈরি করেন তবে পারফরম্যান্সের সমস্যা থাকলে এটি প্রচুর মেমরির ব্যবহার করতে পারে। পদ্ধতিগুলি নির্মাণকারীর সুযোগের বাইরে ঘোষণা করা উচিত ছিল। আমার মন্তব্য একটি সমালোচনার চেয়ে আপনার সমাধানের অসুবিধাগুলির আরও ব্যাখ্যা ছিল।
ফ্রি

1
তবে এটি কি খারাপ অনুশীলনটি কনস্ট্রাক্টরের ভিতরে আপনার পুরো ক্লাসটি সংজ্ঞায়িত করে না? আমরা কি এখন কেবল জাভাস্ক্রিপ্ট "হ্যাকিং" করছি না? অন্য কোনও ওওপি প্রোগ্রামিং ভাষাটি দেখুন, এবং আপনি দেখতে পাবেন যে কনস্ট্রাক্টর কোনও ক্লাস সংজ্ঞায়িত করার উদ্দেশ্যে নয়।
কোকোডোকো

1
হ্যাঁ এটাই আমি বোঝাতে চাইছিলাম এবং আপনার সমাধান কাজ করে! আমি কেবল বলছি যে সাধারণভাবে আমি আশ্চর্য হয়েছি যে ES6 একটি 'শ্রেণি' কীওয়ার্ড যুক্ত করেছে, তবে এনক্যাপসুলেশন অর্জনের জন্য ভেরি এবং এটির সাথে কাজ করার মার্জিত সমাধানটি সরিয়ে ফেলেছে।
কোকোডোকো

8

"ব্যক্তিগত" একটি পৃথক পদ্ধতির

বর্তমানে প্রাইভেট দৃশ্যমানতা ES6 এ অনুপলব্ধ, এই বিরুদ্ধে লড়াই করার পরিবর্তে, আমি সিদ্ধান্ত নিয়েছি যে আরও আইটেমিক পদ্ধতি গ্রহণ করা উচিত যা আপনার আইডিই জেএসডকে সমর্থন করে (যেমন, ওয়েবস্টর্ম) fine @privateট্যাগটি ব্যবহার করার জন্য ধারণা । উন্নয়ন যতদূর যায় আইডিই আপনাকে কোনও শ্রেণীর বাইরে থেকে কোনও ব্যক্তিগত সদস্য অ্যাক্সেস করা থেকে বিরত রাখবে। আমার জন্য বেশ ভাল কাজ করে এবং এটি অভ্যন্তরীণ পদ্ধতিগুলি গোপন করার জন্য সত্যই কার্যকর ছিল যাতে স্বয়ংক্রিয় সম্পূর্ণ বৈশিষ্ট্যটি আমাকে দেখায় যে ক্লাসটি প্রকৃতপক্ষে প্রকাশ করার জন্য কী বোঝায়। এখানে একটি উদাহরণ:

কেবল সর্বজনীন স্টাফ দেখানো স্বয়ংক্রিয়ভাবে সম্পূর্ণ


1
সমস্যাটি হচ্ছে, আমরা সম্পাদকের মাধ্যমে ব্যক্তিগত ভেরিয়েবলগুলি অ্যাক্সেস করতে চাই না, আমরা বাইরে থেকে ব্যক্তিগত ভেরিয়েবলগুলি রক্ষা করতে চাই না - এবং এটি পাবলিক / প্রাইভেট কী করে। যদি আপনার কোড শেষ হয়ে যায়, আপনি ক্লাসের বাইরে থেকে এই ভেরিয়েবলগুলি অ্যাক্সেস করতে পারেন (এবং গুরুত্বপূর্ণগুলি মনে করেন: ওভাররাইড )। আপনার @privateমন্তব্য এগুলি প্রতিরোধ করতে পারে না, এটি কেবলমাত্র ডকুমেন্টেশন-জেনারেশনের বৈশিষ্ট্য এবং আপনি আইডিই।
অ্যাড্রিয়ান প্রেউস

হ্যাঁ, আমি এটি সম্পর্কে সচেতন। এটি কেবলমাত্র আমার পক্ষে যথেষ্ট এবং সেখানকার অন্যান্য ব্যক্তির পক্ষেও এটি যথেষ্ট। আমি জানি এটি সত্যই আমার পরিবর্তনশীলগুলি ব্যক্তিগত করে তুলছে না; এটি কেবলমাত্র আমাকে বাইরে থেকে চেষ্টা না করার এবং অ্যাক্সেস না করার জন্য সতর্ক করছে (কেবলমাত্র, যদি আমার দল এবং আমি সকলেই একটি আইডিই ব্যবহার করে যা এই বৈশিষ্ট্যটিকে সমর্থন করে)। জাভাস্ক্রিপ্ট (এবং পাইথনের মতো অন্যান্য ভাষাগুলি) অ্যাক্সেসের স্তরগুলি মাথায় রেখে তৈরি করা হয়নি। লোকেরা কোনওভাবে সেই কার্যকারিতাটি বাস্তবায়নের জন্য সমস্ত ধরণের স্টাফ করে, তবে শেষ পর্যন্ত আমরা সেটি অর্জনের জন্য কেবল ভাষা হ্যাক করি। আমি যদি সিদ্ধান্ত নিই তবে আরও "প্রাকৃতিক" পদ্ধতির সাথে যাব।
লুসিও পাইভা

6

WeakMap

  • আইই ১১ এ সমর্থিত (প্রতীকগুলি নয়)
  • হার্ড-প্রাইভেট (প্রতীকগুলি ব্যবহার করে প্রপসগুলি নরম-প্রাইভেট হওয়ায় Object.getOwnPropertySymbols)
  • সত্যিই পরিষ্কার দেখতে পারেন (নির্মাতাদের সমস্ত প্রসেস এবং পদ্ধতিগুলির প্রয়োজন এমন ক্লোজারগুলির বিপরীতে)

প্রথমে WeakMap মোড়ানো একটি ফাংশন সংজ্ঞায়িত:

function Private() {
  const map = new WeakMap();
  return obj => {
    let props = map.get(obj);
    if (!props) {
      props = {};
      map.set(obj, props);
    }
    return props;
  };
}

তারপরে, আপনার শ্রেণীর বাইরে একটি রেফারেন্স তৈরি করুন:

const p = new Private();

class Person {
  constructor(name, age) {
    this.name = name;
    p(this).age = age; // it's easy to set a private variable
  }

  getAge() {
    return p(this).age; // and get a private variable
  }
}

দ্রষ্টব্য: শ্রেণি IE11 দ্বারা সমর্থিত নয়, তবে উদাহরণটিতে এটি আরও পরিষ্কার দেখাচ্ছে।


6

ওহ, এত বিদেশী সমাধান! আমি সাধারণত গোপনীয়তার বিষয়ে চিন্তা করি না তাই এখানে যেমন বলা হয়েছে আমি "সিউডো প্রাইভেসি" ব্যবহার করি । তবে যদি যত্ন নিই (যদি এর জন্য কিছু বিশেষ প্রয়োজনীয়তা থাকে তবে) আমি উদাহরণের মতো কিছু ব্যবহার করি:

class jobImpl{
  // public
  constructor(name){
    this.name = name;
  }
  // public
  do(time){
    console.log(`${this.name} started at ${time}`);
    this.prepare();
    this.execute();
  }
  //public
  stop(time){
    this.finish();
    console.log(`${this.name} finished at ${time}`);
  }
  // private
  prepare(){ console.log('prepare..'); }
  // private
  execute(){ console.log('execute..'); }
  // private
  finish(){ console.log('finish..'); }
}

function Job(name){
  var impl = new jobImpl(name);
  return {
    do: time => impl.do(time),
    stop: time => impl.stop(time)
  };
}

// Test:
// create class "Job"
var j = new Job("Digging a ditch");
// call public members..
j.do("08:00am");
j.stop("06:00pm");

// try to call private members or fields..
console.log(j.name); // undefined
j.execute(); // error

ফাংশনের আরেকটি সম্ভাব্য বাস্তবায়ন (কনস্ট্রাক্টর) Job:

function Job(name){
  var impl = new jobImpl(name);
  this.do = time => impl.do(time),
  this.stop = time => impl.stop(time)
}

5

ব্যক্তিগতভাবে আমি বাইন্ড অপারেটরের প্রস্তাবটি পছন্দ করি ::এবং তারপরে এটি উল্লিখিত @ d13 এর সমাধানের সাথে একত্রিত করব তবে আপাতত @ ডি 13 এর উত্তরটির সাথে আটকে থাকুন যেখানে আপনি exportনিজের শ্রেণীর জন্য কীওয়ার্ডটি ব্যবহার করেন এবং মডিউলটিতে ব্যক্তিগত ফাংশন রাখেন।

আরও শক্ত সমাধান রয়েছে যা এখানে উল্লেখ করা হয়নি যা নিম্নলিখিত আরও কার্যকরী পদ্ধতির এবং এটি ক্লাসের মধ্যে সমস্ত প্রাইভেট প্রপস / পদ্ধতি থাকতে দেয়।

Private.js

export const get = state => key => state[key];
export const set = state => (key,value) => { state[key] = value; }

Test.js

import { get, set } from './utils/Private'
export default class Test {
  constructor(initialState = {}) {
    const _set = this.set = set(initialState);
    const _get = this.get = get(initialState);

    this.set('privateMethod', () => _get('propValue'));
  }

  showProp() {
    return this.get('privateMethod')();
  }
}

let one = new Test({ propValue: 5});
let two = new Test({ propValue: 8});
two.showProp(); // 8
one.showProp(); // 5

এটি মন্তব্য প্রশংসা হবে।


সাধারণত আমি পদ্ধতির পছন্দ। প্রতিক্রিয়া: ১. সংঘর্ষ রোধ করতে আপনার প্রতিটি শ্রেণির জন্য একটি আলাদা প্রাইভেট জেএস মডিউল প্রয়োজন। ২. আপনার প্রতিটি ব্যক্তিগত পদ্ধতির ইনলাইন-সংজ্ঞা দিয়ে কনস্ট্রাক্টরটিকে সত্যই দীর্ঘায়িত করার সম্ভাবনা আমি অপছন্দ করি। ৩. ক্লাসের সমস্ত পদ্ধতি এক ফাইলে থাকলে ভাল লাগবে be
ডগ কোবার্ন

5

"ক্লাসের জন্য ব্যক্তিগত ডেটা" জন্য সেরা অনুশীলনের সন্ধান করার সময় আমি এই পোস্টটি জুড়ে এসেছি। এটি উল্লেখ করা হয়েছিল যে কয়েকটি ধাঁচে পারফরম্যান্সের সমস্যা থাকবে।

অনলাইন বই "এক্সপ্লোরিং ইএস 6" থেকে 4 টি মূল নিদর্শনগুলির উপর ভিত্তি করে আমি কয়েকটি জেএসপিআইপি পরীক্ষা একসাথে রেখেছি:

http://exploringjs.com/es6/ch_classes.html#sec_private-data-for-classes

পরীক্ষাগুলি এখানে পাওয়া যাবে:

https://jsperf.com/private-data-for-classes

ক্রোম 63.0.3239 / ম্যাক ওএস এক্স 10.11.6 এ, সেরা পারফর্মিং নিদর্শনগুলি হ'ল "কনস্ট্রাক্টর পরিবেশের মাধ্যমে ব্যক্তিগত ডেটা" এবং "নামকরণের কনভেনশনের মাধ্যমে ব্যক্তিগত ডেটা"। আমার জন্য সাফারি উইকম্যাপের পক্ষে ভাল অভিনয় করেছে তবে ক্রোম এতটা ভাল নয়।

আমি মেমরির প্রভাব জানি না, তবে "কনস্ট্রাক্টর এনভায়রনমেন্টস" এর প্যাটার্নটি যা কেউ কেউ সতর্ক করেছিলেন যে একটি পারফরম্যান্স ইস্যু হতে পারে forma

চারটি বেসিক নিদর্শনগুলি হ'ল:

কনস্ট্রাক্টর পরিবেশের মাধ্যমে ব্যক্তিগত ডেটা

class Countdown {
    constructor(counter, action) {
        Object.assign(this, {
            dec() {
                if (counter < 1) return;
                counter--;
                if (counter === 0) {
                    action();
                }
            }
        });
    }
}
const c = new Countdown(2, () => {});
c.dec();
c.dec();

কনস্ট্রাক্টর পরিবেশের মাধ্যমে ব্যক্তিগত ডেটা 2

class Countdown {
    constructor(counter, action) {
        this.dec = function dec() {
            if (counter < 1) return;
            counter--;
            if (counter === 0) {
                action();
            }
        }
    }
}
const c = new Countdown(2, () => {});
c.dec();
c.dec();

একটি নামকরণ সম্মেলনের মাধ্যমে ব্যক্তিগত ডেটা data

class Countdown {
    constructor(counter, action) {
        this._counter = counter;
        this._action = action;
    }
    dec() {
        if (this._counter < 1) return;
        this._counter--;
        if (this._counter === 0) {
            this._action();
        }
    }
}
const c = new Countdown(2, () => {});
c.dec();
c.dec();

WeakMaps মাধ্যমে ব্যক্তিগত তথ্য

const _counter = new WeakMap();
const _action = new WeakMap();
class Countdown {
    constructor(counter, action) {
        _counter.set(this, counter);
        _action.set(this, action);
    }
    dec() {
        let counter = _counter.get(this);
        if (counter < 1) return;
        counter--;
        _counter.set(this, counter);
        if (counter === 0) {
            _action.get(this)();
        }
    }
}
const c = new Countdown(2, () => {});
c.dec();
c.dec();

প্রতীকগুলির মাধ্যমে ব্যক্তিগত ডেটা

const _counter = Symbol('counter');
const _action = Symbol('action');

class Countdown {
    constructor(counter, action) {
        this[_counter] = counter;
        this[_action] = action;
    }
    dec() {
        if (this[_counter] < 1) return;
        this[_counter]--;
        if (this[_counter] === 0) {
            this[_action]();
        }
    }
}
const c = new Countdown(2, () => {});
c.dec();
c.dec();

4

আমি বিশ্বাস করি কনস্ট্রাক্টরের অভ্যন্তরে ক্লোজার ব্যবহার করে 'উভয় বিশ্বের সেরা' পাওয়া সম্ভব। দুটি ভিন্নতা রয়েছে:

সমস্ত ডেটা সদস্য ব্যক্তিগত

function myFunc() {
   console.log('Value of x: ' + this.x);
   this.myPrivateFunc();
}

function myPrivateFunc() {
   console.log('Enhanced value of x: ' + (this.x + 1));
}

class Test {
   constructor() {

      let internal = {
         x : 2,
      };
      
      internal.myPrivateFunc = myPrivateFunc.bind(internal);
      
      this.myFunc = myFunc.bind(internal);
   }
};

কিছু সদস্য বেসরকারী হয়

দ্রষ্টব্য: এটি স্বভাবতই কুৎসিত। আপনি যদি আরও ভাল সমাধান জানেন তবে দয়া করে এই প্রতিক্রিয়াটি সম্পাদনা করুন।

function myFunc(priv, pub) {
   pub.y = 3; // The Test object now gets a member 'y' with value 3.
   console.log('Value of x: ' + priv.x);
   this.myPrivateFunc();
}

function myPrivateFunc() {
   pub.z = 5; // The Test object now gets a member 'z' with value 3.
   console.log('Enhanced value of x: ' + (priv.x + 1));
}

class Test {
   constructor() {
      
      let self = this;

      let internal = {
         x : 2,
      };
      
      internal.myPrivateFunc = myPrivateFunc.bind(null, internal, self);
      
      this.myFunc = myFunc.bind(null, internal, self);
   }
};


4

আসলে এটি সিম্বলস এবং প্রক্সি ব্যবহার করে সম্ভব। আপনি ক্লাস স্কোপে চিহ্নগুলি ব্যবহার করেন এবং একটি প্রক্সিতে দুটি ফাঁদ সেট করেছেন: একটি ক্লাস প্রোটোটাইপের জন্য যাতে রিফ্লেক.এইনকি (উদাহরণস্বরূপ) বা অবজেক্ট.জেটঅনপোপার্টিসাইমোলস আপনার প্রতীকগুলি দূরে না দেয়, অন্যটি নির্মাণকারীর জন্যই হয় সুতরাং যখন new ClassName(attrs)ডাকা হবে, প্রত্যাবর্তিত উদাহরণটি বাধা দেওয়া হবে এবং নিজস্ব বৈশিষ্ট্য চিহ্নগুলি অবরুদ্ধ করা হবে। কোডটি এখানে:

const Human = (function() {
  const pet = Symbol();
  const greet = Symbol();

  const Human = privatizeSymbolsInFn(function(name) {
    this.name = name; // public
    this[pet] = 'dog'; // private 
  });

  Human.prototype = privatizeSymbolsInObj({
    [greet]() { // private
      return 'Hi there!';
    },
    revealSecrets() {
      console.log(this[greet]() + ` The pet is a ${this[pet]}`);
    }
  });

  return Human;
})();

const bob = new Human('Bob');

console.assert(bob instanceof Human);
console.assert(Reflect.ownKeys(bob).length === 1) // only ['name']
console.assert(Reflect.ownKeys(Human.prototype).length === 1 ) // only ['revealSecrets']


// Setting up the traps inside proxies:
function privatizeSymbolsInObj(target) { 
  return new Proxy(target, { ownKeys: Object.getOwnPropertyNames });
}

function privatizeSymbolsInFn(Class) {
  function construct(TargetClass, argsList) {
    const instance = new TargetClass(...argsList);
    return privatizeSymbolsInObj(instance);
  }
  return new Proxy(Class, { construct });
}

Reflect.ownKeys()এর মতো কাজ করে: Object.getOwnPropertyNames(myObj).concat(Object.getOwnPropertySymbols(myObj))এজন্য আমাদের এই জিনিসগুলির জন্য একটি ফাঁদ দরকার।


ধন্যবাদ, আমি প্রতীকগুলি চেষ্টা করে দেখব :) উপরের সমস্ত উত্তর থেকে এটি একটি অ্যাক্সেসযোগ্য শ্রেণীর সদস্য তৈরি করার সবচেয়ে সহজ উপায় বলে মনে হচ্ছে :)
কোকোডোকো

4

এমনকি টাইপস্ক্রিপ্ট এটি করতে পারে না। তাদের ডকুমেন্টেশন থেকে :

কোনও সদস্যকে যখন ব্যক্তিগত হিসাবে চিহ্নিত করা হয়, এটির ধারণক্ষম শ্রেণীর বাইরে থেকে এটি অ্যাক্সেস করা যায় না। উদাহরণ স্বরূপ:

class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}

new Animal("Cat").name; // Error: 'name' is private;

তবে তাদের খেলার মাঠে স্থানান্তরিত এটি দেয়:

var Animal = (function () {
    function Animal(theName) {
        this.name = theName;
    }
    return Animal;
}());
console.log(new Animal("Cat").name);

সুতরাং তাদের "ব্যক্তিগত" কীওয়ার্ডটি অকার্যকর।


2
ঠিক আছে, এটি এখনও কার্যকর কারণ এটি আইডিই থাকাকালীন "খারাপ" প্রোগ্রামিং প্রতিরোধ করে। এটি আপনাকে দেখায় যে আপনার কোন সদস্য ব্যবহার করা উচিত এবং ব্যবহার করা উচিত নয়। আমি মনে করি এটি ব্যক্তিগত এবং পাবলিক ব্যবহারের মূল কারণ। (উদাহরণস্বরূপ, আপনি যখন সি # মেশিন কোডটি সংকলন করেন, তখনও ব্যক্তিগত কী ব্যক্তিগত হবে? কে জানে?)। অন্যান্য উত্তরগুলি পড়ার সময়, মনে হয় @ সিম্বল ব্যবহার করাও সদস্যকে অ্যাক্সেসযোগ্য করে তুলতে পারে। এমনকি কনসোল থেকে সিম্বলগুলি এখনও পাওয়া যাবে।
কোকোডোকো

টাইপস্ক্রিপ্টটি জাভাস্ক্রিপ্টে স্থানান্তর করার সময় কি টাইপস্ক্রিপ্ট ত্রুটি ঘটে? (ভালো লেগেছে টাইপ পরীক্ষণ কিছু রানটাইম ব্যক্তিগত প্রক্রিয়া চেয়ে transpite সময়ে ঘটে বরং।।)
Eljay

4

এই পার্টিতে খুব দেরি হচ্ছে তবে আমি অনুসন্ধানের জন্য ওপি প্রশ্নটিকে আঘাত করেছি যাতে ... হ্যাঁ, ক্লাসের ঘোষণাটি বন্ধ করে আপনার ব্যক্তিগত সম্পত্তি থাকতে পারে

এই কোডেপেনে আমার কীভাবে ব্যক্তিগত পদ্ধতি রয়েছে তার একটি উদাহরণ রয়েছে । নীচের স্নিপেটে সাবস্ক্রাইবযোগ্য শ্রেণীর দুটি 'ব্যক্তিগত' ফাংশন রয়েছে processএবং processCallbacks। যে কোনও সম্পত্তি এই পদ্ধতিতে যুক্ত করা যেতে পারে এবং বন্ধের ব্যবহারের মাধ্যমে সেগুলি ব্যক্তিগত রাখা হয়। আইএমও গোপনীয়তার একটি বিরল প্রয়োজন, যদি উদ্বেগগুলি ভালভাবে পৃথক করা হয় এবং জাভাস্ক্রিপ্টটি বন্ধ হয়ে যাওয়ার সাথে সাথে কাজটি করার সময় আরও সিনট্যাক্স যুক্ত করে প্রস্ফুটিত হওয়ার প্রয়োজন হয় না।

const Subscribable = (function(){

  const process = (self, eventName, args) => {
    self.processing.set(eventName, setTimeout(() => processCallbacks(self, eventName, args)))};

  const processCallbacks = (self, eventName, args) => {
    if (self.callingBack.get(eventName).length > 0){
      const [nextCallback, ...callingBack] = self.callingBack.get(eventName);
      self.callingBack.set(eventName, callingBack);
      process(self, eventName, args);
      nextCallback(...args)}
    else {
      delete self.processing.delete(eventName)}};

  return class {
    constructor(){
      this.callingBack = new Map();
      this.processing = new Map();
      this.toCallbacks = new Map()}

    subscribe(eventName, callback){
      const callbacks = this.unsubscribe(eventName, callback);
      this.toCallbacks.set(eventName,  [...callbacks, callback]);
      return () => this.unsubscribe(eventName, callback)}  // callable to unsubscribe for convenience

    unsubscribe(eventName, callback){
      let callbacks = this.toCallbacks.get(eventName) || [];
      callbacks = callbacks.filter(subscribedCallback => subscribedCallback !== callback);
      if (callbacks.length > 0) {
        this.toCallbacks.set(eventName, callbacks)}
      else {
        this.toCallbacks.delete(eventName)}
      return callbacks}

    emit(eventName, ...args){
      this.callingBack.set(eventName, this.toCallbacks.get(eventName) || []);
      if (!this.processing.has(eventName)){
        process(this, eventName, args)}}}})();

আমি এই পদ্ধতির পছন্দ করি কারণ এটি উদ্বেগগুলি সুন্দরভাবে আলাদা করে এবং জিনিসগুলিকে সত্যই ব্যক্তিগত রাখে। একমাত্র নেতিবাচকতা হ'ল ব্যক্তিগত সামগ্রীতে 'এটি' উল্লেখ করার জন্য 'স্ব' (বা অনুরূপ কিছু) ব্যবহার করা দরকার।


4

আমি মনে করি বেনজামিনের উত্তর সম্ভবত বেশিরভাগ ক্ষেত্রেই সেরা, যতক্ষণ না ভাষা স্থানীয়ভাবে স্পষ্টতভাবে ব্যক্তিগত ভেরিয়েবলগুলি সমর্থন করে।

যাইহোক, যদি কোনও কারণে আপনাকে অ্যাক্সেস রোধ করতে হবে, তবে Object.getOwnPropertySymbols()আমি যে পদ্ধতিটি ব্যবহার করার বিষয়টি বিবেচনা করেছি তা হ'ল একটি অনন্য, অ-কনফিগারযোগ্য, অ-গণনাযোগ্য, অ-লিখনযোগ্য সম্পত্তি যা সংস্থার প্রতিটি বস্তুর সম্পত্তি সনাক্তকারী হিসাবে ব্যবহার করা যেতে পারে (যেমন একটি অনন্য Symbol, যদি আপনার মতো ইতিমধ্যে অন্য কোনও অনন্য সম্পত্তি না থাকে id)। তারপরে সেই সনাক্তকারীটি ব্যবহার করে প্রতিটি বস্তুর 'ব্যক্তিগত' ভেরিয়েবলের মানচিত্র রাখুন।

const privateVars = {};

class Something {
    constructor(){
        Object.defineProperty(this, '_sym', {
            configurable: false,
            enumerable: false,
            writable: false,
            value: Symbol()
        });

        var myPrivateVars = {
            privateProperty: "I'm hidden"
        };

        privateVars[this._sym] = myPrivateVars;

        this.property = "I'm public";
    }

    getPrivateProperty() {
        return privateVars[this._sym].privateProperty;
    }

    // A clean up method of some kind is necessary since the
    // variables won't be cleaned up from memory automatically
    // when the object is garbage collected
    destroy() {
        delete privateVars[this._sym];
    }
}

var instance = new Something();
console.log(instance.property); //=> "I'm public"
console.log(instance.privateProperty); //=> undefined
console.log(instance.getPrivateProperty()); //=> "I'm hidden"

একটি ব্যবহার উপর এই পদ্ধতির সম্ভাব্য সুবিধা WeakMapহল দ্রুত অ্যাক্সেসের সময় যদি কর্মক্ষমতা একটি উদ্বেগের বিষয় হয়ে ওঠে।


1
আমি ভুল হলে আমাকে সংশোধন করুন, তবে এই কোডটিতে মেমরি ফাঁস থাকবে না কারণ প্রাইভেট ওয়ার্স এখনও অবজেক্টের ব্যক্তিগত ভেরিয়েবলগুলি সংরক্ষণ করবে এমনকি যদি বস্তুটি ইতিমধ্যে ধ্বংস হয়ে যায়?
রাসেল

@ রাসেলস্যান্টোস আপনি ঠিক বলেছেন, ধরে নিচ্ছেন যে কোনও কোনও মুহুর্তে জিনিসগুলি আবর্জনা সংগ্রহ করা দরকার। এটি নির্দেশ করার জন্য আপনাকে ধন্যবাদ। আমার উদাহরণে আমি একটি destroy()পদ্ধতি যুক্ত করেছি যা যখনই কোনও বস্তু সরানোর প্রয়োজন হয় তখন ব্যবহার কোড দ্বারা কল করা উচিত।
ন্যানো উইজার্ড

4

হ্যাঁ সম্পূর্ণরূপে করতে পারেন, এবং খুব সহজেই। কনস্ট্রাক্টরের প্রোটোটাইপ অবজেক্ট গ্রাফটি ফিরিয়ে আপনার ব্যক্তিগত ভেরিয়েবল এবং ফাংশনগুলি প্রকাশ করে এটি করা হয়। এটি নতুন কিছু নয়, তবে এর কমনীয়তা বুঝতে js foo এর কিছুটা সময় নিন। এইভাবে গ্লোবাল স্কোপড, বা দুর্বলম্যাপগুলি ব্যবহার করে না। এটি ভাষার প্রতিবিম্বিত একধরণের প্রতিচ্ছবি। আপনি কীভাবে এটি উপার্জন করছেন তার উপর নির্ভর করে; যে কোনও একটি ব্যতিক্রমকে বাধ্য করতে পারে যা কল স্ট্যাককে বাধাগ্রস্ত করে, বা ব্যতিক্রমটিকে একটি হিসাবে সমাহিত করে undefined। এটি নীচে প্রদর্শিত হয় এবং এখানে এই বৈশিষ্ট্যগুলি সম্পর্কে আরও পড়তে পারেন

class Clazz {
  constructor() {
    var _level = 1

    function _private(x) {
      return _level * x;
    }
    return {
      level: _level,
      public: this.private,
      public2: function(x) {
        return _private(x);
      },
      public3: function(x) {
        return _private(x) * this.public(x);
      },
    };
  }

  private(x) {
    return x * x;
  }
}

var clazz = new Clazz();

console.log(clazz._level); //undefined
console.log(clazz._private); // undefined
console.log(clazz.level); // 1
console.log(clazz.public(1)); //1
console.log(clazz.public2(2)); //2
console.log(clazz.public3(3)); //27
console.log(clazz.private(0)); //error


3
class Something {
  constructor(){
    var _property = "test";
    Object.defineProperty(this, "property", {
        get: function(){ return _property}
    });
  }
}

var instance = new Something();
console.log(instance.property); //=> "test"
instance.property = "can read from outside, but can't write";
console.log(instance.property); //=> "test"

2
কোড কেবল উত্তরগুলি এড়ানো ভাল best আপনার কোডটি কীভাবে ওপি-র প্রশ্নের উত্তর দেয় তা আপনি ব্যাখ্যা করতে পারলে আরও ভাল হত
স্টুয়ার্ট_আর

এটি কীভাবে প্রাইভেট ভেরিয়েবলের চেয়ে বেশি পঠনযোগ্য পরিবর্তনশীল করতে হয় to একটি ব্যক্তিগত ভেরিয়েবল বাইরের অ্যাক্সেসযোগ্য হবে না। console.log(instance.property)আপনাকে নিক্ষিপ্ত করা বা অপরিশোধিত করা উচিত, আপনাকে "পরীক্ষা" ফিরিয়ে দেবে না।
oooyaya

3

শেষ দুটি পোস্টের অনুরূপ অন্য একটি উপায়

class Example {
  constructor(foo) {

    // privates
    const self = this;
    this.foo = foo;

    // public interface
    return self.public;
  }

  public = {
    // empty data
    nodata: { data: [] },
    // noop
    noop: () => {},
  }

  // everything else private
  bar = 10
}

const test = new Example('FOO');
console.log(test.foo); // undefined
console.log(test.noop); // { data: [] }
console.log(test.bar); // undefined

2

বেশিরভাগ উত্তরে বলা হয় এটি অসম্ভব, বা আপনাকে উইকম্যাপ বা প্রতীক ব্যবহার করতে হবে যা ES6 বৈশিষ্ট্যগুলির জন্য সম্ভবত পলফিল প্রয়োজন হবে require অন্য উপায় আছে! এটি পরীক্ষা করে দেখুন:

// 1. Create closure
var SomeClass = function() {
  // 2. Create `key` inside a closure
  var key = {};
  // Function to create private storage
  var private = function() {
    var obj = {};
    // return Function to access private storage using `key`
    return function(testkey) {
      if(key === testkey) return obj;
      // If `key` is wrong, then storage cannot be accessed
      console.error('Cannot access private properties');
      return undefined;
    };
  };
  var SomeClass = function() {
    // 3. Create private storage
    this._ = private();
    // 4. Access private storage using the `key`
    this._(key).priv_prop = 200;
  };
  SomeClass.prototype.test = function() {
    console.log(this._(key).priv_prop); // Using property from prototype
  };
  return SomeClass;
}();

// Can access private property from within prototype
var instance = new SomeClass();
instance.test(); // `200` logged

// Cannot access private property from outside of the closure
var wrong_key = {};
instance._(wrong_key); // undefined; error logged

আমি এই পদ্ধতিটি অ্যাকসেসর প্যাটার্ন বলি । অপরিহার্য ধারণা যে আমরা একটি আছে অবসান , একটি চাবি অবসান ভিতরে এবং আমরা একে সৃষ্টি ব্যক্তিগত বস্তুর (কন্সট্রাকটর মধ্যে) যে শুধুমাত্র যদি আপনি অ্যাক্সেস করা যেতে পারে কী

আপনি যদি আগ্রহী হন তবে আপনি আমার নিবন্ধে এটি সম্পর্কে আরও পড়তে পারেন । এই পদ্ধতিটি ব্যবহার করে, আপনি প্রতি বস্তুর বৈশিষ্ট্য তৈরি করতে পারেন যা বন্ধের বাইরে অ্যাক্সেস করা যায় না। অতএব, আপনি এগুলি নির্মাণকারী বা প্রোটোটাইপে ব্যবহার করতে পারেন তবে অন্য কোথাও নয়। আমি এই পদ্ধতিটি কোথাও ব্যবহার করতে দেখিনি, তবে আমি মনে করি এটি সত্যই শক্তিশালী।


ES6 ক্লাসে এটি কীভাবে অর্জন করা যায় তা নিয়ে প্রশ্ন ছিল।
মাইকেল ফ্রানজল

আপনি ES6 ক্লাসে ঠিক একই পদ্ধতি ব্যবহার করতে পারেন। ES6 ক্লাসগুলি প্রধানত ফাংশনগুলির উপরে কেবল চিনি যেমন আমি আমার উদাহরণটিতে উপস্থাপন করি। এটি বেশ সম্ভব যে মূল পোস্টারটি ট্রান্সপ্লার ব্যবহার করছে, সেক্ষেত্রে উইকম্যাপস বা সিম্বলগুলি এখনও পলিফিলের প্রয়োজন হবে। আমার উত্তর নির্বিশেষে বৈধ।
গিটারিনো

2

ব্যক্তিগত এবং পাবলিক ইন্টারফেস এবং রচনার জন্য সহায়তার সাথে এ ক্লিন ও সাধারণ 'ক্লাস' সমাধানের জন্য এই উত্তরটি দেখুন


2

আমি খুব সহজ সমাধান পেয়েছি, কেবল ব্যবহার করুন Object.freeze()। অবশ্যই সমস্যাটি হ'ল আপনি পরে বস্তুটিতে কোনও কিছুই যুক্ত করতে পারবেন না।

class Cat {
    constructor(name ,age) {
        this.name = name
        this.age = age
        Object.freeze(this)
    }
}

let cat = new Cat('Garfield', 5)
cat.age = 6 // doesn't work, even throws an error in strict mode

এটি সেটার পদ্ধতিটি যেমন অক্ষম করবেsetName(name) { this.name = name; }
এনজিএকাক

2

আমি এই নিদর্শনটি ব্যবহার করি এবং এটি সর্বদা আমার পক্ষে কাজ করে

class Test {
    constructor(data) {
        class Public {
            constructor(prv) {

                // public function (must be in constructor on order to access "prv" variable)
                connectToDb(ip) {
                    prv._db(ip, prv._err);
                } 
            }

            // public function w/o access to "prv" variable
            log() {
                console.log("I'm logging");
            }
        }

        // private variables
        this._data = data;
        this._err = function(ip) {
            console.log("could not connect to "+ip);
        }
    }

    // private function
    _db(ip, err) {
        if(!!ip) {
		    console.log("connected to "+ip+", sending data '"+this.data+"'");
			return true;
		}
        else err(ip);
    }
}



var test = new Test(10),
		ip = "185.167.210.49";
test.connectToDb(ip); // true
test.log(); // I'm logging
test._err(ip); // undefined
test._db(ip, function() { console.log("You have got hacked!"); }); // undefined


2

আসলে এটা হল সম্ভব।
১. প্রথমে ক্লাস তৈরি করুন এবং কনস্ট্রাক্টরে ডাকা _publicফাংশনটি ফিরিয়ে দিন ।
২. কথিত _publicফাংশনে thisরেফারেন্সটি (সমস্ত প্রাইভেট পদ্ধতি এবং প্রপসগুলিতে অ্যাক্সেস পেতে) এবং সমস্ত যুক্তি constructor (যা এতে পাস হবে new Names()) পাস করুন
৩. _publicফাংশনের সুযোগে Namesঅ্যাক্সেস সহ thisশ্রেণিটিও রয়েছে (_এটি ) বেসরকারী Namesশ্রেণীর রেফারেন্স

class Names {
  constructor() {
    this.privateProperty = 'John';
    return _public(this, arguments);
  }
  privateMethod() { }
}

const names = new Names(1,2,3);
console.log(names.somePublicMethod); //[Function]
console.log(names.publicProperty); //'Jasmine'
console.log(names.privateMethod); //undefined
console.log(names.privateProperty); //undefind

function _public(_this, _arguments) {
  class Names {
    constructor() {
      this.publicProperty = 'Jasmine';
      _this.privateProperty; //"John";
      _this.privateMethod; //[Function]
    }

    somePublicMethod() {
      _this.privateProperty; //"John";
      _this.privateMethod; //[Function]
    }

  }
  return new Names(..._arguments);
}

2

আপনি এটি চেষ্টা করতে পারেন https://www.npmjs.com/package/private-meम्बर

এই প্যাকেজটি উদাহরণস্বরূপ সদস্যদের সংরক্ষণ করবে।

const pvt = require('private-members');
const _ = pvt();

let Exemplo = (function () {    
    function Exemplo() {
        _(this).msg = "Minha Mensagem";
    }

    _().mensagem = function() {
        return _(this).msg;
    }

    Exemplo.prototype.showMsg = function () {
        let msg = _(this).mensagem();
        console.log(msg);
    };

    return Exemplo;
})();

module.exports = Exemplo;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.