क्या मुझे ऑब्जेक्ट शाब्दिक या निर्माता कार्यों का उपयोग करना चाहिए?


94

मैं भ्रमित हो रहा हूं कि मुझे किस तरह से जावास्क्रिप्ट में एक ऑब्जेक्ट बनाना चाहिए। ऐसा लगता है कि कम से कम दो तरीके हैं। एक वस्तु शाब्दिक संकेतन का उपयोग करना है जबकि दूसरा निर्माण कार्यों का उपयोग करता है। क्या एक का दूसरे पर फायदा है?


1
सबसे अच्छा जवाब: stackoverflow.com/questions/4597926/… - सारांश में, आप उदाहरण के लिए शाब्दिक रूप में भी उदाहरण बनाने के लिए एक फ़ंक्शन सेट कर सकते हैं। ऐसा करने से प्रत्येक आवृत्ति सभी विधियों को वहन करती है, जबकि एक निर्माता के साथ सभी उदाहरण प्रोटोटाइप विधियों का उल्लेख करते हैं। यानी कंस्ट्रक्टर में बेहतर मेमोरी परफॉर्मेंस होती है।
— फेडेरिको

यदि स्मृति कोई समस्या नहीं है तो वस्तु शाब्दिक संपत्ति का उपयोग बहुत अधिक तेज़ी से होता है - jsperf.com/module-pattern-vs-object-literal-vs-prototype/4
— डैनियल

जवाबों:


131

यदि आपके पास किसी वस्तु से जुड़ा व्यवहार नहीं है (अर्थात यदि वस्तु केवल डेटा / राज्य के लिए एक कंटेनर है), तो मैं एक वस्तु शाब्दिक उपयोग करूंगा।

var data = {
    foo: 42,
    bar: 43
};

लागू करें KISS सिद्धांत । यदि आपको डेटा के एक साधारण कंटेनर से परे कुछ भी नहीं चाहिए, तो एक साधारण शाब्दिक के साथ जाएं।

यदि आप अपने ऑब्जेक्ट में व्यवहार जोड़ना चाहते हैं, तो आप एक कंस्ट्रक्टर के साथ जा सकते हैं और निर्माण के दौरान ऑब्जेक्ट में तरीकों को जोड़ सकते हैं या अपनी कक्षा को एक प्रोटोटाइप दे सकते हैं।

function MyData(foo, bar) {
    this.foo = foo;
    this.bar = bar;

    this.verify = function () {
        return this.foo === this.bar;
    };
}

// or:
MyData.prototype.verify = function () {
    return this.foo === this.bar;
};

इस तरह का एक वर्ग आपके डेटा ऑब्जेक्ट के लिए एक स्कीमा की तरह भी काम करता है: अब आपके पास किसी प्रकार का अनुबंध (निर्माणकर्ता के माध्यम से) होता है कि ऑब्जेक्ट किस गुण को प्रारंभ / समाहित करता है। एक मुफ्त शाब्दिक डेटा का सिर्फ एक अनाकार बूँद है।

आपके पास एक बाहरी verifyफ़ंक्शन हो सकता है जो सादे पुराने डेटा ऑब्जेक्ट पर कार्य करता है:

var data = {
    foo: 42,
    bar: 43
};

function verify(data) {
    return data.foo === data.bar;
}

हालांकि, यह एनकैप्सुलेशन के संबंध में अनुकूल नहीं है: आदर्श रूप से, एक इकाई से जुड़े सभी डेटा + व्यवहार एक साथ रहना चाहिए।


12
महान व्याख्या, लेकिन एक वस्तु शाब्दिक में कार्य करने के बारे में क्या? मैंने ऐसा पहले भी देखा है। दरअसल नीचे की पोस्ट इसका एक उदाहरण है।
— चोबो

23
यदि आप फ़ंक्शन परिभाषाओं को ऑब्जेक्ट शाब्दिक के भाग के रूप में शामिल करते हैं, या this.fn = function ...एक कंस्ट्रक्टर में दृष्टिकोण का उपयोग करते हैं , तो आपके प्रत्येक ऑब्जेक्ट इंस्टेंसेस के कार्यों की अपनी प्रतियां होंगी। प्रोटोटाइप दृष्टिकोण का उपयोग करते हुए, आप प्रत्येक फ़ंक्शन को एक बार और केवल एक बार संलग्न करते हैं: उन्हें प्रोटोटाइप विरासत के माध्यम से उदाहरणों से विरासत में मिलेगा।
— एटिस गोरल

