টাইপস্ক্রিপ্টে ব্যক্তিগত কীওয়ার্ড এবং ব্যক্তিগত ক্ষেত্রগুলির মধ্যে পার্থক্যগুলি কী?


27

টাইপস্ক্রিপ্ট ৩.৮+ তে, privateসদস্যকে ব্যক্তিগত চিহ্নিত করার জন্য কীওয়ার্ডটি ব্যবহারের মধ্যে পার্থক্যগুলি কী :

class PrivateKeywordClass {
    private value = 1;
}

এবং জাভাস্ক্রিপ্টের জন্য প্রস্তাবিত# ব্যক্তিগত ক্ষেত্রগুলি ব্যবহার :

class PrivateFieldClass {
    #value = 1;
}

আমি কি অন্যের চেয়ে বেশি পছন্দ করি?


উত্তর:


43

ব্যক্তিগত কীওয়ার্ড

ব্যক্তিগত শব্দ টাইপ করা বিষয় একটি হল সময় সঙ্কলন টীকা। এটি সংকলককে বলে যে কোনও শ্রেণি কেবলমাত্র সেই শ্রেণীর অভ্যন্তরে প্রবেশযোগ্য হবে:

class PrivateKeywordClass {
    private value = 1;
}

const obj = new PrivateKeywordClass();
obj.value // compiler error: Property 'value' is private and only accessible within class 'PrivateKeywordClass'.

তবে সংকলনের সময় পরীক্ষা করা সহজেই বাইপাস করা যায়, উদাহরণস্বরূপ টাইপ তথ্য ফেলে দেওয়া:

const obj = new PrivateKeywordClass();
(obj as any).value // no compile error

privateশব্দ এছাড়াও রানটাইম এ কার্যকরী হয় না

নির্গত জাভাস্ক্রিপ্ট

টাইপস্ক্রিপ্টটি জাভাস্ক্রিপ্টে সংকলন করার সময়, privateকীওয়ার্ডটি সরানো হয়:

class PrivateKeywordClass {
    private value = 1;
}

হয়ে:

class PrivateKeywordClass {
    constructor() {
        this.value = 1;
    }
}

এ থেকে, আপনি privateকীওয়ার্ডটি কোনও রানটাইম সুরক্ষা সরবরাহ করে না তা দেখতে পাবেন : উত্পন্ন জাভাস্ক্রিপ্টে এটি কেবল একটি সাধারণ জাভাস্ক্রিপ্ট সম্পত্তি।

ব্যক্তিগত ক্ষেত্র

ব্যক্তিগত ক্ষেত্রগুলি রানটাইমের সময় সম্পত্তিগুলি ব্যক্তিগত রাখা নিশ্চিত করে :

class PrivateFieldClass {
    #value = 1;

    getValue() { return this.#value; }
}

const obj = new PrivateFieldClass();

// You can't access '#value' outside of class like this
obj.value === undefined // This is not the field you are looking for.
obj.getValue() === 1 // But the class itself can access the private field!

// Meanwhile, using a private field outside a class is a runtime syntax error:
obj.#value

// While trying to access the private fields of another class is 
// a runtime type error:
class Other {
    #value;

