নিয়মিত ES6 শ্রেণি পদ্ধতি থেকে স্থির পদ্ধতিতে কল করুন


175

স্থির পদ্ধতি কল করার স্ট্যান্ডার্ড উপায় কী? আমি constructorনিজেই ক্লাসের নামটি ব্যবহার বা ব্যবহার করার কথা ভাবতে পারি, কারণ আমি এটি পরে পছন্দ করি না কারণ এটি প্রয়োজনীয় মনে হয় না। প্রাক্তনটি কি প্রস্তাবিত উপায়, বা অন্য কিছু আছে?

এখানে একটি (স্বীকৃত) উদাহরণ:

class SomeObject {
  constructor(n){
    this.n = n;
  }

  static print(n){
    console.log(n);
  }

  printN(){
    this.constructor.print(this.n);
  }
}

8
SomeObject.printপ্রাকৃতিক বোধ হয়। কিন্তু this.nযেহেতু কোন উদাহরণস্বরূপ, যদি আমরা স্ট্যাটিক পদ্ধতি সম্পর্কে কথা বলা হয় ভিতরে কোন মানে নেই।
dfsq

3
@dfsq printNযদিও স্থির নয়।
সাইমনজ্যাক

আপনি ঠিক, বিভ্রান্ত নাম।
dfsq

1
আমি কৌতূহল যে কেন এই প্রশ্নে এতগুলি উত্সাহ নেই! এটি কি ইউটিলিটি ফাংশন তৈরির জন্য সাধারণ অভ্যাস নয়?
থোরান

উত্তর:


210

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

class Super {
  static whoami() {
    return "Super";
  }
  lognameA() {
    console.log(Super.whoami());
  }
  lognameB() {
    console.log(this.constructor.whoami());
  }
}
class Sub extends Super {
  static whoami() {
    return "Sub";
  }
}
new Sub().lognameA(); // Super
new Sub().lognameB(); // Sub

শ্রেণীর মাধ্যমে স্থিতিশীল সম্পত্তি উল্লেখ করা স্থির হবে এবং ক্রমাগত একই মান দেবে। ব্যবহার this.constructorপরিবর্তে গতিশীল প্রেরণ ব্যবহার এবং বর্তমান দৃষ্টান্ত বর্গ, যেখানে স্ট্যাটিক সম্পত্তি পড়ুন হবে পারে উত্তরাধিকারসূত্রে মূল্য আছে কিন্তু উপেক্ষা করা হতে পারে।

এটি পাইথনের আচরণের সাথে মেলে যেখানে আপনি শ্রেণীর নাম বা উদাহরণের মাধ্যমে স্থির বৈশিষ্ট্যগুলি উল্লেখ করতে বেছে নিতে পারেন self

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


আপনি কি নির্মাণকারী সম্পত্তি বনাম শ্রেণির পদ্ধতির সংজ্ঞাটি ব্যাখ্যা করতে পারেন?
ক্রিস

2
@Chris: প্রত্যেক বর্গ হয় একটি কন্সট্রাকটর ফাংশন (ঠিক মত তোমাকে ছাড়া ES5 থেকে এটা জানি classসিনট্যাক্স), সেখানে পদ্ধতির সংজ্ঞা কোন পার্থক্য নেই। উত্তরাধিকার সূত্রে প্রাপ্ত constructorসম্পত্তির মাধ্যমে বা সরাসরি এর নামে আপনি এটি কীভাবে সন্ধান করবেন এটি কেবল বিষয় ।
বার্গি

আর একটি উদাহরণ পিএইচপি এর লেট স্ট্যাটিক বাইন্ডিংস । এটি কেবলমাত্র এই কনস্ট্রাক্টরই উত্তরাধিকারকে সম্মান করে না, তবে আপনি শ্রেণীর নাম পরিবর্তন করলে কোড আপডেট করা এড়াতে সহায়তা করে।
রিচানটোথরুন

@ricanontherun আপনি পরিবর্তনশীল নাম পরিবর্তন করার সময় কোডটি আপডেট করা নাম ব্যবহার করার পক্ষে যুক্তি নয়। এছাড়াও রিফ্যাক্টরিং সরঞ্জামগুলি যে কোনওভাবে এটি স্বয়ংক্রিয়ভাবে করতে পারে।
বার্গি

