জেএস বিষয়বস্তু সংজ্ঞায়নের এই উপায়টির কোনও উদ্দেশ্য আছে?


87

আমি কিছু লিগ্যাসি কোড বজায় করছি এবং আমি লক্ষ্য করেছি যে সংজ্ঞায়িত অবজেক্টগুলির জন্য নিম্নলিখিত প্যাটার্নটি ব্যবহৃত হয়েছে:

var MyObject = {};

(function (root) {

    root.myFunction = function (foo) {
        //do something
    };

})(MyObject);

এর কোন উদ্দেশ্য আছে কি? এটি কি কেবল নীচের কাজগুলির সমান?

var MyObject = {

    myFunction : function (foo) {
        //do something
    };

};

আমি আমার পছন্দ অনুসারে পুরো কোডবেসটি রিফ্যাক্টর করার জন্য কোনও পবিত্র কোয়েস্টে প্রবেশ করতে যাচ্ছি না, তবে বস্তুর সংজ্ঞা দেওয়ার সেই রাউন্ডআউট পথের পিছনে কারণটি আমি সত্যিই বুঝতে চাই।

ধন্যবাদ!


4
আপনার সঠিক উদাহরণে কোনও পার্থক্য নেই। আপনি যদি এটি প্রসারিত করেন তবে একটি পার্থক্য থাকতে পারে তবে তারপরে বিভিন্ন পন্থাগুলিও খেলতে পারে play
ট্র্যাভিস জে

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

4
@ এডিনিও এই উদাহরণের জন্য নয় myFunction, নিজের বাইরে নির্ধারিত কিছু ভেরিয়েবল ব্যবহার করতে পারেন যা বাইরে থেকে অ্যাক্সেসযোগ্য হবে না। আমার উত্তর দেখুন
হুয়ান মেন্ডেস


উত্তর:


116

একে মডিউল প্যাটার্ন বলা হয় http://toddmotto.com/mastering-t- Module-pattern/

মূল কারণটি হ'ল সত্যিকারের ব্যক্তিগত পদ্ধতি এবং ভেরিয়েবলগুলি তৈরি করা। আপনার ক্ষেত্রে এটি অর্থবহ নয় কারণ এটি কোনও প্রয়োগের বিবরণ গোপন করে না।

এখানে একটি উদাহরণ যেখানে এটি মডিউল প্যাটার্নটি ব্যবহার করে তোলে তা বোঝায়।

var MyNameSpace = {};

(function(ns){
    // The value variable is hidden from the outside world
    var value = 0;

    // So is this function
    function adder(num) {
       return num + 1;
    }

    ns.getNext = function () {
       return value = adder(value);
    }
})(MyNameSpace);

var id = MyNameSpace.getNext(); // 1
var otherId = MyNameSpace.getNext(); // 2
var otherId = MyNameSpace.getNext(); // 3

যদিও আপনি যদি কেবল একটি সরল অবজেক্ট ব্যবহার করেন adderএবং valueসর্বজনীন হয়ে যান

var MyNameSpace = {
    value: 0,
    adder: function(num) {
       return num + 1;
    },
    getNext: function() {
       return this.value = this.adder(this.value);
    }
}

এবং আপনি এটি স্টাফ পছন্দ মত করে এটি ভেঙে ফেলতে পারে

MyNameSpace.getNext(); // 1
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 1 again
delete MyNameSpace.adder;
MyNameSpace.getNext(); // error undefined is not a function

তবে মডিউল সংস্করণ সহ

MyNameSpace.getNext(); // 1
 // Is not affecting the internal value, it's creating a new property
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 2, yessss
// Is not deleting anything
delete MyNameSpace.adder;
MyNameSpace.getNext(); // no problemo, outputs 3

4
এই দুটি বিকল্পের মধ্যে পার্থক্য কি এই প্রশ্নের সত্যই উত্তর দেয় না?

