ES6 শ্রেণীর পরিবর্তনশীল বিকল্প


491

বর্তমানে ES5- এ আমরা অনেকে ক্লাস এবং ক্লাস ভেরিয়েবলগুলি তৈরি করতে ফ্রেমওয়ার্কগুলিতে নিম্নোক্ত প্যাটার্ন ব্যবহার করছি যা স্বাচ্ছন্দ্যযুক্ত:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

ES6 এ আপনি স্থানীয়ভাবে ক্লাস তৈরি করতে পারবেন তবে শ্রেণি ভেরিয়েবলগুলি থাকার কোনও বিকল্প নেই:

// ES6
class MyClass {
    const MY_CONST = 'string'; // <-- this is not possible in ES6
    constructor(){
        this.MY_CONST;
    }
}

দুঃখের বিষয়, উপরেরগুলি কাজ করবে না, কারণ ক্লাসে কেবলমাত্র পদ্ধতি থাকতে পারে।

আমি বুঝি যে আমি করতে পারেন this.myVar = trueমধ্যে constructor... কিন্তু আমি বিশেষ করে যখন আমি একটি বড় ক্লাসের জন্য 20-30 + + প্যারাম আছে 'আবর্জনা' আমার কন্সট্রাকটর, এর চাই না।

আমি এই সমস্যাটি হ্যান্ডেল করার জন্য অনেকগুলি উপায় নিয়ে ভাবছিলাম, তবে এখনও কোনও ভাল পাইনি। (উদাহরণস্বরূপ: একটি তৈরি ClassConfigহ্যান্ডলার A, এবং পাস parameterবস্তু, কোন ক্লাস থেকে আলাদাভাবে ঘোষিত হয় তখন হ্যান্ডলার বর্গ সংযুক্ত হবে আমি চিন্তা ছিল।। WeakMaps, এছাড়াও সংহত করতে একরকম।)

এই পরিস্থিতিটি পরিচালনা করতে আপনার কী ধরণের ধারণা থাকতে হবে?


1
আপনার প্রধান সমস্যাটি হ'ল this.member = member20-30 পরামিতিগুলির সাথে আপনার কনস্ট্রাক্টরের পুনরাবৃত্তি হবে ?
25

1
আপনি কি শুধু public variable2 = trueক্লাসের অধীনে ব্যবহার করতে পারবেন না ? এটি প্রোটোটাইপে এটি সংজ্ঞায়িত করবে।

14
@ Θεόφιλος Μουρατίδης: হ্যাঁ, এবং আমি আমার কনস্ট্রাক্টরটি ভেরিয়েবল ঘোষণার জন্য নয়, সূচনা পদ্ধতির জন্য ব্যবহার করতে চাই।
শীতকালীন কাউন্টার 12

@ আডারিলিয়াস: এটিই মূল সমস্যা, এর এমন বৈশিষ্ট্য নেই। এমনকি সরকারী / বেসরকারী ব্যবহারের সিদ্ধান্ত এখনও ES6 খসড়ায় হয়নি। এটিকে একটি পরীক্ষার স্পিন দিন: es6fiddle.net
শীতকালীন

সর্বশেষ অনুসারে, এটির এই ফাংশনটি রয়েছে: wiki.ecmascript.org/doku.php?id=harmony:class

উত্তর:


514

2018 আপডেট:

এখন একটি পর্যায়ে 3 প্রস্তাব রয়েছে - আমি কয়েক মাসের মধ্যে এই উত্তরটি অপ্রচলিত করার জন্য অপেক্ষা করছি।

এর মধ্যে টাইপস্ক্রিপ্ট বা ব্যাবেল ব্যবহার করা যে কেউ সিনট্যাক্সটি ব্যবহার করতে পারেন:

varName = value

শ্রেণীর ঘোষণা / অভিব্যক্তি সংস্থার অভ্যন্তরে এবং এটি একটি পরিবর্তনশীল সংজ্ঞায়িত করবে। আশা করি কয়েক মাস / সপ্তাহের মধ্যে আমি একটি আপডেট পোস্ট করতে সক্ষম হব।

আপডেট: ক্রোম 74 এখন এই সিনট্যাক্সের সাথে কাজ করে।


ES6 এর প্রস্তাবের জন্য ES উইকির নোটসমূহ ( সর্বাধিক ন্যূনতম শ্রেণি ) নোট:

