স্ব-সম্পাদনকারী বেনামে ফাংশন বনাম প্রোটোটাইপ


26

জাভাস্ক্রিপ্টে জাভাস্ক্রিপ্টে ক্লাস / নেমস্পেস তৈরি এবং পরিচালনা করার জন্য কয়েকটি স্পষ্টভাবে বিশিষ্ট কৌশল রয়েছে।

আমি কৌতূহলী যে পরিস্থিতিগুলি একটি কৌশল বনাম অন্যটি ব্যবহার করে কীভাবে ওয়ারেন্ট দেয়। আমি একটি বাছাই করতে চাই এবং এটি এগিয়ে এগিয়ে চলতে চাই।

আমি এমন একটি এন্টারপ্রাইজ কোড লিখি যা একাধিক টিমের জুড়ে রক্ষণাবেক্ষণ এবং ভাগ করা হয় এবং আমি রক্ষণাবেক্ষণযোগ্য জাভাস্ক্রিপ্ট লেখার সময় সেরা অনুশীলনটি কী তা জানতে চাই?

আমি স্ব-কার্যকরকারী বেনামে কার্যকারীদের পছন্দ করতে চাই তবে এই কৌশলগুলিতে সম্প্রদায়ের ভোট কী তা আমি আগ্রহী।

প্রোটোটাইপ:

function obj()
{
}

obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();

স্ব-সমাপ্তি নামহীন কার্য:

//Self-Executing Anonymous Function 
(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }     
}( window.skillet = window.skillet || {}, jQuery ));   
//Public Properties      
console.log( skillet.ingredient ); //Bacon Strips  

//Public Methods 
skillet.fry(); //Adding Butter & Fraying Bacon Strips 

//Adding a Public Property 
skillet.quantity = "12"; console.log( skillet.quantity ); //12   

//Adding New Functionality to the Skillet 
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " + 
                     skillet.ingredient + " & " + 
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
     };     

}( window.skillet = window.skillet || {}, jQuery ));
//end of skillet definition


try {
    //12 Bacon Strips & 1 Cup of Grease
    skillet.toString(); //Throws Exception 
} catch( e ) {
    console.log( e.message ); //isHot is not defined
}

আমি মনে করি যে আমার উল্লেখ করা উচিত যে স্ব-কার্যনির্বাহী বেনাম ফাংশন হল jQuery টিম ব্যবহৃত প্যাটার্ন।

আপডেট যখন আমি এই প্রশ্নটি জিজ্ঞাসা করি তখন আমি কী বুঝতে চেষ্টা করেছিলাম তার গুরুত্ব সত্যই দেখিনি। আপনার আসল সমস্যাটি হ'ল আপনার অবজেক্টগুলির উদাহরণ তৈরি করতে নতুন ব্যবহার করা উচিত বা newকীওয়ার্ডের নির্মাণ / ব্যবহারের প্রয়োজন হয় না এমন নিদর্শনগুলি ব্যবহার করুন ।

আমি আমার নিজের উত্তর যুক্ত করেছি, কারণ আমার মতে আমাদের এমন নিদর্শনগুলি ব্যবহার করা উচিত যা newকীওয়ার্ডটি ব্যবহার করে না ।

আরও তথ্যের জন্য দয়া করে আমার উত্তর দেখুন।


1
আপনি যে দুটি কৌশল বর্ণনা করছেন তার সংক্ষিপ্ত উদাহরণ দিতে পারেন?
আরে

আমার সাধারণ নমুনার কারণে প্রোটোটাইপটিকে হ্রাস করবেন না।
রোবটুশি

1
এটি নিজেই কার্যকর করছে না = /
আরে

2
আমি এক্সপ্রেশনটি বন্ধ করতে বা এটির জন্য কোনও বন্ধনী দেখতে পাচ্ছি না ...
আরে

1
(+1) নেমস্পেসগুলি অনেক বিকাশকারীকে উপেক্ষা করা হয়।
ইউলক্যাট

উত্তর:


22

স্ব-সম্পাদনকারী বেনামি ফাংশনগুলি বাইরের ইভেন্টগুলিতে (যেমন উইন্ডো.অনলোড) না scriptুকিয়ে স্ক্রিপ্ট এক্সিকিউশনটি স্বয়ংক্রিয় করতে ব্যবহৃত হয়।

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

