जावास्क्रिप्ट निजी तरीके


482

एक सार्वजनिक विधि के साथ एक जावास्क्रिप्ट वर्ग बनाने के लिए मैं कुछ ऐसा करूंगा:

function Restaurant() {}

Restaurant.prototype.buy_food = function(){
   // something here
}

Restaurant.prototype.use_restroom = function(){
   // something here
}

इस तरह मेरी कक्षा के उपयोगकर्ता कर सकते हैं:

var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();

मैं एक निजी विधि द्वारा कहा जा सकता है कैसे बना सकता हूँ buy_foodऔर use_restroomतरीकों नहीं बल्कि वर्ग के उपयोगकर्ताओं द्वारा बाहर से?

दूसरे शब्दों में, मैं चाहता हूं कि मेरी विधि कार्यान्वयन करने में सक्षम हो:

Restaurant.prototype.use_restroom = function() {
   this.private_stuff();
}

लेकिन यह काम नहीं करना चाहिए:

var r = new Restaurant();
r.private_stuff();

मैं private_stuffएक निजी विधि के रूप में कैसे परिभाषित करूं ताकि ये दोनों सही हों?

मैंने कुछ समय में डौग क्रॉकफोर्ड के राइटअप को पढ़ा है, लेकिन ऐसा नहीं लगता कि "निजी" तरीकों को सार्वजनिक तरीकों से बुलाया जा सकता है और "विशेषाधिकार प्राप्त" तरीकों को बाहरी रूप से कहा जा सकता है।

जवाबों:


403

आप इसे कर सकते हैं, लेकिन नकारात्मक पक्ष यह है कि यह प्रोटोटाइप का हिस्सा नहीं हो सकता है:

function Restaurant() {
    var myPrivateVar;

    var private_stuff = function() {  // Only visible inside Restaurant()
        myPrivateVar = "I can set this here!";
    }

    this.use_restroom = function() {  // use_restroom is visible to all
        private_stuff();
    }

    this.buy_food = function() {   // buy_food is visible to all
        private_stuff();
    }
}

9
क्लोजर के अंदर थिन्स छिपाना सभी दुभाषियों पर गोपनीयता की गारंटी नहीं देगा। कोड देखें। http://www.p/google-caja/wiki/…
माइक सैमुअल

51
@mikesamuel - सच है, लेकिन केवल जब उन दुभाषियों में कीड़े हैं :)
jvenema

133
यह सब ठीक है, लेकिन एक निजी प्रोटोटाइप विधि की तुलना में बहुत अधिक मेमोरी का उपयोग करने की प्रवृत्ति है, खासकर यदि आप इन वस्तुओं का एक बहुत कुछ बना रहे हैं। प्रत्येक ऑब्जेक्ट उदाहरण के लिए, यह ऑब्जेक्ट के लिए बाध्य एक अलग फ़ंक्शन बनाता है न कि क्लास। इसके अलावा, यह तब तक कचरा एकत्र नहीं करता है जब तक कि वस्तु स्वयं नष्ट न हो जाए।
अरिंदम

4
यदि आप एक ऑब्जेक्ट बनाते हैं McDonalds () रेस्तरां से विरासत में मिला () McDonalds निजी तरीकों को ओवरराइड नहीं कर सकता है यदि आप उन्हें इस तरह से घोषित करते हैं। ठीक है, वास्तव में आप कर सकते हैं, लेकिन यह काम नहीं करेगा यदि कोई अन्य विधि निजी कॉल करती है, तो यह विधि के मूल संस्करण को कॉल करेगी और आप मूल विधि को भी कॉल नहीं कर सकते। अब तक मुझे निजी तरीकों को घोषित करने का एक अच्छा तरीका नहीं मिला है जो विरासत के साथ अच्छी तरह से काम करते हैं। यह और प्रदर्शन निहितार्थ यह बिल्कुल अच्छा डिज़ाइन पैटर्न नहीं बनाता है। मैं निजी तरीकों को इंगित करने के लिए किसी प्रकार का उपसर्ग करने की सलाह दूंगा, जो एक रेखांकन के साथ हो।
हॉफमैन

68
निजी तरीकों को ओवरराइड नहीं किया जाना चाहिए - वे निजी हैं।
17 की 26

163

सेल्फ इनवोकिंग फंक्शन और कॉल का उपयोग करना

जावास्क्रिप्ट प्रोटोटाइप का उपयोग करता है और इसमें ऑब्जेक्ट ओरिएंटेड भाषाओं की तरह कक्षाएं (या उस मामले के लिए तरीके) नहीं हैं। एक जावास्क्रिप्ट डेवलपर को जावास्क्रिप्ट में सोचने की जरूरत है।

विकिपीडिया बोली:

कई ऑब्जेक्ट-ओरिएंटेड भाषाओं के विपरीत, फ़ंक्शन परिभाषा और विधि परिभाषा के बीच कोई अंतर नहीं है। बल्कि, फ़ंक्शन कॉलिंग के दौरान अंतर होता है; जब किसी फ़ंक्शन को ऑब्जेक्ट की विधि के रूप में कहा जाता है, तो फ़ंक्शन का स्थानीय यह कीवर्ड उस इन्वोकेशन के लिए उस ऑब्जेक्ट के लिए बाध्य होता है।

एक का उपयोग कर समाधान निजी "विधि" को कॉल करने के लिए स्वयं आह्वान फ़ंक्शन और कॉल फ़ंक्शन :

var MyObject = (function () {

    // Constructor
    function MyObject (foo) {
        this._foo = foo;
    }

    function privateFun (prefix) {
        return prefix + this._foo;
    }

    MyObject.prototype.publicFun = function () {
        return privateFun.call(this, '>>');
    }

    return MyObject;
})();


var myObject = new MyObject('bar');
myObject.publicFun();      // Returns '>>bar'
myObject.privateFun('>>'); // ReferenceError: private is not defined

कॉल समारोह हमें उचित संदर्भ के साथ निजी समारोह कॉल करने के लिए अनुमति देता है ( this)।


Node.js के साथ सरल

आप उपयोग कर रहे हैं Node.js , आप की जरूरत नहीं है Iife क्योंकि आप का लाभ ले सकते मॉड्यूल लोड हो रहा है प्रणाली :

function MyObject (foo) {
    this._foo = foo;
}

function privateFun (prefix) {
    return prefix + this._foo;
}

MyObject.prototype.publicFun = function () {
    return privateFun.call(this, '>>');
}

exports.MyObject = MyObject;

फ़ाइल लोड करें:

var MyObject = require('./MyObject').MyObject;

var myObject = new MyObject('bar');
myObject.publicFun();      // Returns '>>bar'
myObject.privateFun('>>'); // ReferenceError: private is not defined


(प्रयोगात्मक) बिंद संचालक के साथ ईएस 7

बाइंड ऑपरेटर ::एक ECMAScript प्रस्ताव है और इसे बाबेल ( चरण 0 ) में लागू किया गया है

export default class MyObject {
  constructor (foo) {
    this._foo = foo;
  }

  publicFun () {
    return this::privateFun('>>');
  }
}

function privateFun (prefix) {
  return prefix + this._foo;
}

फ़ाइल लोड करें:

import MyObject from './MyObject';