20
@ টোরাজাবুরো ওপির উদাহরণটি ভাল উদাহরণ নয়, আমি একটি আসল উদাহরণ প্রদান করেছি যা মডিউল প্যাটার্নটি কখন ব্যবহার করতে হবে তা দেখায়।
হুয়ান মেন্ডেস

এটি ns.getNext: function () {সংকলন করবে না।
পুনন্ড

আমি এটি করতে পারি, যদি আমি নিশ্চিত ছিলাম যে এটি কীভাবে ঠিক করবেন। আমি ভেবেছিলাম কিছু প্রতিরোধের জন্য সেখানে কোন নির্মাণ আছে delete MyNameSpace.getNext
পুনন্ড

4
@ পুনুন্ড জেএস এর সংকলক নেই এর এর দোভাষী রয়েছে:)
ফ্রেগাটো

22

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

http://lupomontero.com/ using-javascript-closures-to-create-private-scopes/

নিবন্ধ থেকে:

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



কোড:

var MyObject = {};

(function (root) {
    function myPrivateFunction() {
       return "I can only be called from within the closure";
    }

    root.myFunction = function (foo) {
        //do something
    };    

    myPrivateFunction(); // returns "I can only be called from within the closure"

})(MyObject);


myPrivateFunction(); // throws error - undefined is not a function

4
myFunctionদ্বিতীয় সংস্করণে বিশ্বব্যাপী সুযোগে নেই। উদ্দেশ্যটি এমন একটি সুযোগ প্রদান করা যেখানে অভ্যন্তরীণ সহায়ক ফাংশনগুলি সংজ্ঞায়িত করা যায়।
বার্মার

myFunctionএটি বিশ্বব্যাপী স্কোপে রয়েছে কারণ এটি বিশ্বব্যাপী অবজেক্টের মধ্যে সংজ্ঞায়িত myObject। দ্বিতীয় সংস্করণে অ্যাপ্লিকেশনটির অন্য কোনও কোড কার্যকর করতে পারে myFunction। প্রথম সংস্করণে বন্ধের মধ্যে কেবল myFunction
জোনাথন ক্রো

না, myFunctionকেবল MyObject.myFunction()প্রথম সংস্করণ হিসাবে একই হিসাবে কার্যকর করা যেতে পারে ।
বর্মার

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

@ জুয়ানমেন্ডেস ভাল কথা, ওপি-র উদাহরণ মডিউল প্যাটার্নের দুর্দান্ত ব্যবহার নয়
জোনাথন ক্রো

6

সুবিধাদি:

  1. ব্যক্তিগত সুযোগে পরিবর্তনশীল বজায় রাখে।

  2. আপনি বিদ্যমান বস্তুর কার্যকারিতা প্রসারিত করতে পারেন।

  3. কর্মক্ষমতা বৃদ্ধি করা হয়।

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


6

আপনি যে নির্দিষ্ট ক্ষেত্রে দেখান, কার্যকারিতা বা দৃশ্যমানতার দিক থেকে কোনও অর্থপূর্ণ পার্থক্য নেই।

সম্ভবত সম্ভবত আসল কোডারটি এই পদ্ধতির এক ধরণের টেম্পলেট হিসাবে গ্রহণ করেছিলেন যা তাকে ব্যক্তিগত ভেরিয়েবলগুলি সংজ্ঞায়িত করতে দেয় যা এই জাতীয় জিনিসের সংজ্ঞা হিসাবে ব্যবহৃত হতে পারে myFunction:

var MyObject = {};
(function(root) {
    var seconds_per_day = 24 * 60 * 60;   // <-- private variable
    root.myFunction = function(foo) {
        return seconds_per_day;
    };
})(MyObject);

এটি seconds_per_dayবিশ্বব্যাপী সুযোগকে দূষিত করা থেকে দূরে রাখার সাথে সাথে ফাংশনটি ডাকা প্রতিটি সময় গণনা করা এড়ায়।