14
मेरा मानना ​​है कि आपने एक महत्वपूर्ण चीज को याद किया। केवल कंस्ट्रक्टर फ़ंक्शन निजी सदस्यों के साथ-साथ सार्वजनिक सदस्यों (एनकैप्सुलेशन) को भी प्रदान कर सकता है। वस्तु शाब्दिक में - वे सभी सार्वजनिक हैं।
— रॉय नमिर

गेम इंजन के लिए एक बेहतर तरीका क्या होगा? मैंने कंस्ट्रक्टर विधि का उपयोग किया है, लेकिन मेरे प्रोटोटाइप का निर्माण डेटा तक पहुंच नहीं है।
— zachdyer

90

यह अनिवार्य रूप से उबलता है अगर आपको अपनी वस्तु के कई उदाहरणों की आवश्यकता है या नहीं; एक निर्माता के साथ परिभाषित वस्तु आपको उस वस्तु के कई उदाहरण देती है। ऑब्जेक्ट शाब्दिक रूप से चर / विधियों के साथ मूल रूप से एकल हैं जो सभी सार्वजनिक हैं।

// define the objects:
var objLit = {
  x: 0,
  y: 0,
  z: 0,
  add: function () {
    return this.x + this.y + this.z;
  }
};

var ObjCon = function(_x, _y, _z) {
  var x = _x; // private
  var y = _y; // private
  this.z = _z; // public
  this.add = function () {
    return x + y + this.z; // note x, y doesn't need this.
  };
};

// use the objects:
objLit.x = 3; 
objLit.y = 2; 
objLit.z = 1; 
console.log(objLit.add());    

var objConIntance = new ObjCon(5,4,3); // instantiate an objCon
console.log(objConIntance.add());
console.log((new ObjCon(7,8,9)).add()); // another instance of objCon
console.log(objConIntance.add()); // same result, not affected by previous line

1
यह निर्णय लेते समय ध्यान में रखने के लिए एक बहुत अच्छा बिंदु है। धन्यवाद।
— जंक

मेरे अनुभव में यह वही है जो फर्क करता है। महान स्पष्ट उदाहरण।
— एयर

9

एक समान तरीके से वस्तुओं को बनाने का एक और तरीका एक वस्तु का उपयोग करने वाले फ़ंक्शन का उपयोग करना है:

function makeObject() {
    var that = {
        thisIsPublic: "a public variable"
        thisIsAlsoPublic: function () {
            alert(that.thisIsPublic);
        }
    };

    var secret = "this is a private variable"

    function secretFunction() { // private method
        secret += "!"; // can manipulate private variables
        that.thisIsPublic = "foo";     
    }

    that.publicMethod = function () {
        secret += "?"; // this method can also mess with private variables
    }

    that.anotherPublicVariable = "baz";

    return that; // this is the object we've constructed
}

makeObject.static = "This can be used to add a static varaible/method";

var bar = makeObject();
bar.publicMethod(); // ok
alert(bar.thisIsPublic); // ok
bar.secretFunction(); // error!
bar.secret // error!

चूंकि जावास्क्रिप्ट में कार्य बंद हैं, हम निजी चर और विधियों का उपयोग कर सकते हैं और बच सकते हैं new।

जावास्क्रिप्ट में निजी चर पर http://javascript.crockford.com/pStreet.html से ।


7

नीचे दिया गया कोड ऑब्जेक्ट बनाने के तीन तरीके दिखाता है, ऑब्जेक्ट लिटरल सिंटैक्स, एक फंक्शन कन्स्ट्रक्टर और Object.create()। वस्तु शाब्दिक वाक्य रचना बस बनाता है और मक्खी पर वस्तु और इस तरह के रूप में अपनी __prototype__है Objectवस्तु और यह सब गुण और के तरीकों के लिए उपयोग होगा Object। कड़ाई से एक डिजाइन पैटर्न के नजरिए से एक साधारण वस्तु शाब्दिक डेटा का एक भी उदाहरण संग्रहीत करने के लिए इस्तेमाल किया जाना चाहिए।

फ़ंक्शन कंस्ट्रक्टर के पास एक विशेष संपत्ति है जिसका नाम है .prototype। यह संपत्ति __prototype__फ़ंक्शन कंस्ट्रक्टर द्वारा बनाई गई किसी भी ऑब्जेक्ट की हो जाएगी । .prototypeएक फ़ंक्शन कंस्ट्रक्टर की संपत्ति में जोड़े गए सभी गुण और विधियां सभी ऑब्जेक्ट्स के लिए उपलब्ध होंगी जो इसे बनाता है। एक कंस्ट्रक्टर का उपयोग किया जाना चाहिए, यदि आपको डेटा के कई उदाहरणों की आवश्यकता होती है या अपनी वस्तु से व्यवहार की आवश्यकता होती है। ध्यान दें कि जब आप एक निजी / सार्वजनिक विकास पैटर्न का अनुकरण करना चाहते हैं तो फंक्शन कंस्ट्रक्टर का भी उपयोग किया जाता है। सभी साझा किए गए तरीकों को रखना याद रखें .prototypeताकि वे प्रत्येक ऑब्जेक्ट उदाहरण में नहीं बनाए जाएंगे।

