ES6 শ্রেণীর উদাহরণের শ্রেণীর নাম পান


156

ES6 শ্রেণীর উদাহরণ থেকে শ্রেণীর নাম পাওয়ার জন্য কি কোনও 'সুরেলা' উপায় আছে? আর অন্যান্য

someClassInstance.constructor.name

বর্তমানে আমি ট্রেসুর বাস্তবায়নে গণনা করছি। এবং মনে হয় যে বাবেলের একটি পলফিল রয়েছে Function.nameযখন ট্রেসুরের নেই।

সব মিলিয়ে সংক্ষেপে: ES6 / ES2015 / সম্প্রীতির অন্য কোনও উপায় ছিল না, এবং ES.Next- তে কোনও কিছুই প্রত্যাশিত নয়।

এটি অবিচলিত সার্ভার-সাইড অ্যাপ্লিকেশনগুলির জন্য দরকারী নিদর্শন সরবরাহ করতে পারে তবে ব্রাউজার / ডেস্কটপ / মোবাইলের জন্য ব্যবহৃত অ্যাপ্লিকেশনগুলিতে অযাচিত।

ব্যাবেল পলিফিল ব্যবহারcore-js করে Function.name, এটি ট্রেসুর এবং টাইপস্ক্রিপ্ট অ্যাপ্লিকেশনগুলির পক্ষে যথাযথভাবে লোড করা উচিত।


2
আমি একই বিষয়টি জুড়ে এসেছি; ট্রেসারের একমাত্র সমাধান ছিল নামটি বের করার জন্য প্রকৃত শ্রেণীর কোডটি নিজেই বিশ্লেষণ করা, যা আমি মনে করি না যে এটি সুরেলা হিসাবে যোগ্য। আমি কেবল পিলটি গ্রাস করে বাবেলের দিকে চলে গেলাম; ট্রেসারের বিকাশ কিছুটা স্থবির বলে মনে হচ্ছে এবং অনেকগুলি ES6 বৈশিষ্ট্যগুলি খারাপভাবে প্রয়োগ করা হয়নি। যেমনটি আপনি উল্লেখ করেছেন, instance.constructor.nameএবং class.nameযথাযথ ES6 এ শ্রেণীর নামটি ফিরিয়ে দিন।
অ্যান্ড্রু ওড্রি

একমাত্র উপায় বলে মনে হচ্ছে।
ফ্রেডেরিক ক্রাউটওয়াল্ড

এটি কি ES6 স্ট্যান্ডার্ডে রয়েছে?
drudru

12
এটি উল্লেখ করার মতো যে someClassInstance.constructor.nameআপনি যদি নিজের কোডটি অগলিফ করেন তবে ম্যাঙ্গাল হয়ে যাবেন।
জেমসবি

stackoverflow.com/questions/2648293/… এটিকে দেখতে চাইলে ডাব্লু / এ কাজ করা উচিত .constructor
ফ্লোরি

উত্তর:


204

someClassInstance.constructor.nameএটি করার সঠিক উপায়। স্থানান্তরকারীরা এটি সমর্থন নাও করতে পারে তবে এটি নির্দিষ্টকরণের মান অনুসারে। ( nameক্লাসডেক্লারেশন প্রোডাকশনের মাধ্যমে ঘোষিত ফাংশনের সম্পত্তি 14.5.15 , ধাপ in এ সেট করা হয়েছে )


2
এটাই আমার ভয় ছিল। আপনি কি এর জন্য কোনও যুক্তিসঙ্গত পলিফিল সম্পর্কে অবগত আছেন? আমি বুঝতে চেষ্টা করেছি যে বাবেল এটি কী করে তবে খুব কম সাফল্য পেয়েছিল।
এস্তাস ফ্লাস্ক

কোনও ভাষা বৈশিষ্ট্য (ক্লাস) এর জন্য পলিফিল বলতে কী বোঝাতে চেয়েছি তা আমি সত্যিই জানি না।
ডোমেনিক

আমার অর্থ কনস্ট্রাক্টর.নামের পলিফিল। দেখে মনে হচ্ছে এটি ব্যাবেল বাস্তবায়ন করেছে, তবে এটি কীভাবে তা বুঝতে পেরে আমি সফল হইনি।
এস্তাস ফ্লাস্ক

2
@estus someClassInstance.constructorএকটি ফাংশন। সমস্ত ক্রিয়াকলাপের একটি nameসম্পত্তি রয়েছে যা এর নামে সেট করা আছে। এজন্য বাবেলের কিছু করার দরকার নেই। দয়া করে বিকাশকারী.মোজিলা.অর্গ.ইন-
এস্তেবান