যাইহোক, মূলত এর থেকে আলাদা এবং কেবল বলার মতো কিছুই নেই

var MyObject = function() {
    var seconds_per_day = 24 * 60 * 60;
    return {
        myFunction: function(foo) {
            return seconds_per_day;
        }
    };
}();

মূল কোডার root.myFunction = functionএর অবজেক্ট / প্রপার্টি সিনট্যাক্সের পরিবর্তে এর ঘোষণামূলক বাক্য গঠন ব্যবহার করে অবজেক্টে ফাংশন যুক্ত করতে সক্ষম হতে পারে myFunction: function। তবে সেই পার্থক্যটি মূলত পছন্দের বিষয়।

তবে মূল কোডার দ্বারা গৃহীত কাঠামোর সুবিধা রয়েছে যে বৈশিষ্ট্য / পদ্ধতিগুলি কোডের অন্য কোনও জায়গায় সহজেই যুক্ত করা যায়:

var MyObject = {};
(function(root) {
    var seconds_per_day = 24 * 60 * 60;
    root.myFunction = function(foo) {
        return seconds_per_day;
    };
})(MyObject);

(function(root) {
    var another_private_variable = Math.pi;
    root.myFunction2 = function(bar) { };
})(MyObject);

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


6
  1. প্রথম প্যাটার্নটি মডিউল হিসাবে ব্যবহার করা যেতে পারে যা কোনও অবজেক্ট নেয় এবং সেই বস্তুকে কিছু পরিবর্তন করে ফেরত দেয়। অন্য কথায়, আপনি নিম্নলিখিত হিসাবে এই ধরনের মডিউল সংজ্ঞায়িত করতে পারেন।

    var module = function (root) {
        root.myFunction = function (foo) {
            //do something
        };
    }
    

    এবং এটি ব্যবহার করুন:

    var obj = {};
    module(obj);
    

    সুতরাং একটি সুবিধা হ'ল পরে ব্যবহারের জন্য এই মডিউলটির পুনরায় ব্যবহারযোগ্যতা।


  1. প্রথম প্যাটার্নে, আপনি আপনার ব্যক্তিগত জিনিস যেমন ব্যক্তিগত সম্পত্তি এবং পদ্ধতি সংরক্ষণ করতে একটি ব্যক্তিগত সুযোগ নির্ধারণ করতে পারেন । উদাহরণস্বরূপ, এই স্নিপেট বিবেচনা করুন:

    (function (root) {
    
        // A private property
        var factor = 3;
    
        root.multiply = function (foo) {
            return foo * factor;
        };
    })(MyObject);
    

  1. এই ধরণটি অ্যারে, অবজেক্ট ল্যাটারালস, ফাংশনগুলির মতো সমস্ত ধরণের অবজেক্টে কোনও পদ্ধতি বা সম্পত্তি যুক্ত করতে ব্যবহার করা যেতে পারে।

    function sum(a, b) {
        return a + b;
    }
    
    (function (root) {
        // A private property
        var factor = 3;
        root.multiply = function (foo) {
            return foo * factor;
        };
    })(sum);
    
    console.log(sum(1, 2)); // 3
    console.log(sum.multiply(4)); // 12
    

আমার মতে মূল সুবিধাটি দ্বিতীয়টি হতে পারে (একটি ব্যক্তিগত সুযোগ তৈরি করা)


5

এই নিদর্শনটি এমন একটি সুযোগ দেয় যেখানে আপনি সহায়তাকারী ফাংশনগুলি সংজ্ঞায়িত করতে পারেন যা বৈশ্বিক সুযোগে দৃশ্যমান নয়:

(function (root) {

    function doFoo() { ... };

    root.myFunction = function (foo) {
        //do something
        doFoo();
        //do something else
    };

})(MyObject);

doFoo বেনামে ফাংশনে স্থানীয়, এটি বাইরে থেকে উল্লেখ করা যায় না।

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