ऑब्जेक्ट के साथ ऑब्जेक्ट बनाना इस पद्धति द्वारा बनाई गई ऑब्जेक्ट के लिए Object.create()एक वस्तु शाब्दिक का उपयोग करता है __prototype__। ऑब्जेक्ट शाब्दिक रूप से जोड़े गए सभी गुण और विधियाँ वास्तविक प्रोटोटाइप विरासत के माध्यम से इससे निर्मित सभी वस्तुओं के लिए उपलब्ध होंगी। यह मेरी पसंदीदा विधि है।

//Object Example

//Simple Object Literal
var mySimpleObj = {
    prop1 : "value",
    prop2 : "value"
}

// Function Constructor
function PersonObjConstr()  {
    var privateProp = "this is private";
    this.firstname = "John";
    this.lastname = "Doe";
}
PersonObjConstr.prototype.greetFullName = function()    {
    return "PersonObjConstr says: Hello " + this.firstname + 
    " " + this.lastname;
};

// Object Literal
var personObjLit = {
    firstname : "John",
    lastname: "Doe",
    greetFullName : function() {
        return "personObjLit says: Hello " + this.firstname +
        ", " + this.lastname;
    }
} 

var newVar = mySimpleObj.prop1;
var newName = new PersonObjConstr();
var newName2 = Object.create(personObjLit);

1
चूंकि आपने फ़ंक्शन को ऑब्जेक्ट शाब्दिक के अंदर घोषित किया है। क्या इसका मतलब है कि जब आप Object.createशाब्दिक के अंदर फ़ंक्शन का उपयोग करके ऑब्जेक्ट बनाते हैं तो प्रति उदाहरण अद्वितीय होगा?
— जॉनी क्यू

6

यह आप पर निर्भर करता है की आप क्या करना चाहते हो। यदि आप (सेमी-) निजी चर या कार्यों का उपयोग करना चाहते हैं, तो एक निर्माण कार्य इसे करने का तरीका है। यदि आपकी ऑब्जेक्ट में केवल गुण और विधियाँ हैं, तो एक ऑब्जेक्ट शाब्दिक ठीक है।

function SomeConstructor(){
    var x = 5;
    this.multiply5 = function(i){
        return x*i;
    }
}
var myObj = new SomeConstructor;

var SomeLiteral = {
    multiply5: function(i){ return i*5; }
}

अब विधि multiply5में myObjऔर SomeLiteralबिल्कुल वही काम करते हैं। अंतर केवल इतना है कि myObj एक निजी चर का उपयोग करता है। उत्तरार्द्ध कुछ मामलों में उपयोगी हो सकता है। जेएस-ऑब्जेक्ट बनाने के लिए अधिकांश समय एक ऑब्जेक्ट शाब्दिक पर्याप्त और एक अच्छा और साफ तरीका है।


एक फ़ंक्शन और एक विधि के बीच अंतर क्या है? मैं एसी # बैकग्राउंड से आता हूं इसलिए मेरे लिए एक फंक्शन स्टैंडअलोन है और एक तरीका सिर्फ एक फंक्शन है जो एक क्लास का हिस्सा है।
— चोबो