এটি কীভাবে টাইপস্ক্রিপ্টে প্রয়োগ করবেন? এটি ত্রুটি দেয়Property 'staticProperty' does not exist on type 'Function'
ayZagen

71

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

প্রকারের অ্যাক্সেস

ধরে নিই একটি ক্লাস ফু সম্ভবত অন্য কিছু ক্লাস (এস) থেকে উদ্ভূত সম্ভবত এর থেকে আরও ক্লাস হয়েছে।

তারপরে অ্যাক্সেস করা হচ্ছে

  • স্ট্যাটিক পদ্ধতি / ফু এর প্রাপ্তি থেকে
    • কিছু সম্ভবত ওভাররাইড স্ট্যাটিক পদ্ধতি / গেটার:
      • this.method()
      • this.property
    • কিছু সম্ভবত ওভাররাইড করা উদাহরণ পদ্ধতি / গেটর:
      • নকশা দ্বারা অসম্ভব
    • নিজের অ-ওভাররাইড স্ট্যাটিক পদ্ধতি / গেটর:
      • Foo.method()
      • Foo.property
    • নিজের অ-ওভাররাইড উদাহরণ পদ্ধতি / গেটর:
      • নকশা দ্বারা অসম্ভব
  • উদাহরণ থেকে পদ্ধতি / ফু এর প্রাপ্ত
    • কিছু সম্ভবত ওভাররাইড স্ট্যাটিক পদ্ধতি / গেটার:
      • this.constructor.method()
      • this.constructor.property
    • কিছু সম্ভবত ওভাররাইড করা উদাহরণ পদ্ধতি / গেটর:
      • this.method()
      • this.property
    • নিজের অ-ওভাররাইড স্ট্যাটিক পদ্ধতি / গেটর:
      • Foo.method()
      • Foo.property
    • নিজের অ-ওভাররাইড উদাহরণ পদ্ধতি / গেটর:
      • উদ্দেশ্যপ্রণালী দ্বারা কিছুটা ব্যবহার না করা সম্ভব না :
        • Foo.prototype.method.call( this )
        • Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);

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

পটভূমি

  • যখন কোনও উদাহরণের পদ্ধতি বা গেটের প্রসঙ্গে
    • this বর্তমান উদাহরণ উল্লেখ করা হয়।
    • super মূলত একই উদাহরণটিকে উল্লেখ করছে তবে কিছু শ্রেণীর বর্তমানের প্রসঙ্গে লিখিত কিছু পদ্ধতি এবং গেটারগুলি প্রসারিত হচ্ছে (ফু এর প্রোটোটাইপের প্রোটোটাইপ ব্যবহার করে)।
    • এটি তৈরিতে ব্যবহৃত ক্লাসের সংজ্ঞা প্রতি উপলব্ধ this.constructor
  • কোনও স্থিতিশীল পদ্ধতি বা প্রাপ্তির প্রসঙ্গে যখন উদ্দেশ্য এবং তেমন কোনও "বর্তমান উদাহরণ" থাকে না
    • this সরাসরি বর্তমান বর্গ সংজ্ঞা রেফারেন্স উপলব্ধ উপলব্ধ।
    • super হয় কিছু উদাহরণের উল্লেখ না করে স্থির পদ্ধতি এবং কিছু শ্রেণীর বর্তমানের প্রসঙ্গে লেখা গেটারগুলি প্রসারিত হচ্ছে।

উপসংহার

এই কোড ব্যবহার করে দেখুন:

class A {
  constructor( input ) {
    this.loose = this.constructor.getResult( input );
    this.tight = A.getResult( input );
    console.log( this.scaledProperty, Object.getOwnPropertyDescriptor( A.prototype, "scaledProperty" ).get.call( this ) );
  }

  get scaledProperty() {
    return parseInt( this.loose ) * 100;
  }
  
  static getResult( input ) {
    return input * this.scale;
  }
  
  static get scale() {
    return 2;
  }
}