let myObject = new MyObject('bar');
myObject.publicFun();      // Returns '>>bar'
myObject.privateFun('>>'); // TypeError: myObject.privateFun is not a function

34
यह सबसे अच्छा जवाब है। निजी तरीकों का लाभ, कोई कबाड़ नहीं।
टेलरमैक्स

1
@TaylorMac .callभाग को छोड़कर ।
pishpish

1
@ जंजी हू? यह सवाल का बिंदु है, f()जावास्क्रिप्ट में कोई निजी नहीं है (फिलहाल नहीं)।
यव्स। एम।

2
@YvesM। प्रश्न का बिंदु सबसे अच्छा पैटर्न चुन रहा है जो इसे अनुकरण करता है।
19

1
@changed छुपे कार्यों (बाहर से कॉल करने योग्य), अच्छा सिंटैक्स (नहीं .call) और छोटी मेमोरी (उदाहरण पर कोई फ़ंक्शन नहीं ) के लिए सबसे अच्छा समझौता क्या है ? क्या वह भी मौजूद है?
सिप्रियन टोमोआग्यो

161

आप इस तरह से निजी तरीकों का अनुकरण कर सकते हैं:

function Restaurant() {
}

Restaurant.prototype = (function() {
    var private_stuff = function() {
        // Private code here
    };

    return {

        constructor:Restaurant,

        use_restroom:function() {
            private_stuff();
        }

    };
})();

var r = new Restaurant();

// This will work:
r.use_restroom();

// This will cause an error:
r.private_stuff();

इस तकनीक के बारे में अधिक जानकारी यहाँ: http://webreflection.blogspot.com/2008/04/natural-javascript-pStreet-methods.html


7
मैं डगलस क्रॉकफोर्ड की साइट को निजी / सार्वजनिक तरीकों और सदस्यों पर संसाधन के रूप में सुझाता हूं javascript.crockford.com/pStreet.html
Jared

10
उन्होंने प्रश्न में उस लिंक का उल्लेख किया।
गुलज़ार नाज़िम

8
इस पद्धति का नकारात्मक पक्ष यह है कि आप Private_stuff नहीं कर सकते () रेस्तरां में अन्य निजी डेटा तक पहुँच सकते हैं और अन्य रेस्तरां विधियाँ निजी_stuff () को कॉल नहीं कर सकते हैं। उल्टा यह है कि अगर आपको मेरे द्वारा बताई गई शर्तों की जरूरत नहीं है, तो आप प्रोटोटाइप में use_restroom () रख सकते हैं।
17 की 26

6
यह समाधान और स्वीकृत उत्तर होना चाहिए क्योंकि लेखक स्पष्ट रूप से प्रोटोटाइप संपत्ति का उपयोग कर रहा है।
गेब्रियल लामास

23
पैटर्न के साथ @georgebrock द्वारा प्रस्तावित सभी निजी डेटा बीच साझा किया जाएगा सब रेस्टोरेंट वस्तुओं। यह स्थिर निजी चर और वर्ग आधारित OOP में कार्यों के समान है। मैं मानता हूं कि ओपी ऐसा नहीं चाहता। मेरा मतलब समझने के लिए, मैंने एक jsFiddle बनाया ।
फेकली जूल

35

इन स्थितियों में जब आपके पास एक सार्वजनिक एपीआई है, और आप निजी और सार्वजनिक तरीकों / गुणों को पसंद करेंगे, तो मैं हमेशा मॉड्यूल पैटर्न का उपयोग करता हूं। इस पैटर्न को YUI लाइब्रेरी के भीतर लोकप्रिय बनाया गया था, और विवरण यहां पाया जा सकता है:

http://yuiblog.com/blog/2007/06/12/module-pattern/

यह वास्तव में सीधा है, और अन्य डेवलपर्स के लिए समझना आसान है। एक साधारण उदाहरण के लिए:

var MYLIB = function() {  
    var aPrivateProperty = true;
    var aPrivateMethod = function() {
        // some code here...
    };
    return {
        aPublicMethod : function() {
            aPrivateMethod(); // okay
            // some code here...
        },
        aPublicProperty : true
    };  
}();

MYLIB.aPrivateMethod() // not okay
MYLIB.aPublicMethod() // okay