1
इतना अंतर नहीं है, उदाहरण के लिए देखें web-source.net/javascript_tutorial/… । दरअसल, DOMscripting (एक ब्राउज़र में क्लाइंट साइड js), सभी फ़ंक्शन विंडो-ऑब्जेक्ट (वैश्विक नामस्थान) के तरीके बन जाते हैं, मैं कहूंगा (आप विंडो के रूप में सभी 'स्टैंडअलोन' कार्यों को संबोधित कर सकते हैं। [somefunction]
— KooiInc

5

यहां छवि विवरण दर्ज करें

क्या आप पृष्ठ के लिए ऑब्जेक्ट का एकल उदाहरण चाहते हैं - लिटरल।

क्या आप डीटीओ ऑब्जेक्ट्स की तरह डेटा को सरल GET SET में स्थानांतरित करना चाहते हैं: - शाब्दिक

क्या आप विधि व्यवहार, कई उदाहरणों - कन्स्ट्रक्टर फ़ंक्शन के साथ वास्तविक ऑब्जेक्ट बनाना चाहते हैं, ओओपी सिद्धांतों का पालन करें, विरासत: - कंस्ट्रक्टर फ़ंक्शन।

नीचे यूट्यूब वीडियो है जो विस्तार से बताता है कि शाब्दिक क्या है, निर्माण कार्य क्या हैं और वे एक दूसरे से कैसे भिन्न हैं।

https://www.youtube.com/watch?v=dVoAq2D3n44


1

ऑब्जेक्ट शाब्दिक के साथ जाओ, यह अधिक सामान्य है और प्रारंभिक मूल्यों की शुरूआत के साथ बेहतर विस्तार करता है।


आप एक वस्तु शाब्दिक में निजी चर कैसे बनाते हैं?
— एहीवुतोव

आप वास्तव में नहीं कर सकते, यह मूल प्रश्न के लिए प्रासंगिक नहीं है, इसलिए मैं आपको एक लिंक देने जा रहा हूं: javascript.crockford.com/pStreet.html
— टॉम

1
वास्तव में, यह प्रासंगिक है क्योंकि जहां अंतर है, वहां कुछ स्थितियों के आधार पर एक या दूसरे का उपयोग करने का एक कारण है; इस उदाहरण में यह होगा कि आप निजी चर चाहते हैं या नहीं। आप अपने शाब्दिक रूप से एक क्लोजर फंक्शन बनाकर एक शाब्दिक रूप से निजी चर बना सकते हैं, लेकिन यह मेरी राय में और पढ़ने में कठिन है।
— एवुवोतोव

मैं सही हो गया हूं, प्रश्न का मेरा मूल वाचन यह था कि चोबो एक रचनाकार के रूप में पैरामीटर सूची बनाम एकल वस्तु शाब्दिक पैरामीटर के रूप में चर कैसे पारित करें, इसके बारे में पूछ रहा था।
— टॉम

1

जैसा कि https://www.w3schools.com/js/js_object_definition.asp में बताया गया है

एक वस्तु शाब्दिक उपयोग करके, आप दोनों को परिभाषित और बनाने , एक में वस्तु एक बयान।

भी

ऑब्जेक्ट शाब्दिक केवल एक ही ऑब्जेक्ट बनाते हैं। कभी-कभी हमें एक वस्तु प्रकार पसंद होता है जिसका उपयोग एक प्रकार की कई वस्तुओं को बनाने के लिए किया जा सकता है ।


0

ऑब्जेक्ट () कंस्ट्रक्टर फ़ंक्शन थोड़ा धीमा और अधिक क्रिया है। जैसे, जावास्क्रिप्ट में नई वस्तुओं को बनाने के लिए अनुशंसित तरीका शाब्दिक अंकन का उपयोग करना है

उडनेस ऑब्जेक्ट-ओरिएंटेड जावास्क्रिप्ट


0

वास्तव में, मेथिंक, हम वस्तु शाब्दिक में निजी तरीके हो सकते हैं। नीचे दिए गए कोड पर विचार करें:

var myObject = {

   publicMethod: function () {
      privateMethod1();
      privateMethod2(); 
      function privateMethod1(){
          console.log('i am privateMethod1');
      } 
      function privateMethod2(){
          console.log('i am privateMethod2');
      } 
   }

}

स्वाद का पदार्थ, लेकिन मैं वस्तु शाब्दिक उपयोग करना पसंद करता हूं जहां यह संभव है।


-1

// ऑब्जेक्ट लिटरल और ऑब्जेक्ट कंस्ट्रक्टर

function MyData(foo, bar) {
        this.foo = foo;
        this.bar = bar;

    }
MyData.prototype.verify = function () {
        return this.foo === this.bar;
    };

//add property using prototype

var MD  = new MyData;//true.
var MD = new MyData();//true.
MD.verify// return only the function structure.
MD.verify(); //return the verify value and in this case return true coz both value is null. 
var MD1  = new MyData(1,2); // intialized the value at the starting. 
MD1.verify// return only the function structure.
MD1.verify(); // return false coz both value are not same.
MD1.verify(3,3);// return false coz this will not check this value intialized at the top 
MyData.prototype.verify = function (foo,bar) {
    return this.foo === this.bar;
};
var MD1  = new MyData(1,2);
MD1.verify();
MD1.verify(3,3);// return false coz this keyword used with foo and bar that will check parent data 

1
आपके उदाहरण में ऑब्जेक्ट को शाब्दिक रूप से कहाँ घोषित किया गया है?
— जॉनीक्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.