অন্যদিকে কোনও অবজেক্টের প্রোটোটাইপ পরিবর্তন করে উত্তরাধিকার প্রতিষ্ঠার জন্য (বা স্থানীয়দের প্রসারিত করতে) ব্যবহৃত হয়। এই প্যাটার্নটি সাধারণ পদ্ধতি বা বৈশিষ্ট্য সহ 1: n অবজেক্ট তৈরি করতে ব্যবহৃত হয়।

আপনি এক প্যাটার্ন চয়ন করা উচিত নয় পক্ষপাত অপরের, যেহেতু তারা সঞ্চালন বিভিন্ন কর্ম। নেমস্পেসিংয়ের ক্ষেত্রে, স্ব সম্পাদনা কার্য একটি উপযুক্ত পছন্দ ction


7
নোট করুন যে "স্ব সম্পাদনকারী বেনামে ফাংশন" সাধারণত তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন এক্সপ্রেশন (IIFE) হিসাবে পরিচিত ।
voithos

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

4

আমি সবেমাত্র যে প্যাটার্নটি ব্যবহার করতে শুরু করেছি তা হ'ল (গতকাল পর্যন্ত এর বিভিন্নতা ব্যবহার করে আসছি):

function MyClass() {
    // attributes
    var privateVar = null;

    // function implementations
    function myPublicFunction() {
    }

    function myPrivateFunction() {
    }

    // public declarations
    this.myPublicFunction = myPublicFunction;
}

MyClass.prototype = new ParentClass(); // if required

এই সম্পর্কে কয়েকটি চিন্তা:

  1. আপনি যে কোনো না পাওয়া উচিত (anonymous)সবকিছু নামে (কোন বেনামী ফাংশন) হিসাবে আপনার ডিবাগার স্ট্যাক ট্রেস মধ্যে ট্রেস।
  2. এটি এখনও পরিষ্কার প্যাটার্ন যা আমি দেখেছি
  3. আপনি ঘোষণার সাথে মিলিতভাবে বাস্তবায়ন না করেই আপনার উন্মুক্ত এপিআই সহজেই গোষ্ঠী করতে সক্ষম হবেন (যার অর্থ কেউ সহজেই আপনার পাবলিক ক্লাসের ইন্টারফেসটি স্ক্রোল না করেই আঁকতে পারে)

আমি prototypeআর একবার ব্যবহার করতে পারি তা হ'ল উত্তরাধিকার সংজ্ঞা দেওয়া।


5
এটির সাথে কয়েকটি সমস্যা রয়েছে। কনস্ট্রাক্টরের প্রতিটি অনুরোধ সহ প্রতিটি "পদ্ধতি" এর জন্য একটি নতুন ফাংশন অবজেক্ট তৈরি করা হয়। এছাড়াও, উত্তরাধিকারের জন্য প্রোটোটাইপ অবজেক্টের একটি অনুলিপি পেতে কোনও কনস্ট্রাক্টরকে কল করা ভ্রান্ত হয়। অবজেক্ট ক্রেইট (প্যারেন্টক্লাস.প্রোটোটাইপ), বা অবজেক্ট ক্রিয়েটের মতো একটি শিম ব্যবহার করুনfunction clone(obj){return this typeof 'clone' ? this : new clone(clone.prototype=obj)}
আরে

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

এছাড়াও, jsperf ( jsperf.com/object-create-vs-constructor-vs-object-literal/12 ) এ নিম্নলিখিত কাজগুলি দেখার পরে , আমি প্রায় কোনও দিন অতিরিক্ত কপিগুলির মেমরি ব্যয়ের তুলনায় কর্মক্ষমতা বৃদ্ধি করব (আবার, নির্দিষ্ট ব্যবহারের ক্ষেত্রে খুব সাবজেক্টিভ)।
ডেমিয়ান ব্রেচেট

এখন, এই সমস্ত কথাটি বলে, আমি কেবল ইসিএমএ-262 এর মধ্য দিয়েই আছি, সুতরাং এমন একগুচ্ছ জিনিস থাকতে পারে যা আমি দেখছি না .. এছাড়াও, আমি ক্রকফোর্ডের শব্দটিকে সুসমাচার হিসাবে গ্রহণ করি না .. হ্যাঁ, সে একটি ক্ষেত্রের বিশেষজ্ঞদের মধ্যে (অবশ্যই অন্যতম) তবে এটি সর্বদা তাকে 100% সঠিক করে তোলে না right সেখানে অন্যান্য বিশেষজ্ঞ রয়েছেন (আমি তাদের মধ্যে একজন নই;)) বাধ্যতামূলক যুক্তিগুলির সাথে পরস্পরবিরোধী মতামত রয়েছে।
ডেমিয়ান ব্রেচেট