2
@ ইস্তেবান এটি প্রদর্শিত হয় যে ব্যাবেল অবিচ্ছিন্নভাবে কোর-জেএস পলফিলগুলি প্রচার করে (ফাংশন.নামের জন্য একটি পলিফিল সহ), এজন্য কিছু বাবেল বিল্ডস সমস্ত ব্রাউজারে বক্সের বাইরে কাজ করতে পারে।
এস্তাস ফ্লাস্ক

52

যেমন @ ডোমেনিক বলেছেন, ব্যবহার করুন someClassInstance.constructor.name। @ স্টেস্টাবান মন্তব্যগুলিতে উল্লেখ করেছেন যে

someClassInstance.constructorএকটি ফাংশন। সমস্ত ক্রিয়াকলাপের একটি nameসম্পত্তি আছে ...

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

class SomeClass {
  constructor() {}
}

var someClassInstance = new SomeClass();
someClassInstance.constructor.name;      // === 'SomeClass'
SomeClass.name                           // === 'SomeClass'

হালনাগাদ

বাবেল ঠিকঠাক ছিল, তবে কুশলী / মিনিফিকেশনটি আমার সমস্যার কারণ হয়েছিল। আমি একটি গেম তৈরি করছি, এবং পুলযুক্ত স্প্রাইট সংস্থানগুলির একটি হ্যাশ তৈরি করছি (যেখানে কীটির ফাংশনটির নাম)। সংশোধনের পরে, প্রতিটি ফাংশন / শ্রেণীর নামকরণ করা হয়েছিল t। এটি হ্যাশটিকে হত্যা করে। আমি Gulpএই প্রকল্পে ব্যবহার করছি , এবং আমি আবিষ্কার করেছি যে gulp-uglify ডক্সটি পড়ার পরে এই স্থানীয় ভেরিয়েবল / ফাংশন নামের ম্যাংলিং ঘটতে না দেওয়ার জন্য একটি প্যারামিটার রয়েছে। সুতরাং, আমার gulpfile আমি পরিবর্তন

.pipe($.uglify()) প্রতি .pipe($.uglify({ mangle: false }))

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

হালনাগাদ

মন্তব্যে আলোচনার পরে, মনে হয় যে .nameএই ফাংশনগুলি সংজ্ঞায়নের পক্ষে কনভেনশন এড়ানো একটি ভাল দৃষ্টান্ত। এটি কেবল কয়েকটি লাইনের কোড নেয় এবং এটি আপনার কোডের সম্পূর্ণ সংশোধন ও সাধারণতার অনুমতি দেয় (কোনও লাইব্রেরিতে ব্যবহৃত হলে)। সুতরাং আমি অনুমান করি আমি আমার মন পরিবর্তন করেছি এবং getClassNameআমার ক্লাসগুলির জন্য ম্যানুয়ালি সংজ্ঞা দেব। ধন্যবাদ @estus! । গেটর / সেটারগুলি সাধারণত যে কোনওভাবে সরাসরি চলক অ্যাক্সেসের তুলনায় বিশেষত একটি ধারণা, বিশেষত ক্লায়েন্ট ভিত্তিক অ্যাপ্লিকেশনটিতে।

class SomeClass {
  constructor() {}
  static getClassName(){ return 'SomeClass'; }
  getClassName(){ return SomeClass.getClassName(); }
}
var someClassInstance = new SomeClass();
someClassInstance.constructor.getClassName();      // === 'SomeClass' (static fn)
someClassInstance.getClassName();                  // === 'SomeClass' (instance fn)
SomeClass.getClassName()                           // === 'SomeClass' (static fn)

3
ম্যাংলিং সম্পূর্ণরূপে অক্ষম করা খুব ভাল ধারণা নয় কারণ ম্যাংলিং অনেক পরিমাণে খাটায় অবদান রাখে। বিষয়টিকে ক্লায়েন্ট-সাইড কোডে প্রথম স্থানে ব্যবহার করা খুব ভাল ধারণা নয়, তবে ক্লাসগুলি reservedউগলিফ বিকল্পের সাথে ম্যাংলিং থেকে রক্ষা করা যেতে পারে (ক্লাসগুলির একটি তালিকা রেজিএক্সপ্যাক বা যে কোনও কিছুতে পাওয়া যেতে পারে)।
এস্তাস ফ্লাস্ক