প্রোটোটাইপ ডেটা বৈশিষ্ট্য (পদ্ধতি ব্যতীত) শ্রেণীর বৈশিষ্ট্য বা উদাহরণ সম্পত্তি হিসাবে সংজ্ঞায়নের জন্য (ইচ্ছাকৃতভাবে) কোনও সরাসরি ঘোষণামূলক উপায় নেই

শ্রেণীর বৈশিষ্ট্য এবং প্রোটোটাইপ ডেটা বৈশিষ্ট্যগুলি ঘোষণার বাইরে তৈরি করা দরকার।

শ্রেণীর সংজ্ঞায় বর্ণিত বৈশিষ্ট্যগুলিকে একই বৈশিষ্ট্য নির্ধারণ করা হয় যেন তারা কোনও বস্তুতে আক্ষরিক উপস্থিত হয়।

এর অর্থ হ'ল আপনি যা চাইছেন তা বিবেচনা করা হয়েছিল এবং এর বিরুদ্ধে সুস্পষ্ট সিদ্ধান্ত নেওয়া হয়েছিল।

কিন্তু কেন?

ভাল প্রশ্ন. টিসি 39 এর ভাল লোকেরা শ্রেণীর ঘোষণাকে কোনও শ্রেণীর সক্ষমতা ঘোষণা করতে এবং সংজ্ঞায়িত করতে চায়। এর সদস্য নয়। একটি ES6 শ্রেণির ঘোষণাটি তার ব্যবহারকারীর জন্য এটির চুক্তিটি সংজ্ঞায়িত করে।

মনে রাখবেন, একটি শ্রেণীর সংজ্ঞা প্রোটোটাইপ পদ্ধতিগুলি সংজ্ঞায়িত করে - প্রোটোটাইপে ভেরিয়েবলগুলি সংজ্ঞায়িত করা সাধারণত আপনার কিছু হয় না। আপনি অবশ্যই ব্যবহার করতে পারেন:

constructor(){
    this.foo = bar
}

আপনার মত কনস্ট্রাক্টর মধ্যে। Theকমত্যের সংক্ষিপ্তসারও দেখুন ।

ES7 এবং এর বাইরেও

ES7 এর জন্য একটি নতুন প্রস্তাব কাজ করা হচ্ছে যা শ্রেণীর ঘোষণা এবং অভিব্যক্তিগুলির মাধ্যমে আরও সংক্ষিপ্ত উদাহরণের পরিবর্তনশীলগুলিকে মঞ্জুরি দেয় - https://esdiscuss.org/topic/es7-property-initializer


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

5
আপনি staticবৈশিষ্ট্যগুলি উল্লেখ করতে চাইতে পারেন
বার্গি

8
উফ, মস্তিষ্ক আমি ভুলে গেছি যে staticকেবল পদ্ধতিগুলির জন্যও কাজ করে।
বার্গি

637
হয়তো টিসি 39-তে ভাল লোকেরা এই ধারণার নামটি "শ্রেণি" ব্যতীত অন্য কিছু দেওয়া উচিত যদি তারা না চান যদি প্রোগ্রামিংয়ের বাকি অংশগুলি "শ্রেণি" নামের কিছু থেকে প্রত্যাশা করে।
অ্যালেক্স