इस तरह की बात का पता एक आईडीई के स्वत: पूर्ण द्वारा नहीं लगाया जाएगा :(
क्लिक करें

19
लेकिन यह एक वर्ग नहीं है, इसलिए आपके पास विभिन्न राज्यों के साथ इसके 2 "उदाहरण" नहीं हो सकते हैं।
DevAntoine

() हिस्सा निकालें और आपके पास "क्लास" है। कम से कम जहां आप अलग-अलग राज्यों के साथ अलग-अलग isntances को तुरंत कर सकते हैं। मॉड्यूल पैटर्न काफी मेमोरी इंटेंसिव है, हालांकि ...
ऑलिगॉफ्रेन

@DevAntoine 26 के 17 उत्तरों के लिए टिप्पणियों को देखें। जावास्क्रिप्ट में एक्स्टेंसिबल कक्षाएं और निजी तरीके आसानी से हाथ से नहीं जाते हैं। इस मामले में मेरा सुझाव विरासत पर रचना के साथ जाना होगा। संलग्न कंक्रीट ऑब्जेक्ट के समान तरीकों के साथ एक एक्स्टेंसिबल प्रोटोटाइप बनाएं। फिर अपने प्रोटोटाइप में आंतरिक आप तय कर सकते हैं कि आपके ठोस ऑब्जेक्ट पर तरीकों को कब बुलाया जाए।

क्या निजी कार्यों से सार्वजनिक चर को कॉल करने के लिए कोई नकारात्मक पहलू है जैसे aPrivateMethod = function() { MYLIB.aPublicProperty}:?
हन्ना

21

यहां वह वर्ग है जो मैंने यह समझने के लिए बनाया है कि डगलस क्रॉकफोर्ड ने जावास्क्रिप्ट में अपनी साइट निजी सदस्यों में क्या सुझाव दिया है

function Employee(id, name) { //Constructor
    //Public member variables
    this.id = id;
    this.name = name;
    //Private member variables
    var fName;
    var lName;
    var that = this;
    //By convention, we create a private variable 'that'. This is used to     
    //make the object available to the private methods. 

    //Private function
    function setFName(pfname) {
        fName = pfname;
        alert('setFName called');
    }
    //Privileged function
    this.setLName = function (plName, pfname) {
        lName = plName;  //Has access to private variables
        setFName(pfname); //Has access to private function
        alert('setLName called ' + this.id); //Has access to member variables
    }
    //Another privileged member has access to both member variables and private variables
    //Note access of this.dataOfBirth created by public member setDateOfBirth
    this.toString = function () {
        return 'toString called ' + this.id + ' ' + this.name + ' ' + fName + ' ' + lName + ' ' + this.dataOfBirth; 
    }
}
//Public function has access to member variable and can create on too but does not have access to private variable
Employee.prototype.setDateOfBirth = function (dob) {
    alert('setDateOfBirth called ' + this.id);
    this.dataOfBirth = dob;   //Creates new public member note this is accessed by toString
    //alert(fName); //Does not have access to private member
}
$(document).ready()
{
    var employee = new Employee(5, 'Shyam'); //Create a new object and initialize it with constructor
    employee.setLName('Bhaskar', 'Ram');  //Call privileged function
    employee.setDateOfBirth('1/1/2000');  //Call public function
    employee.id = 9;                     //Set up member value
    //employee.setFName('Ram');  //can not call Private Privileged method
    alert(employee.toString());  //See the changed object

}


8
thatthisजब कोई कार्य किसी भिन्न ऑब्जेक्ट से बँधा हो, तो स्कूपिंग समस्या से बचने के लिए इसका उपयोग किया जाता है । यहाँ, आप भंडारण कर रहे हैं thisमें thatहै और यह कभी नहीं का उपयोग कर फिर से जो यह बिल्कुल नहीं कर रही के समान है। आपको सभी आंतरिक कार्यों के thisसाथ बदलना चाहिए (तरीकों की घोषणा नहीं)। अगर है एड या किसी तरह से एड इन तरीकों के बाद से फेंक सकती है गलत तरीके से बाध्य होंगे। thatConstructoremployeeapplycallthis
मारसोइ

इसके अलावा, हर उदाहरण में निजी कार्यों की पूरी प्रतिलिपि होगी, अक्षम। इस तथ्य के शीर्ष पर कि सार्वजनिक विधियाँ निजी वर्ग के संस्करणों तक नहीं पहुँच सकती हैं, मुझे डार्ट पर स्विच करने के लिए प्रेरित करती हैं। दुर्भाग्य से angulardart सुपर बीटा है।
रे फॉस

इसमें "कंस्ट्रक्टर" विधि कहाँ है? मैं तर्क कहां डालूंगा जो सामान्य तौर पर एक वर्ग के कंस्ट्रक्टर पद्धति में निष्पादित होता है जब इसे तत्काल किया जाता है?
BadHorsie

13

मैंने इसे समझा: EDIT: वास्तव में, किसी ने एक समान समाधान से जोड़ा है। ओह!

var Car = function() {
}

Car.prototype = (function() {
    var hotWire = function() {
        // Private code *with* access to public properties through 'this'
        alert( this.drive() ); // Alerts 'Vroom!'
    }

    return {
        steal: function() {
            hotWire.call( this ); // Call a private method
        },
        drive: function() {
            return 'Vroom!';
        }
    };
})();

var getAwayVechile = new Car();

hotWire(); // Not allowed
getAwayVechile.hotWire(); // Not allowed
getAwayVechile.steal(); // Alerts 'Vroom!'

1
यह एक अच्छी तकनीक है, लेकिन आप अपने निर्माता में मापदंडों की अनुमति कैसे देंगे? उदाहरण के लिए गति var getAwayVehicle = new Car(100);कहां 100है और आप गति को सचेत करना चाहते हैं। धन्यवाद!
जेसन

1
यह पता लगा, हो सकता है var Car = function(speed) { this.speed = speed; }और `वापसी {कंस्ट्रक्टर: कार, ...`
जेसन

11

मुझे लगता है कि क्लोजर की समझ की कमी के कारण ऐसे प्रश्न बार-बार आते हैं। जेएस में Сlosures सबसे महत्वपूर्ण बात है। हर JS प्रोग्रामर को इसका सार महसूस करना होता है।

1. सबसे पहले हमें अलग से स्कोप (क्लोजर) बनाने की जरूरत है।

function () {

}

2. इस क्षेत्र में हम जो चाहें कर सकते हैं। और किसी को इसके बारे में पता नहीं चलेगा।

function () {
    var name,
        secretSkills = {
            pizza: function () { return new Pizza() },
            sushi: function () { return new Sushi() }
        }

    function Restaurant(_name) {
        name = _name
    }
    Restaurant.prototype.getFood = function (name) {
        return name in secretSkills ? secretSkills[name]() : null
    }
}

3. दुनिया को हमारे रेस्तरां वर्ग के बारे में जानने के लिए, हमें इसे बंद करने से वापस लौटना होगा।

var Restaurant = (function () {
    // Restaurant definition
    return Restaurant
})()

4. अंत में, हमारे पास:

var Restaurant = (function () {
    var name,
        secretSkills = {
            pizza: function () { return new Pizza() },
            sushi: function () { return new Sushi() }
        }

    function Restaurant(_name) {
        name = _name
    }
    Restaurant.prototype.getFood = function (name) {
        return name in secretSkills ? secretSkills[name]() : null
    }
    return Restaurant
})()

5. साथ ही, इस दृष्टिकोण में वंशानुक्रम और गतिरोध के लिए क्षमता है

// Abstract class
function AbstractRestaurant(skills) {
    var name
    function Restaurant(_name) {
        name = _name
    }
    Restaurant.prototype.getFood = function (name) {
        return skills && name in skills ? skills[name]() : null
    }
    return Restaurant
}

// Concrete classes
SushiRestaurant = AbstractRestaurant({ 
    sushi: function() { return new Sushi() } 
})

PizzaRestaurant = AbstractRestaurant({ 
    pizza: function() { return new Pizza() } 
})

var r1 = new SushiRestaurant('Yo! Sushi'),
    r2 = new PizzaRestaurant('Dominos Pizza')

r1.getFood('sushi')
r2.getFood('pizza')

मुझे आशा है कि इससे किसी को इस विषय को बेहतर ढंग से समझने में मदद मिलेगी


2
आपके पास बिंदु 4 में है। अद्भुत है! मुझे लगता है कि यह यहां सभी लोगों का एकमात्र उत्तर है जहां आपको प्रोटोटाइप पर विधियों का उपयोग करने के प्रदर्शन / मेमोरी लाभ दोनों मिलते हैं और इन सार्वजनिक तरीकों की निजी सदस्यों तक पूरी पहुंच है। +1
हडून

7
यह काम नहीं करता है। यहाँ नाम चर स्थिर चर की तरह काम करता है और रेस्तरां के सभी उदाहरणों द्वारा साझा किया जाता है। यहां jsbin: jsbin.com/oqewUWa/2/edit?js,output
शीतल शाह

यह एक अच्छी कोशिश है, लेकिन जैसा कि शीतल ने बताया, नाम चर छोटी गाड़ी है।
ऑलिगॉफ्रेन 16

2
मेरे 2 सी को जोड़ने से यह पुष्टि करने के लिए काम नहीं करता है, अच्छा लग रहा है, लेकिन जैसा कि ऊपर बताया गया है "नाम" एक स्थिर चर के रूप में काम करेगा अर्थात सभी उदाहरणों में साझा किया जाएगा
पॉल कैरोल

10

व्यक्तिगत रूप से, मैं जावास्क्रिप्ट बनाने के लिए निम्न पैटर्न पसंद करता हूं:

var myClass = (function() {
    // Private class properties go here

    var blueprint = function() {
        // Private instance properties go here
        ...
    };

    blueprint.prototype = { 
        // Public class properties go here
        ...
    };

    return  {
         // Public class properties go here
        create : function() { return new blueprint(); }
        ...
    };
})();

जैसा कि आप देख सकते हैं, यह आपको वर्ग गुणों और उदाहरण गुणों दोनों को परिभाषित करने की अनुमति देता है, जिनमें से प्रत्येक सार्वजनिक और निजी हो सकता है।


डेमो

var Restaurant = function() {
    var totalfoodcount = 0;        // Private class property
    var totalrestroomcount  = 0;   // Private class property
    
    var Restaurant = function(name){
        var foodcount = 0;         // Private instance property
        var restroomcount  = 0;    // Private instance property
        
        this.name = name
        
        this.incrementFoodCount = function() {
            foodcount++;
            totalfoodcount++;
            this.printStatus();
        };
        this.incrementRestroomCount = function() {
            restroomcount++;
            totalrestroomcount++;
            this.printStatus();
        };
        this.getRestroomCount = function() {
            return restroomcount;
        },
        this.getFoodCount = function() {
            return foodcount;
        }
    };
   
    Restaurant.prototype = {
        name : '',
        buy_food : function(){
           this.incrementFoodCount();
        },
        use_restroom : function(){
           this.incrementRestroomCount();
        },
        getTotalRestroomCount : function() {
            return totalrestroomcount;
        },
        getTotalFoodCount : function() {
            return totalfoodcount;
        },
        printStatus : function() {
           document.body.innerHTML
               += '<h3>Buying food at '+this.name+'</h3>'
               + '<ul>' 
               + '<li>Restroom count at ' + this.name + ' : '+ this.getRestroomCount() + '</li>'
               + '<li>Food count at ' + this.name + ' : ' + this.getFoodCount() + '</li>'
               + '<li>Total restroom count : '+ this.getTotalRestroomCount() + '</li>'
               + '<li>Total food count : '+ this.getTotalFoodCount() + '</li>'
               + '</ul>';
        }
    };

    return  { // Singleton public properties
        create : function(name) {
            return new Restaurant(name);
        },
        printStatus : function() {
          document.body.innerHTML
              += '<hr />'
              + '<h3>Overview</h3>'
              + '<ul>' 
              + '<li>Total restroom count : '+ Restaurant.prototype.getTotalRestroomCount() + '</li>'
              + '<li>Total food count : '+ Restaurant.prototype.getTotalFoodCount() + '</li>'
              + '</ul>'
              + '<hr />';
        }
    };
}();

var Wendys = Restaurant.create("Wendy's");
var McDonalds = Restaurant.create("McDonald's");
var KFC = Restaurant.create("KFC");
var BurgerKing = Restaurant.create("Burger King");

Restaurant.printStatus();

Wendys.buy_food();
Wendys.use_restroom();
KFC.use_restroom();
KFC.use_restroom();
Wendys.use_restroom();
McDonalds.buy_food();
BurgerKing.buy_food();

Restaurant.printStatus();

BurgerKing.buy_food();
Wendys.use_restroom();
McDonalds.buy_food();
KFC.buy_food();
Wendys.buy_food();
BurgerKing.buy_food();
McDonalds.buy_food();

Restaurant.printStatus();

इस फिडल को भी देखें ।


यह मैं ES6 कक्षाओं का उपयोग और देखते हैं कि यह बहुत transpiles करना चाहते हैं बनाता है
sheriffderek

9

इस क्लोजर के सभी आप खर्च होंगे। सुनिश्चित करें कि आप विशेष रूप से IE में गति निहितार्थ का परीक्षण करते हैं। आप पाएंगे कि आप एक नामकरण सम्मेलन के साथ बेहतर हैं। अभी भी बहुत सारे कॉर्पोरेट वेब उपयोगकर्ता हैं जो IE6 का उपयोग करने के लिए मजबूर हैं ...


34
कौन परवाह करता है, गंभीरता से?
अयय

17
वह 9% जो अभी भी IE6 का उपयोग कर रहे हैं वे गति, अनुकूलन और सभी आधुनिक एचटीएमएल 5 विशेषताओं के बारे में परवाह नहीं करते हैं। इसलिए बंद करने से कुछ भी खर्च नहीं होगा।
गेब्रियल लामास


7
@LorenzoPolidori w3schools उपयोगकर्ता! == कॉर्पोरेट वेब उपयोगकर्ता?]
WynandB