খুবই সত্য. আরও বড় আকারের ফাইলের বাণিজ্য রয়েছে। দেখে মনে হচ্ছে আপনি কেবলমাত্র নির্বাচিত আইটেমগুলির জন্য ম্যাঙ্গিলিং রোধ করতে আপনি RegEx কীভাবে ব্যবহার করতে পারেন । এটির অর্থ কী? "ক্লায়েন্ট-সাইড কোডটিতে বিষয়টি ব্যবহার করা খুব ভাল ধারণা নয়"? এটি কিছু পরিস্থিতিতে সুরক্ষা ঝুঁকি উপস্থাপন করবে?
জেমস এল।

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

ঠিক আছে সুতরাং ম্যানলিং হেল্প পেতে এবং সম্পূর্ণ ক্ষুদ্রাকরণের অনুমতি দেওয়ার জন্য (কোনও বিরক্তিকর RegEx ছাড়াই) 2 getClassName ফাংশনগুলি (স্ট্যাটিক & উদাহরণ) ম্যানুয়ালি সংজ্ঞায়নের প্রস্তাব দিচ্ছেন। লাইব্রেরি সম্পর্কে এই পয়েন্টটি অনেক অর্থবোধ করে। প্রচুর বোধ করে। আমার জন্য, আমার প্রকল্পটি একটি স্ব-নির্মিত ছোট কর্ডোভা অ্যাপ্লিকেশন, সুতরাং এগুলি আসলে সমস্যা নয়। এর বাইরে যে কোনও কিছুই আমি এই সমস্যাগুলি উঠতে দেখছি। আলোচনার জন্য ধন্যবাদ! আপনি যদি পোস্টটিতে কোনও উন্নতির কথা ভাবতে পারেন তবে এটি সম্পাদনা করতে নির্দ্বিধায়
জেমস এল।

1
হ্যাঁ, আমি প্রাথমিকভাবে nameক্লাসের নাম থেকে শ্রেণি (পরিষেবা, প্লাগইন, ইত্যাদি) ব্যবহার করে এমন সত্তার নাম বের করার জন্য ডিআরওয়াই কোড ব্যবহার করেছি , তবে শেষ পর্যন্ত আমি দেখতে পেয়েছি যে এটি স্ট্যাটিক প্রোপ ( id, _name) দিয়ে স্পষ্টভাবে এটির সদৃশ হয়ে গেছে শুধুমাত্র সবচেয়ে দৃ .় পদ্ধতির। একটি ভাল বিকল্প হ'ল শ্রেণীর নাম সম্পর্কে যত্ন না করা, একটি শ্রেণি নিজেই (ফাংশন অবজেক্ট) এই শ্রেণীর সাথে ম্যাপ করা কোনও সত্তা এবং importযেখানে প্রয়োজন সেখানে এটি সনাক্তকারী হিসাবে ব্যবহার করুন (কৌনিক 2 ডিআই দ্বারা ব্যবহৃত একটি পদ্ধতির)।
এস্তাস ফ্লাস্ক

8

ক্লাস থেকে সরাসরি ক্লাসের নাম পাওয়া

পূর্ববর্তী উত্তরগুলি ব্যাখ্যা করেছে যে someClassInstance.constructor.nameঠিক কাজ করে, তবে আপনার যদি প্রোগ্রামিকভাবে শ্রেণিক নামটিকে স্ট্রিংয়ে রূপান্তর করতে হয় এবং কেবলমাত্র এর জন্য কোনও উদাহরণ তৈরি করতে না চান তবে মনে রাখবেন:

typeof YourClass === "function"

এবং, যেহেতু প্রতিটি ফাংশনের একটি nameসম্পত্তি থাকে, তাই আপনার শ্রেণীর নামের সাথে একটি স্ট্রিং পাওয়ার আরও একটি দুর্দান্ত উপায় হ'ল:

YourClass.name

নিম্নলিখিতগুলি কেন এটি কার্যকর তার একটি ভাল উদাহরণ।

ওয়েব উপাদান লোড হচ্ছে

হিসাবে MDN ডকুমেন্টেশন আমাদের শিক্ষা দেয়, কিভাবে এই আপনি একটি ওয়েব উপাদান লোড হল:

customElements.define("your-component", YourComponent);

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

function registerComponent(componentClass) {
    const componentName = upperCamelCaseToSnakeCase(componentClass.name);
    customElements.define(componentName, componentClass);
}