class B extends A {
  constructor( input ) {
    super( input );
    this.tight = B.getResult( input ) + " (of B)";
  }
  
  get scaledProperty() {
    return parseInt( this.loose ) * 10000;
  }

  static get scale() {
    return 4;
  }
}

class C extends B {
  constructor( input ) {
    super( input );
  }
  
  static get scale() {
    return 5;
  }
}

class D extends C {
  constructor( input ) {
    super( input );
  }
  
  static getResult( input ) {
    return super.getResult( input ) + " (overridden)";
  }
  
  static get scale() {
    return 10;
  }
}


let instanceA = new A( 4 );
console.log( "A.loose", instanceA.loose );
console.log( "A.tight", instanceA.tight );

let instanceB = new B( 4 );
console.log( "B.loose", instanceB.loose );
console.log( "B.tight", instanceB.tight );

let instanceC = new C( 4 );
console.log( "C.loose", instanceC.loose );
console.log( "C.tight", instanceC.tight );

let instanceD = new D( 4 );
console.log( "D.loose", instanceD.loose );
console.log( "D.tight", instanceD.tight );


1
Own non-overridden instance method/getter / not possible by intention unless using some workaround--- এটাই আসল করুণা। আমার মতে এটি ES6 + এর একটি ঘাটতি। সম্ভবত এটি উল্লেখ করার অনুমতি দেওয়ার জন্য আপডেট করা উচিত method- যেমন method.call(this)। এর চেয়ে ভাল Foo.prototype.method। হট্টগোল / ইত্যাদি। একটি এনএফই (নামযুক্ত ফাংশন এক্সপ্রেশন) ব্যবহার করে প্রয়োগ করতে পারে।
রায় টিঙ্কার

method.call( this )methodকাঙ্ক্ষিত বেস "শ্রেণি" এর সাথে আবদ্ধ না হয়ে ব্যতীত একটি সম্ভাব্য সমাধান এবং সুতরাং এটি একটি অ-ওভারডিডেন্স উদাহরণ পদ্ধতি / গেটর হিসাবে ব্যর্থ হয় । শ্রেণি-স্বাধীন পদ্ধতিগুলির সাথে সেভাবে কাজ করা সর্বদা সম্ভব। তবুও আমি মনে করি না বর্তমান ডিজাইনটি খারাপ। আপনার বেস ক্লাস ফু থেকে উত্পন্ন ক্লাসের অবজেক্টের প্রসঙ্গে একটি উদাহরণ পদ্ধতি ওভাররাইড করার জন্য ভাল কারণ থাকতে পারে। এই ওভারডেন পদ্ধতিতে এটির superবাস্তবায়নের জন্য অনুরোধ করার উপযুক্ত কারণ থাকতে পারে । উভয় ক্ষেত্রেই যোগ্য এবং তা মানা উচিত। অন্যথায় এটি খারাপ ওওপি নকশায় শেষ হবে।
থমাস আরবান

ওওপি চিনি থাকা সত্ত্বেও, ইএস পদ্ধতিগুলি এখনও ফাংশন , এবং লোকেদের সেগুলি ব্যবহার এবং উল্লেখ করতে চাইবে। ES বর্গের সিনট্যাক্সের সাথে আমার সমস্যাটি হ'ল এটি বর্তমানে সম্পাদনকারী পদ্ধতির কোনও সরাসরি রেফারেন্স সরবরাহ করে না - এমন কিছু যা arguments.calleeএনএফই এর মাধ্যমে সহজ হতে পারে ।
রায় টিঙ্কার

খারাপ অনুশীলন বা যাইহোক কমপক্ষে খারাপ সফ্টওয়্যার ডিজাইনের মতো শোনাচ্ছে। আমি উভয় দৃষ্টিভঙ্গি একে অপরের বিপরীতে বিবেচনা করব, যেহেতু আমি ওওপি দৃষ্টান্তের প্রসঙ্গে যোগ্য কারণ দেখতে পাচ্ছি না যেখানে বর্তমানে অনুরোধ করা পদ্ধতিটি রেফারেন্সের মাধ্যমে জড়িত রয়েছে (যা কেবলমাত্র এর প্রসঙ্গটি কেবল উপলভ্য নয় this)। এটি উচ্চ স্তরের সি # এর সাথে বেয়ার সি এর পয়েন্টার পাটিগণিতের সুবিধার সাথে মিশ্রিত করার চেষ্টা করার মতো শোনাচ্ছে। কৌতূহলের বাইরে: arguments.calleeআপনি পরিষ্কারভাবে ডিজাইন করা ওওপি কোডটিতে কী ব্যবহার করবেন?
থমাস আরবান