एक नामकरण सम्मेलन (उदा: एक अंडरस्कोर को रोकना) जाने का रास्ता है। कोड बनाए रखना आसान है और विधियों को अभी भी प्रोटोटाइप पर परिभाषित किया गया है। आजकल हालांकि ... मैं सिर्फ टाइपस्क्रिप्ट में निजी के रूप में विधि को चिह्नित करता हूं।
डेविड शेरेट

5

इतनी क्रिया मत बनो। यह जावास्क्रिप्ट है। एक नामकरण कन्वेंशन का उपयोग करें ।

Es6 वर्गों में काम करने के वर्षों के बाद, मैंने हाल ही में एक es5 परियोजना पर काम शुरू कर दिया है (आवश्यकताJJS का उपयोग करना जो पहले से ही बहुत ही क्रियाशील है)। मैं यहां बताई गई सभी रणनीतियों से अधिक रहा हूं और यह सभी मूल रूप से नामकरण सम्मेलन का उपयोग करने के लिए उबलते हैं :

  1. जावास्क्रिप्ट में गुंजाइश कीवर्ड नहीं हैं जैसे private। जावास्क्रिप्ट में प्रवेश करने वाले अन्य डेवलपर्स को यह पता चल जाएगा। इसलिए, एक साधारण नामकरण सम्मेलन पर्याप्त से अधिक है। अंडरस्कोर के साथ प्रीफ़िक्सिंग का एक सरल नामकरण सम्मेलन निजी गुणों और निजी तरीकों दोनों की समस्या को हल करता है।
  2. आइए गति कारणों के लिए प्रोटोटाइप का लाभ उठाएं, लेकिन इससे अधिक क्रिया नहीं होने देता। आइए es5 "वर्ग" को उसी तरह से देखने की कोशिश करें जो हम अन्य बैकएंड भाषाओं में उम्मीद कर सकते हैं (और हर फ़ाइल को एक वर्ग के रूप में मानें, भले ही हमें एक उदाहरण वापस करने की आवश्यकता न हो)।
  3. आइए अधिक यथार्थवादी मॉड्यूल स्थिति के साथ प्रदर्शित करें (हम पुराने es5 और पुराने आवश्यकताएं का उपयोग करेंगे)।

मेरी-tooltip.js

    define([
        'tooltip'
    ],
    function(
        tooltip
    ){

        function MyTooltip() {
            // Later, if needed, we can remove the underscore on some
            // of these (make public) and allow clients of our class
            // to set them.
            this._selector = "#my-tooltip"
            this._template = 'Hello from inside my tooltip!';
            this._initTooltip();
        }

        MyTooltip.prototype = {
            constructor: MyTooltip,

            _initTooltip: function () {
                new tooltip.tooltip(this._selector, {
                    content: this._template,
                    closeOnClick: true,
                    closeButton: true
                });
            }
        }

        return {
            init: function init() {
               new MyTooltip();  // <-- Our constructor adds our tooltip to the DOM so not much we need to do after instantiation.
            }

            // You could instead return a new instantiation, 
            // if later you do more with this class.
            /* 
            create: function create() {
               return new MyTooltip();
            }
            */
        }
    });