7
আরও দেখুন "ক্লাস ক্ষেত্রসমূহ & স্ট্যাটিক বৈশিষ্ট্যাবলী" প্রস্তাব (ইতিমধ্যে বাস্তবায়িত হট্টগোল : github.com/jeffmo/es-class-fields-and-static-properties
ম্যাট ব্রাউনি

127

কেবল বেনিয়ামিনের উত্তরে যুক্ত করতে - শ্রেণি ভেরিয়েবলগুলি সম্ভব তবে আপনি prototypeসেগুলি সেট করতে ব্যবহার করবেন না ।

সত্যিকারের শ্রেণীর পরিবর্তনের জন্য আপনি নীচের মতো কিছু করতে চাই:

class MyClass {}
MyClass.foo = 'bar';

একটি শ্রেণি পদ্ধতির মধ্যে থেকে পরিবর্তনশীল হিসাবে অ্যাক্সেস করা যেতে পারে this.constructor.foo (বা MyClass.foo) ।

এই শ্রেণীর বৈশিষ্ট্যগুলি সাধারণত শ্রেণীর উদাহরণ থেকে অ্যাক্সেসযোগ্য হবে না। অর্থাত্ MyClass.fooদেয়'bar' কিন্তু new MyClass().fooহয়undefined

যদি আপনি কোনও উদাহরণ থেকে আপনার ক্লাস ভেরিয়েবলের অ্যাক্সেস পেতে চান তবে আপনাকে অতিরিক্তভাবে একটি গিটারও সংজ্ঞায়িত করতে হবে:

class MyClass {
    get foo() {
        return this.constructor.foo;
    }
}

MyClass.foo = 'bar';

আমি এটি কেবল ট্রেসারের মাধ্যমে পরীক্ষা করেছি, তবে আমি বিশ্বাস করি এটি একটি স্ট্যান্ডার্ড বাস্তবায়নে একই কাজ করবে।

জাভাস্ক্রিপ্টের আসলে ক্লাস নেই । এমনকি ES6 এর সাথে আমরা কোনও শ্রেণিভিত্তিক ভাষার চেয়ে কোনও অবজেক্ট- বা প্রোটোটাইপ-ভিত্তিক ভাষার দিকে তাকিয়ে আছি। যে কোনও ক্ষেত্রে function X () {}, X.prototype.constructorফিরে যাও X। যখন newঅপারেটর উপর ব্যবহার করা হয় X, একটি নতুন বস্তু inheriting তৈরি করা হয় X.prototype। সেই নতুন অবজেক্টের (অপরিবর্তিত ) কোনও অপরিজ্ঞাত বৈশিষ্ট্য constructorসেখান থেকে সন্ধান করা হবে। আমরা এটিকে উত্পন্ন বস্তু এবং শ্রেণীর বৈশিষ্ট্য হিসাবে ভাবতে পারি।


29

বাবেল ESNext এ ক্লাস ভেরিয়েবল সমর্থন করে, এই উদাহরণটি দেখুন :

class Foo {
  bar = 2
  static iha = 'string'
}

const foo = new Foo();
console.log(foo.bar, foo.iha, Foo.bar, Foo.iha);
// 2, undefined, undefined, 'string'

1
আপনি "#" এর সাথে এটির মতো ভান করে বারটিকে একটি ব্যক্তিগত শ্রেণীর পরিবর্তনশীল করতে পারেন : # বার = 2;
লনি সেরা

26

আপনার উদাহরণে:

class MyClass {
    const MY_CONST = 'string';
    constructor(){
        this.MY_CONST;
    }
}

MY_CONST এর কারণে আদিম https://developer.mozilla.org/en-US/docs/ গ্লোসারি / প্রিমিটিভ আমরা ঠিক করতে পারি:

class MyClass {
    static get MY_CONST() {
        return 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

কিন্তু যদি MY_CONSTমত রেফারেন্স ধরনের static get MY_CONST() {return ['string'];}সতর্কতা আউটপুট স্ট্রিং, মিথ্যা । এই ক্ষেত্রে deleteঅপারেটর কৌশলটি করতে পারেন:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

এবং পরিশেষে ক্লাস ভেরিয়েবলের জন্য নয় const:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    static set U_YIN_YANG(value) {
      delete MyClass.MY_CONST;
      MyClass.MY_CONST = value;
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    set MY_CONST(value) {
        this.constructor.MY_CONST = value;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass
// alert: string, true
MyClass.MY_CONST = ['string, 42']
alert(MyClass.MY_CONST);
new MyClass
// alert: string, 42 ; true

5
deleteপারফরম্যান্সের কারণে একা থাকলে অপারেটরটিকে এড়িয়ে চলুন । আপনি এখানে যা চান তা হ'ল Object.defineProperty
বার্গি

@ শিনজৌ আমিও একই কথা ভাবছিলাম। অগত্যা অপের দোষ অবশ্য নয়; এটি সত্যই এমন ভাষা যা ডেটা উপস্থাপনের জন্য সঠিক পদ্ধতির অভাব বোধ করে যেগুলি তার আসল বিশ্ব সম্পর্কের প্রতিফলন ঘটায়।
ব্যবহারকারী 1974458

17

যেহেতু আপনার সমস্যাটি বেশিরভাগই স্টাইলিস্টিক (একাধিক ঘোষণার সাথে নির্মাণকারী পূরণ করতে চাইছে না) এটি স্টাইলিস্টিকভাবেও সমাধান করা যেতে পারে।

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

"কঠোর ব্যবহার";

ক্লাস মাইক্লাস
{
    // কেবলমাত্র আপনার সম্পত্তি ঘোষণা করুন এবং তারপরে এটিকে কল করুন lass ক্লাসনাম (); এখান থেকে
    কন্সট্রাকটর () {
        this.prop1 = 'ব্লাহ 1';
        this.prop2 = 'ব্লাহ 2';
        this.prop3 = 'ব্লাহ 3';
        this.MyClass ();
    }

    // সমস্ত অন্যান্য "কন্সট্রাক্টর" স্টাফ, ঘোষণার সাথে আর ঝাঁকুনি দেয় না
    আমার ক্লাস() {
        যা ইচ্ছা কর();
    }
}

নতুন দৃষ্টান্তটি নির্মিত হওয়ায় উভয়কেই ডাকা হবে।

2 টি কনস্ট্রাক্টর রাখার মতো সাজ্ট যেখানে আপনি ঘোষণাপত্রগুলি এবং অন্যান্য নির্মাণকারী পদক্ষেপগুলি আলাদা করতে চান এবং স্টাইলিস্টিকালি এটি বুঝতে খুব অসুবিধা হয় না যে এটি কী চলছে।

আমি প্রচুর পরিমাণে ঘোষণাপত্র এবং / অথবা ইনস্ট্যান্টেশন করার সময় প্রচুর ক্রিয়াকলাপ হওয়া এবং দুটি ধারণা একে অপরের থেকে পৃথক রাখতে চাইলে ব্যবহার করার জন্য এটি একটি দুর্দান্ত স্টাইল বলে মনে করি।


দ্রষ্টব্য : আমি খুব উদ্দেশ্যমূলকভাবে "ইনিশিয়ালিং" (যেমন কোনও init()বা initialize()পদ্ধতির মতো) এর আদর্শিক আইডিয়োমেটিক ধারণা ব্যবহার করি না কারণ সেগুলি প্রায়শই আলাদাভাবে ব্যবহৃত হয় used নির্মাণ এবং আরম্ভের ধারণাটির মধ্যে এক ধরণের গণ্যমান পার্থক্য রয়েছে। কনস্ট্রাক্টরদের সাথে কাজ করা লোকেরা জানে যে তারা তাত্ক্ষণিকতার অংশ হিসাবে স্বয়ংক্রিয়ভাবে ডাকা হবে। একটি initপদ্ধতি দেখে অনেক লোক দ্বিতীয় নজরে ছাড়াই ধরে নিচ্ছে যে তাদের ফর্মের সাথে কিছু করা দরকার var mc = MyClass(); mc.init();, কারণ আপনি সাধারণত এভাবেই আরম্ভ করেন। আমি ক্লাসের ব্যবহারকারীর জন্য একটি সূচনা প্রক্রিয়া যুক্ত করার চেষ্টা করছি না, আমি নিজেই ক্লাসের নির্মাণ প্রক্রিয়াতে যুক্ত করার চেষ্টা করছি ।

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


যারা সেই ধরণটি অনুসরণ করতে চান না তাদের পক্ষে ঠিক বিপরীতে কাজ করতে পারে। শুরুর দিকে অন্য কোনও কার্যক্রমে ঘোষণাগুলি ফার্ম করুন। হতে পারে এর নাম "বৈশিষ্ট্য" বা "পাবলিকপ্রপার্টি" বা অন্য কিছু রাখুন। তারপরে বাকী জিনিসগুলি সাধারণ কনস্ট্রাক্টরে রেখে দিন।

"কঠোর ব্যবহার";

ক্লাস মাইক্লাস
{
    বৈশিষ্ট্য ()
        this.prop1 = 'ব্লাহ 1';
        this.prop2 = 'ব্লাহ 2';
        this.prop3 = 'ব্লাহ 3';
    }

    নির্মাতা () {
        this.properties ();
        যা ইচ্ছা কর();
    }
}

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


1
ক্লাসের নাম অনুসারে কোনও প্রোটোটাইপ পদ্ধতি ব্যবহার করবেন না। এটি জেএস-এ অ-পরিচয়যুক্ত, এটিকে অন্য ভাষার মতো দেখানোর চেষ্টা করবেন না। আপনি যদি সত্যই এই পদ্ধতির ব্যবহার করতে চান তবে পদ্ধতির আধ্যাত্মিক নাম init
বার্গি

1
@ বার্গি - initএমন একটি প্যাটার্ন যা প্রায়শই ব্যবহৃত হয় এবং বাইরের ব্যবহারকারী যখন আরম্ভ করতে চায় অর্থাত্ ক্লাসের বাইরে থেকে ডাকা হত var b = new Thing(); b.init();। এটি একটি 100% স্টাইলিস্টিক পছন্দ যা আমি যোগাযোগ করতে পছন্দ করি যে এটি 2 য় ফাংশন যা অন্য ভাষায় প্রাপ্ত নিদর্শনগুলির সুবিধা গ্রহণ করে স্বয়ংক্রিয়ভাবে ডাকা হয়। এটি সম্ভবত খুব কম সম্ভাব্য যে কেউ এটিকে দেখবে এবং ধরে নেবে যে তাদের MyClassবাইরে থেকে পদ্ধতিটি কল করার দরকার রয়েছে , সম্ভবত তারা বুঝতে পারে যে এই উদ্দেশ্যটি নির্মাণে কাজ করা একটি দ্বিতীয় পদ্ধতি (অর্থাত্ স্বীকৃতিতে নিজেই ডাকা)।
জিম্বো জনি

এইচএম, আমি বুঝতে পারি যে কন্সট্রাক্টরের দিকে তাকিয়ে, তবে পদ্ধতির নাম থেকে নয় MyClass
বার্গি

1
@ বার্গি - অন্য কোনও ভাষা থেকে একটি নিদর্শন নিয়ে জেএসকে এমনভাবে প্রয়োগ করা হচ্ছে যা প্রযুক্তিগতভাবে ঘটছে না, তবে এখনও কাজ করে নজিরবিহীন পুরোপুরি নয়। আপনি আমাকে বলতে পারবেন না যে কেউ $myvarজ্যাচুরির বিষয়বস্তু ধরে রাখার উদ্দেশ্যে ভেরিয়েবলগুলি উল্লেখ করার মানক উপায়টি ভেরিয়েবলের শুরুতে যেমন এতগুলি পিএইচপি প্রোগ্রামারদের ব্যবহৃত হয় তার প্যাটার্নের সাথে সুবিধামত নয়। "এই হ্যাঁ, এটি ঠিক একই জিনিস নয় ... তবে দেখুন ... এটি এখনও একটি পরিবর্তনশীল কারণ এটি কিছু ভাষায় ভেরিয়েবলগুলি করা হয়!" সাহায্য করে।
জিম্বো জনি

1
আমি properties()ফাংশন দিয়ে আপনার শেষ বিকল্প পছন্দ । যাইহোক, ক্লাসগুলি প্রসারিত করার সময় জিনিসগুলি আরও জটিল হয়ে ওঠে তাই আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি যদি properties()শ্রেণীর বৈশিষ্ট্যগুলি ঘোষণার জন্য আপনার সমস্ত শ্রেণীর একটি ফাংশন ব্যবহার করেন যা আপনি শ্রেণীর নামের সাথে পদ্ধতিটির নাম উপস্থাপন করেন (IE: MyClassProperties()দুর্ঘটনাক্রমে ওভাররাইডিং এড়াতে যাতে সাব ক্লাসের মধ্যে ফাংশন super()
কলগুলিও

14

পুরাতন স্কুল পথে কী হবে?

class MyClass {
     constructor(count){ 
          this.countVar = 1 + count;
     }
}
MyClass.prototype.foo = "foo";
MyClass.prototype.countVar = 0;

// ... 

var o1 = new MyClass(2); o2 = new MyClass(3);
o1.foo = "newFoo";

console.log( o1.foo,o2.foo);
console.log( o1.countVar,o2.countVar);

কন্সট্রাক্টর আপনি কেবলমাত্র সেই ভারগুলির উল্লেখ করেছেন যা গুণতে হবে। আমি এই বৈশিষ্ট্যটির জন্য প্রোটোটাইপ উত্তরাধিকার পছন্দ করি - এটি প্রচুর স্মৃতি সঞ্চয় করতে সহায়তা করতে পারে (যদি কখনও কখনও বরাদ্দ না করা ভার্সেস থাকে তবে)।


4
এটি মেমরিটি সংরক্ষণ করে না এবং এটি আপনাকে নির্মাণকারীর মধ্যে ঘোষণা করে দিলে কর্মক্ষমতাটি আরও খারাপ করে তোলে। codereview.stackexchange.com/a/28360/9258
Esailija

2
এছাড়াও, এটি প্রথম স্থানে ইএস 6 ক্লাস ব্যবহারের উদ্দেশ্যকে পরাস্ত করে। এটি যেমন দাঁড়িয়ে আছে, বাস্তব ওওপ শ্রেণীর মতো ES6 ক্লাস ব্যবহার করা খুব কমই সম্ভব বলে মনে হচ্ছে ... যা কিছুটা হতাশাব্যঞ্জক ...
কোকোডোকো

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

2
যদিও এটি কেবল ভাষা বাক্য গঠন সম্পর্কে নয়। ওওপি দর্শন সাধারণত প্রোগ্রামিংয়ে নিজেকে বেশ ভাল ধার দেয় - বিশেষত অ্যাপস এবং গেমস তৈরি করার সময়। জেএস traditionতিহ্যগতভাবে ওয়েবপৃষ্ঠা তৈরিতে কার্যকর হয়েছে যা একেবারেই আলাদা। অ্যাপগুলি সম্পর্কে ওয়েব আরও বাড়ছে বলে যে কোনওভাবে এই দুটি পদ্ধতির একসাথে হওয়া দরকার।
কোকোডোকো

1
@ কোকোডোকো কেবল এটি ভিন্ন OOP এর অর্থ এটি ওওপি নয় । প্রোটোটাইপগুলি একটি 100% বৈধ ওওপি পদ্ধতি; কেউ স্বকে "নন-ওওপি" বলবে না কারণ এটি প্রোটোটাইপ ব্যবহার করে। অন্য ওওপি দৃষ্টান্তের সাথে মেলে না মানে কেবল এটি: এটি আলাদা।
ডেভ নিউটন

13

যেমন বেনিয়ামিন তার উত্তরে বলেছিলেন, টিসি 39 স্পষ্টভাবে সিদ্ধান্ত নিয়েছে কমপক্ষে ES2015 এর জন্য এই বৈশিষ্ট্যটি অন্তর্ভুক্ত করা হবে না। যাইহোক, theক্যমত্য বলে মনে হচ্ছে যে তারা এটি ES2016 এ যুক্ত করবে।

সিনট্যাক্সটি এখনও স্থির হয়নি, তবে ES2016 এর প্রাথমিক প্রস্তাব রয়েছে যা আপনাকে কোনও শ্রেণিতে স্থিতিশীল সম্পত্তি ঘোষণা করতে দেয় to

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

class foo {
  static myProp = 'bar'
  someFunction() {
    console.log(this.myProp)
  }
}

এই প্রস্তাবটি খুব প্রাথমিক অবস্থায় রয়েছে, তাই সময় বাড়ার সাথে সাথে আপনার সিনট্যাক্সটিকে টুইঙ্ক করার জন্য প্রস্তুত থাকুন।


হ্যাঁ, এটি ES6 নয়। এটি কী তা আপনি যদি না জানেন তবে আপনার এটি ব্যবহার করা উচিত নয়।
বার্গি

10

[দীর্ঘ থ্রেড, এটি ইতিমধ্যে বিকল্প হিসাবে তালিকাভুক্ত কিনা তা নিশ্চিত নয় ...]। কেবল প্রতিযোগীদের জন্য
একটি সহজ বিকল্প , শ্রেণির বাইরে কনস্টকে সংজ্ঞায়িত করা হবে। এটি কেবলমাত্র মডিউল থেকেই অ্যাক্সেসযোগ্য হবে, যদি না কোনও গ্রাহকের সাথে থাকে।
এই ভাবে prototypeকোনও জঞ্জাল নয় এবং আপনি এটি পান const

// will be accessible only from the module itself
const MY_CONST = 'string'; 
class MyClass {

    // optional, if external access is desired
    static get MY_CONST(){return MY_CONST;}

    // access example
    static someMethod(){
        console.log(MY_CONST);
    }
}

যদি আপনি ক) 2 এর varপরিবর্তে একটি constব্যবহার করেন) এই শ্রেণীর একাধিক উদাহরণ ব্যবহার করবেন? তারপরে বাহ্যিক ভেরিয়েবলগুলি ক্লাসের প্রতিটি উদাহরণের সাথে পরিবর্তিত হবে
নিক কারাওয়ে

1
ব্যর্থ পয়েন্ট @ নিকক্রারওয়ে, আমার অফারটি কেবল কনস্টের জন্য দাঁড়িয়েছে, প্রশ্নের শিরোনাম হিসাবে নয়।
হার্টজেল গিনেস

6

ES7 শ্রেণীর সদস্য বাক্য গঠন:

ES7আপনার কনস্ট্রাক্টর ফাংশন 'জঙ্কিং' এর জন্য একটি সমাধান রয়েছে। এখানে একটি উদাহরণ:

class Car {
  
  wheels = 4;
  weight = 100;

}

const car = new Car();
console.log(car.wheels, car.weight);

উপরের উদাহরণটি নিম্নলিখিতটি দেখবে ES6:

class Car {

  constructor() {
    this.wheels = 4;
    this.weight = 100;
  }

}

const car = new Car();
console.log(car.wheels, car.weight);

এটি ব্যবহার করার সময় সচেতন হন যে এই সিনট্যাক্সটি সমস্ত ব্রাউজারগুলির দ্বারা সমর্থিত না হতে পারে এবং জেএসের পূর্ববর্তী সংস্করণটি স্থানান্তর করতে হতে পারে।

বোনাস: একটি অবজেক্ট কারখানা:

function generateCar(wheels, weight) {

  class Car {

    constructor() {}

    wheels = wheels;
    weight = weight;

  }

  return new Car();

}


const car1 = generateCar(4, 50);
const car2 = generateCar(6, 100);

console.log(car1.wheels, car1.weight);
console.log(car2.wheels, car2.weight);


3
আপনি ক্লাস ভেরিয়েবল নয়, উদাহরণ ভেরিয়েবলগুলি সম্পন্ন করেছেন।
তাজাদ ক্লার্ক

5

আপনি es6 শ্রেণীর আচরণের নকল করতে পারেন ... এবং আপনার শ্রেণীর ভেরিয়েবলগুলি ব্যবহার করতে পারেন :)

মা দেখ ... ক্লাস নেই!

// Helper
const $constructor = Symbol();
const $extends = (parent, child) =>
  Object.assign(Object.create(parent), child);
const $new = (object, ...args) => {
  let instance = Object.create(object);
  instance[$constructor].call(instance, ...args);
  return instance;
}
const $super = (parent, context, ...args) => {
  parent[$constructor].call(context, ...args)
}
// class
var Foo = {
  classVariable: true,

  // constructor
  [$constructor](who){
    this.me = who;
    this.species = 'fufel';
  },

  // methods
  identify(){
    return 'I am ' + this.me;
  }
}

// class extends Foo
var Bar = $extends(Foo, {

  // constructor
  [$constructor](who){
    $super(Foo, this, who);
    this.subtype = 'barashek';
  },

  // methods
  speak(){
    console.log('Hello, ' + this.identify());
  },
  bark(num){
    console.log('Woof');
  }
});

var a1 = $new(Foo, 'a1');
var b1 = $new(Bar, 'b1');
console.log(a1, b1);
console.log('b1.classVariable', b1.classVariable);

আমি এটি গিটহাবের উপরে রেখেছি


0

আমি যেভাবে এটি সমাধান করেছি, এটি অন্য একটি বিকল্প (যদি আপনার কাছে jQuery উপলব্ধ থাকে) হ'ল একটি পুরানো-স্কুল অবজেক্টে ক্ষেত্রগুলি সংজ্ঞায়িত করা এবং তারপরে সেই অবজেক্ট সহ শ্রেণিটি প্রসারিত করা। আমি নির্ধারককে অ্যাসাইনমেন্ট সহ মরিচও দিতে চাইনি, এটি একটি ঝরঝরে সমাধান বলে মনে হয়েছিল।

function MyClassFields(){
    this.createdAt = new Date();
}

MyClassFields.prototype = {
    id : '',
    type : '',
    title : '',
    createdAt : null,
};

class MyClass {
    constructor() {
        $.extend(this,new MyClassFields());
    }
};

- বার্গির মন্তব্য অনুসরণ করে আপডেট করুন।

কোন জিকুয়ের সংস্করণ নেই:

class SavedSearch  {
    constructor() {
        Object.assign(this,{
            id : '',
            type : '',
            title : '',
            createdAt: new Date(),
        });

    }
}

আপনি এখনও 'ফ্যাট' কনস্ট্রাক্টর দিয়ে শেষ করেন তবে কমপক্ষে এটি সমস্তই এক শ্রেণিতে এবং এক হিট হিসাবে নির্ধারিত হয়।

সম্পাদনা # 2: আমি এখন পুরো বৃত্তে চলে এসেছি এবং এখন নির্মাতায় মান নির্ধারণ করছি, যেমন eg

class SavedSearch  {
    constructor() {
        this.id = '';
        this.type = '';
        this.title = '';
        this.createdAt = new Date();
    }
}

কেন? সত্যই সহজ, উপরোক্ত প্লাস কিছু জেএসডোক মন্তব্য ব্যবহার করে, পিএইচপিএসটারম বৈশিষ্ট্যগুলিতে কোড সমাপ্তি সম্পাদন করতে সক্ষম হয়েছিল। সমস্ত ভারকে এক হিট হিসাবে অর্পণ করা দুর্দান্ত ছিল, তবে বৈশিষ্ট্যগুলি সম্পূর্ণ করতে কোড অক্ষমতা, তবে, (প্রায় অবশ্যই বিয়োগ) পারফরম্যান্স সুবিধার জন্য উপযুক্ত নয়।


2
আপনি যদি classসিনট্যাক্স করতে পারেন তবে আপনিও করতে পারেন Object.assign। JQuery প্রয়োজন নেই।
বার্গি

আমি MyClassFieldsকনস্ট্রাক্টর তৈরির কোনও বিন্দু দেখতে পাচ্ছি না - এর কোনও পদ্ধতি নেই। আপনি কীভাবে এটি ব্যাখ্যা করতে পারেন (এর পরিবর্তে, বলুন, একটি সাধারণ কারখানার ফাংশন যা কোনও বস্তুকে আক্ষরিক ফিরিয়ে দেয়)?
বার্গি

@ বার্গি - সৎ হওয়ার জন্য সম্ভবত অন্য কোনও কিছুর চেয়ে অভ্যাসের জোর করা। Object.assign সম্পর্কেও দুর্দান্ত কল - এটি সম্পর্কে জানতেন না!
স্টিভ চাইল্ডস

0

ঠিক আছে, আপনি কনস্ট্রাক্টরের ভিতরে ভেরিয়েবল ঘোষণা করতে পারেন।

class Foo {
    constructor() {
        var name = "foo"
        this.method = function() {
            return name
        }
    }
}

var foo = new Foo()

foo.method()

1
এই পরিবর্তনশীলটি ব্যবহার করার জন্য আপনাকে এই শ্রেণীর একটি উদাহরণ তৈরি করতে হবে। স্ট্যাটিক ফাংশনগুলি এই পরিবর্তনশীলটি অ্যাক্সেস করতে পারে না
আদিত্য

0

তবুও আপনি অন্য প্রোগ্রামিং ভাষার মতো কোনও ক্লাস ঘোষণা করতে পারবেন না। তবে আপনি যতগুলি ক্লাস ভেরিয়েবল তৈরি করতে পারেন। তবে সমস্যা হ'ল শ্রেণীর অবজেক্টের সুযোগ। সুতরাং আমার মতে, ES6 জাভাস্ক্রিপ্টে সেরা উপায় ওওপি প্রোগ্রামিং: -

class foo{
   constructor(){
     //decalre your all variables
     this.MY_CONST = 3.14;
     this.x = 5;
     this.y = 7;
     // or call another method to declare more variables outside from constructor.
     // now create method level object reference and public level property
     this.MySelf = this;
     // you can also use var modifier rather than property but that is not working good
     let self = this.MySelf;
     //code ......... 
   }
   set MySelf(v){
      this.mySelf = v;
   }
   get MySelf(v){
      return this.mySelf;
   }
   myMethod(cd){
      // now use as object reference it in any method of class
      let self = this.MySelf;
      // now use self as object reference in code
   }
}

-1

এটি স্ট্যাটিকের সামান্য হ্যাকিশ কম্বো এবং আমার জন্য কাজগুলি পান

class ConstantThingy{
        static get NO_REENTER__INIT() {
            if(ConstantThingy._NO_REENTER__INIT== null){
                ConstantThingy._NO_REENTER__INIT = new ConstantThingy(false,true);
            }
            return ConstantThingy._NO_REENTER__INIT;
        }
}

অন্য কোথাও ব্যবহৃত

var conf = ConstantThingy.NO_REENTER__INIT;
if(conf.init)...

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