    getValue(obj) {
        return obj.#value // TypeError: Read of private field #value from an object which did not contain the field
    }
}

new Other().getValue(new PrivateKeywordClass());

আপনি শ্রেণীর বাইরে কোনও ব্যক্তিগত ক্ষেত্র ব্যবহার করার চেষ্টা করলে টাইপস্ক্রিপ্ট একটি সংকলন সময় ত্রুটিও আউটপুট দেয়:

একটি ব্যক্তিগত ক্ষেত্র অ্যাক্সেস করতে ত্রুটি

ব্যক্তিগত ক্ষেত্রগুলি একটি জাভাস্ক্রিপ্ট প্রস্তাব থেকে আসে এবং সাধারণ জাভাস্ক্রিপ্টেও কাজ করে।

নির্গত জাভাস্ক্রিপ্ট

আপনি যদি টাইপস্ক্রিপ্টে ব্যক্তিগত ক্ষেত্রগুলি ব্যবহার করেন এবং আপনার আউটপুটটির জন্য জাভাস্ক্রিপ্টের পুরানো সংস্করণগুলিকে লক্ষ্য করছেন, যেমন es6বা es2018, টাইপসক্রিপ্ট ব্যক্তিগত ক্ষেত্রগুলির রানটাইম আচরণ অনুকরণ করে এমন কোড উত্পন্ন করার চেষ্টা করবে

class PrivateFieldClass {
    constructor() {
        _x.set(this, 1);
    }
}
_x = new WeakMap();

আপনি যদি লক্ষ্যবস্তুতে থাকেন তবে esnextটাইপস্ক্রিপ্ট ব্যক্তিগত ক্ষেত্রটি নির্গত করবে:

class PrivateFieldClass {
    constructor() {
        this.#x = 1;
    }
    #x;
}

আমার কোনটি ব্যবহার করা উচিত?

এটি আপনি কী অর্জন করার চেষ্টা করছেন তার উপর নির্ভর করে।

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

তবে আপনার যদি esnextব্যক্তিগত সময় ব্যবহারের চেয়ে রানটাইম প্রাইভেট िटी প্রয়োগ করতে হয় বা জাভাস্ক্রিপ্ট আউটপুট করা হয় ।

এছাড়াও মনে রাখবেন যে জাভাস্ক্রিপ্ট / টাইপস্ক্রিপ্ট বাস্তুতন্ত্রের মধ্যে ব্যক্তিগত ক্ষেত্রগুলি আরও বিস্তৃত হওয়ায় একটি বা অন্য ব্যবহারের বিষয়ে সংস্থা / সম্প্রদায় সম্মেলনগুলিও বিকশিত হবে

নোট অন্যান্য পার্থক্য

  • ব্যক্তিগত ক্ষেত্রগুলি Object.getOwnPropertyNamesএবং অনুরূপ পদ্ধতি দ্বারা ফেরত আসে না

  • ব্যক্তিগত ক্ষেত্রগুলি দ্বারা সিরিয়ালীকৃত হয় না JSON.stringify

  • উত্তরাধিকারের আশেপাশে গুরুত্বের ক্ষেত্রগুলি রয়েছে।

    উদাহরণস্বরূপ টাইপস্ক্রিপ্ট সুপারক্লাসে একটি ব্যক্তিগত সম্পত্তি হিসাবে একই নামে একটি সাবক্লাসে একটি ব্যক্তিগত সম্পত্তি ঘোষণা নিষিদ্ধ করে।

    class Base {
        private value = 1;
    }
    
    class Sub extends Base {
        private value = 2; // Compile error:
    }

    এটি ব্যক্তিগত ক্ষেত্রগুলির সাথে সত্য নয়:

    class Base {
        #value = 1;
    }
    
    class Sub extends Base {
        #value = 2; // Not an error
    }
  • একটি privateএকটি সূচনাকারী ছাড়া শব্দ ব্যক্তিগত সম্পত্তি নির্গত জাভাস্ক্রিপ্ট মধ্যে একটি সম্পত্তি ঘোষণা উৎপন্ন না:

    class PrivateKeywordClass {
        private value?: string;
        getValue() { return this.value; }
    }

    সংকলন:

    class PrivateKeywordClass {
        getValue() { return this.value; }
    }

    যেখানে ব্যক্তিগত ক্ষেত্র সর্বদা একটি সম্পত্তি ঘোষণা উত্পন্ন করে:

    class PrivateKeywordClass {
        #value?: string;
        getValue() { return this.#value; }
    }

    সংকলন (লক্ষ্য করার সময় esnext):