2
यह ध्यान दिया जाना चाहिए कि न तो जावास्क्रिप्ट भाषा और न ही कोई विशिष्ट ब्राउज़र होस्ट किसी भी ऑब्जेक्ट को परिभाषित करता है जो निजी राज्य को "छिपाने" के लिए नामकरण पर भरोसा करते हैं, इसलिए जब आप सही हो सकते हैं कि डेवलपर्स अवधारणा को समझेंगे, तो यह अभी भी बहुत गैर की ओर जाता है- OO प्रोग्रामिंग के लिए OO दृष्टिकोण।
अमीर रेवर

क्या मुझे ऐसा बनाने में एक अच्छा संदर्भ चाहिए? इस उदाहरण के कुछ हिस्से हैं जो मेरे लिए नए हैं। define, और constructorऔर संरचना ही। जबकि मैं ज्यादातर जवाब पर सहमत हूं, मैंने बहुत सारे ओओपी प्रभाव के साथ जेएस के साथ काम करना शुरू कर दिया है और यहां तक ​​कि टीएस के लिए बहुत जल्दी कूद गया क्योंकि मुझे सी # से पहले का अनुभव था। मुझे लगता है कि मुझे इन सामानों को अनजान करना होगा और प्रोटोटाइप / प्रक्रियात्मक प्रतिमान को समझना होगा। (upvoted, btw)
कोल्ड सेर्बस

1
@ColdCerberus यह कोड स्निपेट es5 का उपयोग कर रहा है। : आप इस दृष्टिकोण यहां की पूरी तस्वीर देख सकते हैं gist.github.com/jonnyreeves/2474026 । लेकिन ध्यान रखें, आप इस दृष्टिकोण को लेना चाहते हैं और इसे es6 कक्षाओं का उपयोग करके अपडेट करना चाहते हैं: googlechrome.github.io/samples/classes-es6 और es6 मॉड्यूल (आयात / निर्यात सिंटैक्स): hackernoon.com/ ...
prograhammer

5

अब आप es10 निजी तरीकों से ऐसा कर सकते हैं । आपको बस #विधि नाम से पहले जोड़ना होगा ।

class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world';
  }

  getPrivateMessage() {
    return #privateMethod();
  }
}

2
सिवाय इसके चरण 3 है और अभी तक आधिकारिक तौर पर भाषा का हिस्सा नहीं है।
misterhtmlcss

3

क्रॉकफोर्ड के निजी या निजीकृत पैटर्न का पालन करने वाला कोई भी उपाय करें । उदाहरण के लिए:

function Foo(x) {
    var y = 5;
    var bar = function() {
        return y * x;
    };

    this.public = function(z) {
        return bar() + x * z;
    };
}

किसी भी मामले में जहां हमलावर के पास जेएस संदर्भ पर कोई "निष्पादित" अधिकार नहीं है, उसके पास किसी भी "सार्वजनिक" या "निजी" फ़ील्ड या विधियों तक पहुंचने का कोई तरीका नहीं है। यदि हमलावर के पास वह पहुंच है जो वह इस वन-लाइनर को अंजाम दे सकता है:

eval("Foo = " + Foo.toString().replace(
    /{/, "{ this.eval = function(code) { return eval(code); }; "
));

ध्यान दें कि उपरोक्त कोड सभी निर्माता-प्रकार-गोपनीयता के लिए सामान्य है। यह यहाँ कुछ समाधानों के साथ विफल हो जाएगा, लेकिन यह स्पष्ट होना चाहिए कि बहुत सारे क्लोजर आधारित समाधानों को इस तरह से अलग किया जा सकता हैreplace() मापदंडों के ।

यह निष्पादित होने के बाद बनाई गई किसी भी वस्तु के new Foo()पास एक evalविधि है जिसे लौटाने या मूल्यों को बदलने या निर्माणकर्ता के बंद होने में परिभाषित तरीकों को कहा जा सकता है, जैसे:

f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");

एकमात्र समस्या जो मैं यह देख सकता हूं कि यह उन मामलों के लिए काम नहीं करेगा जहां केवल एक ही उदाहरण है और यह लोड पर बनाया गया है। लेकिन तब वास्तव में एक प्रोटोटाइप को परिभाषित करने का कोई कारण नहीं होता है और उस मामले में हमलावर बस निर्माता के बजाय ऑब्जेक्ट को फिर से बना सकता है जब तक कि उसके पास एक ही पैरामीटर पास करने का एक तरीका है (जैसे वे स्थिर हैं या उपलब्ध मूल्यों से गणना की जाती हैं)।

मेरी राय में, यह बहुत क्रॉकफोर्ड के समाधान को बेकार बना देता है। चूंकि "गोपनीयता" आसानी से उसके समाधान के डाउनसाइड को तोड़ दिया जाता है (पठनीयता और स्थिरता में कमी, प्रदर्शन में वृद्धि, स्मृति में वृद्धि) "नो प्राइवेसी" प्रोटोटाइप आधारित पद्धति को बेहतर विकल्प बनाती है।

मैं आमतौर पर अंक __privateऔर _protectedविधियों और फ़ील्ड (पर्ल शैली) को रेखांकित करने के लिए अग्रणी अंडरस्कोर का उपयोग करता हूं , लेकिन जावास्क्रिप्ट में गोपनीयता रखने के विचार से पता चलता है कि यह कैसे गलत भाषा है।

इसलिए मैं क्रॉकफोर्ड के साथ उनके पहले वाक्य को छोड़कर असहमत हूं

तो जेएस में आपको वास्तविक गोपनीयता कैसे मिलती है? सर्वर साइड पर निजी होने के लिए वह सब कुछ रखें और AJAX कॉल करने के लिए JS का उपयोग करें।


यह एक गंभीर मुद्दा है जिसे अधिक जाना जाना चाहिए। क्या इस हमले के खिलाफ 'रक्षा' है?
जेम्स

@ जेम्स कोई भी जिसे मैं नहीं जानता, मुझे लगता है कि यह जानवर की प्रकृति है। जैसा कि मैंने बताया कि आप सर्वर को कार्यक्षमता को स्थानांतरित कर सकते हैं जहां यह संरक्षित वातावरण में चलता है। मैं अपने जवाब में जो बात करना चाहता था, वह यह है कि क्रॉकफोर्ड का समाधान मदद नहीं कर रहा है, अनावश्यक रूप से कोड को उलझाता है और इसके बारे में कुछ करने की आवश्यकता को छुपाता है।
फोजी

यदि कोई उपयोगकर्ता गुप्त पासवर्ड दर्ज करता है, तो वह यह सर्वर-साइड नहीं कर सकता है। कुछ बिंदु पर पासवर्ड एक 'निजी' संस्करण में होगा। तो क्या कोई हमलावर इसे पढ़ सकता है? मुझे अपने कोड पर भरोसा है, और वैसे भी मेरे घर के मानक निष्कासन () की अनुमति नहीं देते हैं। हमलावर कुछ दुर्भावनापूर्ण तृतीय पक्ष जावास्क्रिप्ट प्लग-इन या लाइब्रेरी हो सकता है जिसे मैंने ठीक से जांच नहीं किया था - इसलिए, हां मुझे इनकी जांच करने की आवश्यकता है। हमलावर उस तरफ के विज्ञापन जैसा भी हो सकता है जो मेरे कोड के साथ बातचीत न करे। मैं एक अज्ञात में अपने सभी कोड को लपेटकर उस के खिलाफ रक्षा करता हूं (function () {allMyStuff}());ताकि वैश्विक कुछ भी उजागर न हो।
जेम्स

@ जेम्स यह ओटी मिल रहा है, यदि आप इसे जारी रखना चाहते हैं तो कृपया एक नया प्रश्न खोलें। हां, एक हमलावर पासवर्ड पढ़ सकता है। आपके "निजी" चर से। या डोम से। या वह AJAX एपीआई की जगह ले सकता है। या वह आपके पेज को किसी और चीज़ से बदल देता है। यदि वह उपरोक्त में से कोई भी नहीं कर सकता है तो जेएस "गोपनीयता" की कोई आवश्यकता नहीं है क्योंकि वह आपके किसी भी जेएस चर को नहीं पढ़ सकता है। मुद्दा यह है कि क्रॉकफोर्ड का "समाधान" जिसका हर कोई अभी उपयोग कर रहा है, इस समस्या के साथ मदद नहीं कर रहा है।
फोजी

मेरा मानना ​​है कि छद्म आयामी कोड उत्पीड़न इस हमले के खिलाफ एक कमजोर बचाव हो सकता है - फ़ंक्शन बॉडी को संशोधित करने के लिए अधिक कठिन जब आप एक निश्चित नाम वाले फ़ंक्शन पर निर्भर नहीं हो सकते; अधिक कठिन है f.eval('nameOfVariable')जब आप नहीं जानते कि क्या 'nameOfVariable'है ...
Gershom


2

यदि आप सार्वजनिक और निजी कार्यों की पूरी श्रृंखला चाहते हैं, तो सार्वजनिक कार्यों के लिए निजी कार्यों तक पहुंचने की क्षमता, इस तरह की वस्तु के लिए लेआउट कोड:

function MyObject(arg1, arg2, ...) {
  //constructor code using constructor arguments...
  //create/access public variables as 
  // this.var1 = foo;

  //private variables

  var v1;
  var v2;

  //private functions
  function privateOne() {
  }

  function privateTwon() {
  }

  //public functions

  MyObject.prototype.publicOne = function () {
  };

  MyObject.prototype.publicTwo = function () {
  };
}

क्या कोई मुझे बता सकता है कि यह मतदान क्यों हुआ? मुझे ठीक लगता है।
थोमसट्रुटर

10
हर बार जब आप ऐसा करते हैं new MyObject, MyObjectउसी के मान को बदल दिया जाता है।
bpierre

2
-1। कभी भी .prototypeकंस्ट्रक्टर के अंदर का काम न करें।
बरगी

2
var TestClass = function( ) {

    var privateProperty = 42;

    function privateMethod( ) {
        alert( "privateMethod, " + privateProperty );
    }

    this.public = {
        constructor: TestClass,

        publicProperty: 88,
        publicMethod: function( ) {
            alert( "publicMethod" );
            privateMethod( );
        }
    };
};
TestClass.prototype = new TestClass( ).public;


var myTestClass = new TestClass( );

alert( myTestClass.publicProperty );
myTestClass.publicMethod( );

alert( myTestClass.privateMethod || "no privateMethod" );

जियोब्रुक के समान लेकिन थोड़ी कम क्रिया (IMHO) इस तरह से करने के साथ कोई समस्या? (मैंने इसे कहीं नहीं देखा है)

संपादित करें: मुझे एहसास हुआ कि यह थोड़े बेकार है क्योंकि प्रत्येक स्वतंत्र तात्कालिकता की सार्वजनिक विधियों की अपनी प्रतिलिपि है, इस प्रकार प्रोटोटाइप के उपयोग को कम किया गया है।


2

यहाँ मैंने निजी / सार्वजनिक विधियों / सदस्यों और जावास्क्रिप्ट में तात्कालिकता के बारे में अब तक सबसे अधिक आनंद लिया है:

यहाँ लेख है: http://www.sefol.com/?p=1090

और यहाँ उदाहरण है:

var Person = (function () {

    //Immediately returns an anonymous function which builds our modules 
    return function (name, location) {

        alert("createPerson called with " + name);

        var localPrivateVar = name;

        var localPublicVar = "A public variable";

        var localPublicFunction = function () {
            alert("PUBLIC Func called, private var is :" + localPrivateVar)
        };

        var localPrivateFunction = function () {
            alert("PRIVATE Func called ")
        };

        var setName = function (name) {

            localPrivateVar = name;

        }

        return {

            publicVar: localPublicVar,

            location: location,

            publicFunction: localPublicFunction,

            setName: setName

        }

    }
})();


//Request a Person instance - should print "createPerson called with ben"
var x = Person("ben", "germany");

//Request a Person instance - should print "createPerson called with candide"
var y = Person("candide", "belgium");

//Prints "ben"
x.publicFunction();

//Prints "candide"
y.publicFunction();

//Now call a public function which sets the value of a private variable in the x instance
x.setName("Ben 2");

//Shouldn't have changed this : prints "candide"
y.publicFunction();

//Should have changed this : prints "Ben 2"
x.publicFunction();

JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/


इस दृष्टिकोण में एक महत्वपूर्ण अवधारणा है - यदि आपने 2 ऑब्जेक्ट बनाए हैं, तो स्मृति में 2 समान मैथ्स (उदाहरण के लिए PublicFunction) होंगे 1000 ऑब्जेक्ट्स आपकी सभी मेमोरी खाएंगे।
आर्टेम जी

2

मॉड्यूल पैटर्न ज्यादातर मामलों में सही है। लेकिन अगर आपके पास हजारों उदाहरण हैं, तो कक्षाएं स्मृति को बचाती हैं। यदि स्मृति को सहेजना एक चिंता का विषय है और आपकी वस्तुओं में थोड़ी मात्रा में निजी डेटा हैं, लेकिन बहुत सारे सार्वजनिक कार्य हैं, तो आप चाहते हैं कि सभी सार्वजनिक फ़ंक्शन मेमोरी को बचाने के लिए .prototyp में रहें।

मैंने ये ढूंढ निकाला:

var MyClass = (function () {
    var secret = {}; // You can only getPriv() if you know this
    function MyClass() {
        var that = this, priv = {
            foo: 0 // ... and other private values
        };
        that.getPriv = function (proof) {
            return (proof === secret) && priv;
        };
    }
    MyClass.prototype.inc = function () {
        var priv = this.getPriv(secret);
        priv.foo += 1;
        return priv.foo;
    };
    return MyClass;
}());
var x = new MyClass();
x.inc(); // 1
x.inc(); // 2

वस्तु privमें निजी गुण होते हैं। यह सार्वजनिक फ़ंक्शन के माध्यम से पहुंच योग्य है getPriv(), लेकिन यह फ़ंक्शन falseतब तक लौटता है जब तक आप इसे पास नहीं करते हैं secret, और यह केवल मुख्य क्लोजर के अंदर जाना जाता है।


जो संरक्षित सदस्यों का अनुकरण करता है, उससे प्राप्त होने वाले प्रकार संरक्षित सदस्यों तक पहुँच सकते हैं। मैं इस पैटर्न को निजी तौर पर भी पसंद करता हूं
HMR

2

इस बारे में क्या?

var Restaurant = (function() {

 var _id = 0;
 var privateVars = [];

 function Restaurant(name) {
     this.id = ++_id;
     this.name = name;
     privateVars[this.id] = {
         cooked: []
     };
 }

 Restaurant.prototype.cook = function (food) {
     privateVars[this.id].cooked.push(food);
 }

 return Restaurant;

})();

तत्काल फ़ंक्शन के दायरे से बाहर निजी चर खोज असंभव है। स्मृति को बचाने, कार्यों का कोई दोहराव नहीं है।

नकारात्मक पक्ष यह है कि निजी चर की खोज क्लंकी के privateVars[this.id].cookedप्रकार के लिए हास्यास्पद है। एक अतिरिक्त "आईडी" चर भी है।


यह छोड़ देंगे Restaurantके रूप में undefinedक्योंकि आप गुमनाम समारोह से कुछ भी नहीं लौटा रही हैं।
user4815162342

कहां और कैसे? बनाए गए रेस्तरां के संदर्भ को मान लेने से, PrivateVars के पास उसके स्वामी का संदर्भ नहीं होगा। संदर्भ ग्राफ एसाइक्लिक है। मैं क्या खो रहा हूँ?
इवान लेइस

वास्तव में यह एकमात्र उत्तर है जो विधियों के अलावा निजी गुणों का समर्थन करता है। उत्तर में केवल दो मुद्दे पहले से ही नोट किए गए हैं।
पिशिश

मुझे एक स्मृति रिसाव दिखाई देता है: जब एक उदाहरण Restaurantको कचरा एकत्र किया जाता है, तो इसके मान भीतर रहते हैं privateVars। एक WeakMapके लिए एक अच्छा प्रतिस्थापन हो सकता है Arrayइस मामले में।
गेरशोम

2

अनाम फ़ंक्शन में सभी कोड लपेटें: फिर, सभी कार्य निजी होंगे, केवल windowऑब्जेक्ट से जुड़े कार्य :

(function(w,nameSpacePrivate){
     w.Person=function(name){
         this.name=name;   
         return this;
     };

     w.Person.prototype.profilePublic=function(){
          return nameSpacePrivate.profile.call(this);
     };  

     nameSpacePrivate.profile=function(){
       return 'My name is '+this.name;
     };

})(window,{});

इसे इस्तेमाल करो :

  var abdennour=new Person('Abdennour');
  abdennour.profilePublic();

बेला


1

मैं एक संबद्ध में निजी डेटा संग्रहीत करना पसंद करता हूं WeakMap। यह आपको अपने सार्वजनिक तरीकों को प्रोटोटाइप पर रखने की अनुमति देता है जहां वे संबंधित हैं। यह बड़ी संख्या में वस्तुओं के लिए इस समस्या को संभालने का सबसे कारगर तरीका लगता है।

const data = new WeakMap();

function Foo(value) {
    data.set(this, {value});
}

// public method accessing private value
Foo.prototype.accessValue = function() {
    return data.get(this).value;
}

// private 'method' accessing private value
function accessValue(foo) {
    return data.get(foo).value;
}

export {Foo};

0

निजी कार्य मॉड्यूल पैटर्न का उपयोग करके सार्वजनिक चर का उपयोग नहीं कर सकते हैं


0

चूंकि हर कोई यहाँ अपना कोड पोस्ट कर रहा था, मैं भी यही करने जा रहा हूँ ...

मुझे क्रॉकफोर्ड पसंद है क्योंकि उसने जावास्क्रिप्ट में वास्तविक वस्तु उन्मुख पैटर्न पेश किए। लेकिन वह एक नई गलतफहमी के साथ भी आया, "वह" एक।

तो वह "वह = यह" क्यों उपयोग कर रहा है? इसका निजी कार्यों से कोई लेना-देना नहीं है। यह आंतरिक कार्यों के साथ करना है!

क्योंकि क्रॉकफोर्ड के अनुसार यह छोटी गाड़ी कोड है:

Function Foo( ) {
    this.bar = 0; 
    var foobar=function( ) {
        alert(this.bar);
    }
} 

इसलिए उन्होंने ऐसा करने का सुझाव दिया:

Function Foo( ) {
    this.bar = 0;
    that = this; 
    var foobar=function( ) {
        alert(that.bar);
    }
}

इसलिए जैसा कि मैंने कहा, मुझे पूरा यकीन है कि क्रॉकफोर्ड उस और इस बारे में उनकी व्याख्या गलत थी (लेकिन उनका कोड निश्चित रूप से सही है)। या वह सिर्फ जावास्क्रिप्ट दुनिया को बेवकूफ बना रहा था, यह जानने के लिए कि उसका कोड कौन कॉपी कर रहा है? मुझे पता नहीं ... मैं कोई ब्राउज़र geek नहीं हूँ;

संपादित करें

आह, बस इतना ही जावास्क्रिप्ट में मतलब है?

तो क्रोकी उनके स्पष्टीकरण के साथ वास्तव में गलत था .... लेकिन अपने कोड के साथ सही है, इसलिए वह अभी भी एक महान व्यक्ति है। :))