সুতরাং আপনাকে যা করতে হবে তা হ'ল:

registerComponent(YourComponent);

যা দুর্দান্ত কারণ এটি নিজেই উপাদান লেখার চেয়ে ত্রুটি-প্রবণতা কম। এটিকে মোড়ানোর জন্য, এটি upperCamelCaseToSnakeCase()ফাংশন:

// converts `YourString` into `your-string`
function upperCamelCaseToSnakeCase(value) {
    return value
        // first char to lower case
        .replace(/^([A-Z])/, $1 => $1.toLowerCase())
        // following upper chars get preceded with a dash
        .replace(/([A-Z])/g, $1 => "-" + $1.toLowerCase());
}

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

হ্যাঁ, আপনি পুরোপুরি ঠিক বলেছেন। কাজের জন্য এই পদ্ধতির জন্য ক্লাসের নামগুলি স্পর্শ না করার জন্য মিনিফায়ারটি কনফিগার করতে হবে।
লুসিও পাইভা

1

বাবেল প্রতিস্থাপনের জন্য (ম্যানিফিকেশনের আগে)

আপনি যদি বাবেলের সাথে @babel/preset-envএটি ব্যবহার করে থাকেন তবে ক্লাসের সংজ্ঞাগুলি ফাংশনে রূপান্তর না করেই রাখা সম্ভব (যা constructorসম্পত্তি সরিয়ে দেয় )

আপনি এই কনফিগারেশনের সাথে কিছু পুরানো ব্রাউজারের সামঞ্জস্যতা আপনার মধ্যে ফেলে দিতে পারেন babel.config / babelrc:

{
  "presets": [
    ["@babel/preset-env", {"targets": {"browsers": ["> 2%"]}}]
  ]
}

সম্পর্কে আরও তথ্য targets: https://babeljs.io/docs/en/babel-preset-env#targets

বাবেল শোধনের জন্য (প্রতিস্থাপনের পরে)

দেখে মনে হচ্ছে এখনই কোনও সহজ সমাধান নেই ... আমাদের ম্যাঙ্গালিংয়ের বাদ পড়ার দিকে নজর দেওয়া উচিত।


এটি কীভাবে সংশোধনের ক্ষেত্রে সাহায্য করার কথা বলে আপনি আরও ব্যাখ্যা করতে পারেন? কোনও লক্ষ্য সহ class Foo {}এমন কিছুতে সংযুক্ত করা হবে class a{}Fooমিনাইডেড সোর্স কোডে কোনও শব্দ থাকবে না ।
এস্তাস ফ্লাস্ক

সত্যিই আমি নথির চেয়ে বেশি খনন করতে পারি নি এবং সত্য যে এটি আমাকে এই কনফিগারেশনটি ব্যবহার করতে সহায়তা করেছে ... আমি ইবিএসওয়াই ব্যাবেল ট্রান্সপ্লাইড প্রকল্পে ব্যবহার করছি এবং বৈধ শ্রেণীর নাম পাওয়ার জন্য এটির এই পরম প্রয়োজন: github.com/MozillaReality/ecsy/issues/ 119
ইফনট

আমি দেখি. এটি আপনার মোকাবেলা করা কোডটির সাথে খুব নির্দিষ্ট। উদাহরণস্বরূপ নামগুলি ES মডিউল এবং ES6 এর জন্য সংরক্ষিত হতে পারে কারণ export class Foo{}আরও দক্ষতার সাথে uglified করা যায় না তবে এটি অন্য জায়গাগুলির চেয়ে আলাদা হতে পারে, নির্দিষ্ট সময়ে নির্দিষ্ট কোড টুকরা দিয়ে কী ঘটে যায় তা ভাল ধারণা না থাকলে ঠিক কীভাবে আমরা জানতে পারি না। যে কোনও উপায়ে, ২০১৫ সাল থেকে এটি পরিবর্তন হয়নি some কিছু সংকলন কনফিগারেশন এবং কোডের জন্য এটি সর্বদা সম্ভব ছিল। এবং আমি বলব অ্যাপ লজিকের জন্য ক্লাসের নাম ব্যবহারের জন্য এই সম্ভাবনাটি এখনও খুব নাজুক। উত্সের কোডে এক দুর্ঘটনা পরিবর্তনের পরে আপনি যে শ্রেণীর নাম নির্ভর করেন তার বর্জ্য হয়ে উঠতে পারে
এস্তাস ফ্লাস্ক

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