    class PrivateKeywordClass {
        #value;
        getValue() { return this.#value; }
    }

আরও পড়া:


4

ব্যবহারের ক্ষেত্রে: # -প্রাইভেট ফিল্ড

মুখবন্ধ:

সংকলন সময় এবং রান-সময় গোপনীয়তা

#- ব্যক্তিগত ক্ষেত্রগুলি সংকলন-সময় এবং রান-টাইম গোপনীয়তা সরবরাহ করে, যা "হ্যাকযোগ্য" নয়। শ্রেণিবদ্ধের বাইরে থেকে কোনও সদস্যের সরাসরি কোনও উপায়ে কোনও সদস্যের প্রবেশ রোধ করার এটি একটি প্রক্রিয়া ।

class A {
    #a: number;
    constructor(a: number) {
        this.#a = a;
    }
}

let foo: A = new A(42);
foo.#a; // error, not allowed outside class bodies
(foo as any).#bar; // still nope.

নিরাপদ শ্রেণির উত্তরাধিকার

#- ব্যক্তিগত ক্ষেত্রগুলি একটি অনন্য সুযোগ পায়। সমান নাম সহ বেসরকারী সম্পত্তির দুর্ঘটনাজনিত ওভাররাইট ছাড়াই শ্রেণিবদ্ধ শ্রেণিবদ্ধকরণ কার্যকর করা যেতে পারে।

class A { 
    #a = "a";
    fnA() { return this.#a; }
}

class B extends A {
    #a = "b"; 
    fnB() { return this.#a; }
}

const b = new B();
b.fnA(); // returns "a" ; unique property #a in A is still retained
b.fnB(); // returns "b"

টিএস সংকলক সৌভাগ্যক্রমে একটি ত্রুটি প্রকাশ করে, যখন privateবৈশিষ্ট্যগুলি ওভাররাইট হওয়ার ঝুঁকিতে থাকে ( উদাহরণটি দেখুন) )। তবে একটি সংকলন-সময় বৈশিষ্ট্যের প্রকৃতির কারণে রান-টাইমে সমস্ত কিছু এখনও সম্ভব, প্রদত্ত সংকলন ত্রুটিগুলি উপেক্ষা করা হয় এবং / অথবা নির্গত জেএস কোডটি ব্যবহার করা হয়।

বাহ্যিক গ্রন্থাগারগুলি

গ্রন্থাগারের লেখকরা #ক্লায়েন্টদের জন্য ব্রেকিং পরিবর্তন না করে সনাক্তকারী-ব্যক্তিগত সনাক্তকারীকে অশোধক করতে পারেন । অন্যদিকে গ্রন্থাগার ব্যবহারকারীরা অভ্যন্তরীণ ক্ষেত্রগুলি অ্যাক্সেস করা থেকে সুরক্ষিত।

জেএস এপিআই- #গোপনীয় ক্ষেত্র বাদ দেয়

অন্তর্নির্মিত জেএস ফাংশন এবং পদ্ধতি-ব্যক্তিগত #ক্ষেত্রগুলিকে উপেক্ষা করে। এটি রান-টাইমে আরও প্রত্যাশিত সম্পত্তি নির্বাচন করতে পারে। উদাহরণ: Object.keys, Object.entries, JSON.stringify, for..inলুপ এবং অন্যদের ( কোড নমুনা ; এছাড়াও ম্যাট Bierner দেখি উত্তর ):

class Foo {
    #bar = 42;
    baz = "huhu";
}

Object.keys(new Foo()); // [ "baz" ]

কেস ব্যবহার করুন: privateকীওয়ার্ড

মুখবন্ধ:

অভ্যন্তরীণ শ্রেণীর এপিআই এবং রাষ্ট্রের অ্যাক্সেস (কেবলমাত্র সংকলন-সময় গোপনীয়তা)

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

টাইপ অ্যাসেরেশন ( as/ <>) এবং anyটাইপড ভেরিয়েবল অ্যাসাইনমেন্ট সহ উদাহরণ :

class A { 
    constructor(private a: number) { }
}

const a = new A(10);
a.a; // TS compile error
(a as any).a; // works
const casted: any = a; casted.a // works

টিএস এমনকি privateএকটি পলায়ন-হ্যাচ সহ কোনও সদস্যের গতিশীল সম্পত্তি অ্যাক্সেসের অনুমতি দেয় :

class C {
  private foo = 10;
}

const res = new C()["foo"]; // 10, res has type number

ব্যক্তিগত অ্যাক্সেসটি কোথায় বোঝায়? (1) ইউনিট পরীক্ষা, (2) ডিবাগিং / লগিং পরিস্থিতি বা (3) প্রকল্পের অভ্যন্তরীণ ক্লাসগুলির (অপেন-শেষ তালিকা) সহ অন্যান্য উন্নত কেস পরিস্থিতি।

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

সমস্ত ES পরিবেশে উপলব্ধ

টিএস privateসংশোধকগুলি সমস্ত ইএস লক্ষ্যমাত্রার সাথে ব্যবহার করা যেতে পারে। #- ব্যক্তিগত ক্ষেত্রগুলি কেবলমাত্র target ES2015/ ES6বা ততোধিকের জন্য উপলব্ধ । ES6 + এ, WeakMapডাউনলিল বাস্তবায়ন হিসাবে অভ্যন্তরীণভাবে ব্যবহৃত হয় ( এখানে দেখুন )। নেটিভ- #প্রাইভেট ক্ষেত্রগুলি বর্তমানে প্রয়োজন target esnext

ধারাবাহিকতা এবং সামঞ্জস্য

দলগুলি privateকেবলমাত্র অ্যাক্সেস মডিফায়ার হিসাবে ব্যবহার প্রয়োগ করতে কোডিং গাইডলাইন এবং লিন্টার নিয়ম ব্যবহার করতে পারে । এই বিধিনিষেধটি ধারাবাহিকতায় সহায়তা করতে পারে এবং #পিছনের সামঞ্জস্যপূর্ণ উপায়ে প্রাইভেট ফিল্ড নোটেশনের সাথে বিভ্রান্তি এড়াতে পারে ।

প্রয়োজনে প্যারামিটারের বৈশিষ্ট্য (কনস্ট্রাক্টর অ্যাসাইনমেন্ট শর্টহ্যান্ড) শো স্টপার are এগুলি কেবল privateকীওয়ার্ডের সাথেই ব্যবহার করা যেতে পারে এবং ব্যক্তিগত- ক্ষেত্রগুলির জন্য এগুলি বাস্তবায়নের কোনও পরিকল্পনা এখনও নেই #

অন্যান্য কারণ

  • privateকিছু ডাউন-লেভেলিং ক্ষেত্রে ভাল রান-টাইম পারফরম্যান্স সরবরাহ করতে পারে ( এখানে দেখুন )।
  • টিএস-তে এখন পর্যন্ত কোনও হার্ড প্রাইভেট ক্লাসের পদ্ধতি উপলব্ধ নেই।
  • কিছু লোক privateকীওয়ার্ড স্বরলিপি পছন্দ করে like

উভয় নোট

উভয় পন্থা সংকলন সময়ে কিছু ধরণের নামমাত্র বা ব্র্যান্ডযুক্ত প্রকার তৈরি করে।

class A1 { private a = 0; }
class A2 { private a = 42; }

const a: A1 = new A2(); 
// error: "separate declarations of a private property 'a'"
// same with hard private fields

এছাড়াও, উভয়ই ক্রস-ইনস্ট্যান্স অ্যাক্সেসের অনুমতি দেয়: শ্রেণির একটি উদাহরণ Aঅন্য Aউদাহরণগুলির ব্যক্তিগত সদস্যদের অ্যাক্সেস করতে পারে :

class A {
    private a = 0;
    method(arg: A) {
        console.log(arg.a); // works
    }
}

সোর্স

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