0

सामान्य तौर पर मैंने निजी ऑब्जेक्ट _ को अस्थायी रूप से ऑब्जेक्ट में जोड़ा है। आपको पद्धति के लिए "पावर-कंस्ट्रक्टर" में गोपनीयता को पूरी तरह से खोलना होगा। यदि आप प्रोटोटाइप से विधि को कॉल करते हैं, तो आप प्रोटोटाइप-विधि को अधिलेखित करने में सक्षम होंगे

  • एक सार्वजनिक विधि को "पावर-कंस्ट्रक्टर" में सुलभ बनाएं: (ctx वस्तु संदर्भ है)

    ctx.test = GD.Fabric.open('test', GD.Test.prototype, ctx, _); // is a private object
  • अब मेरे पास यह ओपन प्राइवेसी है:

    GD.Fabric.openPrivacy = function(func, clss, ctx, _) {
        return function() {
            ctx._ = _;
            var res = clss[func].apply(ctx, arguments);
            ctx._ = null;
            return res;
        };
    };

0

यह वही है जो मैंने काम किया है:

चीनी कोड के एक वर्ग की आवश्यकता है जिसे आप यहां पा सकते हैं । इसके अलावा संरक्षित, विरासत, आभासी, स्थिर सामान का समर्थन करता है ...

;( function class_Restaurant( namespace )
{
    'use strict';

    if( namespace[ "Restaurant" ] ) return    // protect against double inclusions

        namespace.Restaurant = Restaurant
    var Static               = TidBits.OoJs.setupClass( namespace, "Restaurant" )


    // constructor
    //
    function Restaurant()
    {
        this.toilets = 3

        this.Private( private_stuff )

        return this.Public( buy_food, use_restroom )
    }

    function private_stuff(){ console.log( "There are", this.toilets, "toilets available") }

    function buy_food     (){ return "food"        }
    function use_restroom (){ this.private_stuff() }

})( window )


var chinese = new Restaurant

console.log( chinese.buy_food()      );  // output: food
console.log( chinese.use_restroom()  );  // output: There are 3 toilets available
console.log( chinese.toilets         );  // output: undefined
console.log( chinese.private_stuff() );  // output: undefined

// and throws: TypeError: Object #<Restaurant> has no method 'private_stuff'