2
আপনি কাজ করতে চাই এই জিনিস আপনি আগ্রহী হতে পারে ।
আরে

3

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

উদাহরণ:

var me;

function MyObject () {
    this.name = "Something";
}

MyObject.prototype.speak = function speak () {
    return "Hello, my name is " + this.name;
};

me = new MyObject();
me.name = "Joshua";
alert(me.speak());

1
স্বীকৃত বেনাম ফাংশনগুলি আপনার ব্যক্তিগত ক্লাসে অ্যাক্সেসযোগ্য ব্যক্তিগত ফাংশনগুলির অনুমতি দেওয়ার জন্য খুব কার্যকর।
জি

1

আমি স্ব-কার্যকরকারী কার্যের সাথে যাব, তবে কিছুটা পার্থক্য সহ:

MyClass = (function() {
     var methodOne = function () {};
     var methodTwo = function () {};
     var privateProperty = "private";
     var publicProperty = "public";

     return function MyClass() {
         this.methodOne = methodOne;
         this.methodTwo = methodTwo;
         this.publicProperty = publicProperty;
     };
})();

যদি এই পদ্ধতিকে আরও ক্লিনার মনে হয়, যেহেতু আমি কোনও ইনপুট প্যারামিটারগুলি (যেমন jQuery) থেকে ফেরত গ্লোবাল ভেরিয়েবলকে পৃথক করি (আপনি এটি যেভাবে লিখেছেন তা অকার্যকর ফিরে আসার এবং সি # তে একটি রেফ প্যারামিটার ব্যবহার করার সমতুল্য, যা আমি কিছুটা খুলে দেখি, বা একটি পয়েন্টারে একটি পয়েন্টারে পাস করা এবং এটি C ++ এ পুনরায় নির্ধারণ করা)। আমি যদি তখন শ্রেণিতে অতিরিক্ত পদ্ধতি বা বৈশিষ্ট্য সংযুক্ত করতে যাচ্ছিলাম তবে আমি প্রোটোটাইপাল উত্তরাধিকার ব্যবহার করব (উদাহরণস্বরূপ jQuery এর $। প্রসারিত পদ্ধতির সাথে, তবে এটি আপনার নিজস্ব প্রসারিত ()) রোল করা যথেষ্ট সহজ:

var additionalClassMethods = (function () {
    var additionalMethod = function () { alert('Test Method'); };
    return { additionalMethod: additionalMethod };
})();

$.extend(MyClass.prototype, additionalClassMethods);

var m = new MyClass();
m.additionalMethod(); // Pops out "Test Method"

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


1
আমি কি কেবলমাত্র এই জাতীয় এনএফই ব্যবহার করা খারাপ ধারণা?
আরে

1

সরাসরি উদাহরণ

(function _anonymouswrapper(undefined) {

    var Skillet = {
        constructor: function (options) {
            options && extend(this, options);
            return this; 
        },
        ingredient: "Bacon Strips",
        _isHot: true,
        fry: function fry(oliveOil) {
            this._addItem("\t\n Butter \n\t");
            this._addItem(oliveOil);
            this._addItem(this.ingredient);
            console.log("Frying " + this.ingredient);
        },
        _addItem: function addItem(item) {
            console.log("Adding " + item.toString().trim());
        }
    };

    var skillet = Object.create(Skillet).constructor();

    console.log(skillet.ingredient);
    skillet.fry("olive oil");

    var PrintableSkillet = extend(Object.create(Skillet), {
        constructor: function constructor(options) {
            options && extend(this, options);
            return this;
        },
        _amountOfGrease: "1 Cup",
        quantity: 12,
        toString: function toString() {
            console.log(this.quantity + " " +
                        this.ingredient + " & " +
                        this._amountOfGrease + " of Grease");
            console.log(this._isHot ? "Hot" : "Cold");
        }
    });

    var skillet = Object.create(PrintableSkillet).constructor();

    skillet.toString();

    function extend(target, source) {
        Object.getOwnPropertyNames(source).forEach(function (name) {
            var pd = Object.getOwnPropertyDescriptor(source, name);
            Object.defineProperty(target, name, pd);
        });
        return target;
    }
}());

আপনি আপনার কোডের চারপাশে "মডিউল স্কোপ" অনুকরণ করতে একটি আইআইএফই ব্যবহার করতে পারেন। তারপরে আপনি যেমনটি করেন ঠিক তেমন অবজেক্ট ব্যবহার করতে পারেন।

ক্লোজারগুলি ব্যবহার করে ব্যক্তিগত রাষ্ট্রটিকে "অনুকরণ" করবেন না কারণ এতে বিশাল মেমরির জরিমানা রয়েছে।

যদি আপনার কোনও এন্টারপ্রাইজ অ্যাপ্লিকেশন লেখা হয় এবং আপনার মেমরির ব্যবহারটি 1 জিবি এর নীচে রাখতে চান তবে স্টোর স্টোর করার জন্য অকারণে ক্লোজার ব্যবহার করা এড়িয়ে চলুন।


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

@ এডউডককটি আমি অনুভব করেছি যে কোডটি বাগি ছিল, সবেমাত্র রিফ্যাক্টর এবং এটি ঠিক করা হয়েছে।
রায়নস

স্থানীয় consoleএবং বিশ্বব্যাপী দক্ষতা পার্থক্যটি এডডুডকক consoleএকটি মাইক্রো অপ্টিমাইজেশন। এটি হ্রাস করার মতো এটি আপনি হ্রাস করতে পারেন consoleতবে এটি একটি আলাদা বিষয়
রায়নস

এডওয়ুডককের ক্লোজারগুলি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে your যখন ধীরে ধীরে প্রয়োজন হয় না তখন ফাংশনের ভিতরে ফাংশন তৈরি করে। অবজেক্টগুলিতে সরাসরি স্টোরেজ স্টেটের তুলনায়
ক্লোজারগুলির

হ্যাঁ, এটি কেবল উল্লেখ করতে চেয়েছিলেন যেহেতু আপনার উত্তরটি জিনিসগুলির বিষয়ে যুক্তিযুক্ত যুক্তিযুক্ত উপায় (যদিও আমি যেভাবে ব্যবহার করতে চাই তা নয়)। (আমি একটি সম্পাদনা করেছি তবে আমি এখনও এই বিশেষ এসই সাইটে তাদের শিষ্টাচার সম্পর্কে নিশ্চিত নই)।
এড জেমস

0

আপডেট আমি এখন জাভাস্ক্রিপ্ট সম্পর্কে আরও ভাল বোঝার আছে এবং আমি সঠিকভাবে প্রশ্নের সমাধান করতে পারে বোধ। আমি মনে করি এটি একটি খারাপ শব্দযুক্ত, তবে সম্বোধনের জন্য খুব গুরুত্বপূর্ণ জাভাস্ক্রিপ্টের বিষয়।

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

স্ব নির্বাহী অনামী কার্য এই মানদণ্ডটি পূরণ করে।

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


1
নতুন কীওয়ার্ড সম্পর্কে খারাপ কী? আমি কৌতুহলী.
অ্যালি

0

IIFE SelfExecutingFunctionএর Myclassসাথে প্রসারিত করার জন্য আমি এখানে কীভাবে যাব Myclass.anotherFunction();

MyClass = (function() {
     var methodOne = function () {};
     var methodTwo = function () {};
     var privateProperty = "private";
     var publicProperty = "public";

    //Returning the anonymous object {} all the methods and properties are reflected in Myclass constructor that you want public those no included became hidden through closure; 
     return {
         methodOne = methodOne;
         methodTwo = methodTwo;
         publicProperty = publicProperty;
     };
})();

@@@@@@@@@@@@@@@@@@@@@@@@
//then define another IIFE SEF to add var function=anothermethod(){};
(function(obj){
return obj.anotherfunction=function(){console.log("Added to Myclass.anotherfunction");};
})(Myclass);

//the last bit : (function(obj){})(Myclass); obj === Myclass obj is an alias to pass the Myclass to IIFE

var myclass = new Myclass();
myclass.anotherfunction(); //"Added to Myclass.anotherfunction"

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