আমি ডোজোর ক্লাস সিস্টেমের সাথে নির্মিত একটি বৃহত প্রকল্পে কাজ করছি, যা বর্তমান পদ্ধতির সুপারক্লাস (এস) বাস্তবায়ন (গুলি) এর মাধ্যমে কল করতে দেয় this.inherited(currentFn, arguments);- যেখানে currentFnবর্তমানে সম্পাদনকারী কার্যটির একটি উল্লেখ রয়েছে। সরাসরি সম্পাদনকারী ক্রিয়াকলাপটি সরাসরি উল্লেখ করতে সক্ষম না হওয়ায় এটি টাইপস্ক্রিপ্টে কিছুটা লোমশ হয়ে উঠছে, যা ES6 থেকে এটির শ্রেণি বাক্য গঠন করে।
রায় টিঙ্কার

20

আপনি যদি কোনও ধরণের উত্তরাধিকার করার পরিকল্পনা করে থাকেন তবে আমি সুপারিশ করব this.constructor। এই সাধারণ উদাহরণটি ব্যাখ্যা করতে হবে কেন:

class ConstructorSuper {
  constructor(n){
    this.n = n;
  }

  static print(n){
    console.log(this.name, n);
  }

  callPrint(){
    this.constructor.print(this.n);
  }
}

class ConstructorSub extends ConstructorSuper {
  constructor(n){
    this.n = n;
  }
}

let test1 = new ConstructorSuper("Hello ConstructorSuper!");
console.log(test1.callPrint());

let test2 = new ConstructorSub("Hello ConstructorSub!");
console.log(test2.callPrint());
  • test1.callPrint()ConstructorSuper Hello ConstructorSuper!কনসোলে লগ হবে
  • test2.callPrint()ConstructorSub Hello ConstructorSub!কনসোলে লগ হবে

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

class NamedSuper {
  constructor(n){
    this.n = n;
  }

  static print(n){
    console.log(NamedSuper.name, n);
  }

  callPrint(){
    NamedSuper.print(this.n);
  }
}

class NamedSub extends NamedSuper {
  constructor(n){
    this.n = n;
  }
}

let test3 = new NamedSuper("Hello NamedSuper!");
console.log(test3.callPrint());

let test4 = new NamedSub("Hello NamedSub!");
console.log(test4.callPrint());
  • test3.callPrint()NamedSuper Hello NamedSuper!কনসোলে লগ হবে
  • test4.callPrint()NamedSuper Hello NamedSub!কনসোলে লগ হবে

উপরের সমস্ত চলমান বাবেল আরপিএলে দেখুন

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


3
কিন্তু স্থির ফাংশন কোনও ওভাররাইড সদস্য পদ্ধতি নয়? সাধারণত আপনি স্থিতিশীলভাবে কোনও ওভাররাইড করা স্টাফ রেফারেন্স না দেওয়ার চেষ্টা করছেন
বার্গি

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

হ্যাঁ, আমি এখন আমার নিজের উত্তরে এই সিদ্ধান্তটি শেষ করেছি যে এটি "ধ্রুপদী" উত্তরাধিকারের মধ্যেও ধারাবাহিকভাবে সমাধান করা যায় না - কখনও কখনও আপনি ওভাররাইডগুলিও পেতে পারেন, কখনও কখনও না। আমার মন্তব্যের প্রথম অংশটি স্থিতিশীল শ্রেণীর ফাংশনগুলিতে ইঙ্গিত করেছে, যা আমি "সদস্য" হিসাবে বিবেচনা করি নি। এটি এড়িয়ে
চলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.