0
Class({  
    Namespace:ABC,  
    Name:"ClassL2",  
    Bases:[ABC.ClassTop],  
    Private:{  
        m_var:2  
    },  
    Protected:{  
        proval:2,  
        fight:Property(function(){  
            this.m_var--;  
            console.log("ClassL2::fight (m_var)" +this.m_var);  
        },[Property.Type.Virtual])  
    },  
    Public:{  
        Fight:function(){  
            console.log("ClassL2::Fight (m_var)"+this.m_var);  
            this.fight();  
        }  
    }  
});  

https://github.com/nooning/JSClass


0

मैंने एक नया टूल बनाया है जिससे आप प्रोटोटाइप पर सही निजी तरीकों की अनुमति दे सकते हैं https://github.com/TremayneChrist/ProtectJS

उदाहरण:

var MyObject = (function () {

  // Create the object
  function MyObject() {}

  // Add methods to the prototype
  MyObject.prototype = {

    // This is our public method
    public: function () {
      console.log('PUBLIC method has been called');
    },

    // This is our private method, using (_)
    _private: function () {
      console.log('PRIVATE method has been called');
    }
  }

  return protect(MyObject);

})();

// Create an instance of the object
var mo = new MyObject();

// Call its methods
mo.public(); // Pass
mo._private(); // Fail

1
क्या आप बता सकते हैं कि यह कैसे काम करता है, कृपया? आप विधि को कैसे / कहां कह सकते हैं _private?
बरगी

0

आपको अपने वास्तविक निर्माता-फ़ंक्शन के चारों ओर एक क्लोजर रखना होगा, जहां आप अपने निजी तरीकों को परिभाषित कर सकते हैं। इन निजी तरीकों के माध्यम से इंस्टेंस के डेटा को बदलने के लिए, आपको उन्हें "यह" उनके साथ, फ़ंक्शन तर्क के रूप में या .apply (इस) के साथ इस फ़ंक्शन को कॉल करके देना होगा:

var Restaurant = (function(){
    var private_buy_food = function(that){
        that.data.soldFood = true;
    }
    var private_take_a_shit = function(){
        this.data.isdirty = true;   
    }
    // New Closure
    function restaurant()
    {
        this.data = {
            isdirty : false,
            soldFood: false,
        };
    }

    restaurant.prototype.buy_food = function()
    {
       private_buy_food(this);
    }
    restaurant.prototype.use_restroom = function()
    {
       private_take_a_shit.call(this);
    }
    return restaurant;
})()

// TEST:

var McDonalds = new Restaurant();
McDonalds.buy_food();
McDonalds.use_restroom();
console.log(McDonalds);
console.log(McDonalds.__proto__);

वास्तव में, यह काम नहीं करता है। प्रत्येक new Restaurantका अपना स्वयं का restaurantअवरोधक होगा, और "प्रोटोटाइप" का पूरी तरह से दुरुपयोग किया जाता है।
बरगी

@Bergi। वास्तव में, आप सही हैं। यह काम करेगा, लेकिन एक रीसस हॉग भी होगा (क्या इसे ऐसा कहा जाता है?)। मैंने उस संबंध में अपना उत्तर संपादित किया।
फ्लेक्स एलेक्ट्रो डीम्लिंग

अद्यतन के लिए धन्यवाद। पता नहीं क्या पिछले संस्करण को कॉल करने के लिए (लेकिन "बग" :-)
Bergi

0

मुझे पता है कि यह बहुत देर हो चुकी है लेकिन इस बारे में कैसे?

var obj = function(){
    var pr = "private";
    var prt = Object.getPrototypeOf(this);
    if(!prt.hasOwnProperty("showPrivate")){
        prt.showPrivate = function(){
            console.log(pr);
        }
    }    
}

var i = new obj();
i.showPrivate();
console.log(i.hasOwnProperty("pr"));

0

इस सवाल पर पहले से ही कई जवाब हैं, लेकिन कुछ भी मेरी जरूरतों को पूरा नहीं करता है। इसलिए मैं अपने समाधान के साथ आया, मुझे आशा है कि यह किसी के लिए उपयोगी है:

function calledPrivate(){
    var stack = new Error().stack.toString().split("\n");
    function getClass(line){
        var i = line.indexOf(" ");
        var i2 = line.indexOf(".");
        return line.substring(i,i2);
    }
    return getClass(stack[2])==getClass(stack[3]);
}

class Obj{
    privateMethode(){
        if(calledPrivate()){
            console.log("your code goes here");
        }
    }
    publicMethode(){
        this.privateMethode();
    }
}

var obj = new Obj();
obj.publicMethode(); //logs "your code goes here"
obj.privateMethode(); //does nothing

जैसा कि आप देख सकते हैं कि जावास्क्रिप्ट में इस प्रकार की कक्षाओं का उपयोग करते समय यह प्रणाली काम करती है। जहाँ तक मुझे लगा कि उपरोक्त विधियों में से कोई भी टिप्पणी नहीं की है।


1
जिज्ञासु: क्या आपकी ज़रूरत वास्तव में वास्तव में कार्य को उजागर करने की थी, लेकिन इसे रन-टाइम में एक नो-ऑप बनाते हैं - बजाय बाहरी कॉलर्स से छुपाने के बजाय जैसे कि सभी / अधिकांश अन्य उत्तर देते हैं? यदि हां, तो क्यों? आप इस दृष्टिकोण का क्या लाभ मानते हैं? मेरे लिए, यह सिर्फ एक अनावश्यक प्रदर्शन ओवरहेड, एक अस्पष्ट एपीआई और अच्छी तरह से प्रतीत होता है, शायद डिबग नरक का कारण बनता है, लेकिन मैं हमेशा नए दृष्टिकोणों के लिए खुला हूं ...
JHH

2
@JHH ईमानदार होने के लिए, जब मैं इस पर वापस देख रहा हूं, तो मैं बहुत ज्यादा फेसिंग हूं। ओवरहेड आम तौर पर इसके लायक नहीं होता है, हालांकि मेरे लिए यह एक बहुत बड़ी बात नहीं थी क्योंकि मैंने इन वर्गों को कई कॉल नहीं किए थे। मैंने इसे इस तरह से किया है कारण यह है कि यह आपके द्वारा लिखने और कार्यों को कॉल करने के तरीके में अपेक्षाकृत साफ है। मैं उस समय तक प्रतीकों और ऐसे नहीं समझता था, लेकिन अब मैं ऐसा करता हूं, मुझे लगता है कि आम तौर पर कक्षाओं का उपयोग करते समय जाने का रास्ता होता है। मैं इस उत्तर को एक साथ हटाने पर विचार कर रहा हूं। मैंने कई बेवकूफ जवाब पोस्ट किए हैं, लेकिन हे, आप रहते हैं और सीखते हैं।
गुरुग्राम

प्रतिक्रिया के लिए धन्यवाद! मुझे यकीन नहीं था कि अगर मुझे कुछ गलत समझा गया था। लेकिन हाँ, हम सभी जीते हैं और सीखते हैं!
JHH

0

एक निजी और सार्वजनिक इंटरफ़ेस और रचना के लिए समर्थन के साथ स्वच्छ और सरल 'वर्ग' समाधान के लिए इस उत्तर को देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.