Частные методы JavaScript - PullRequest
       154

Частные методы JavaScript

435 голосов
/ 11 сентября 2008

Чтобы создать класс JavaScript с открытым методом, я бы сделал что-то вроде:

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 как закрытый метод, чтобы оба они выполнялись?

Я прочитал рецензию Дуга Крокфорда несколько раз, но не похоже, что "частные" методы могут вызываться открытыми методами, а "привилегированные" методы могут вызываться извне.

Ответы [ 29 ]

0 голосов
/ 29 мая 2011

Частные функции не могут получить доступ к общедоступным переменным, используя шаблон модуля

0 голосов
/ 22 февраля 2017

См. этот ответ , где приведено чистое и простое «классное» решение с закрытым и общедоступным интерфейсом и поддержкой композиции

0 голосов
/ 10 мая 2016

На этот вопрос уже есть много ответов, но ничего не соответствовало моим потребностям. Поэтому я придумала собственное решение, надеюсь, оно кому-нибудь пригодится:

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

Как вы можете видеть, эта система работает при использовании этого типа классов в javascript. Насколько я понял, ни один из вышеупомянутых методов не помог.

0 голосов
/ 11 ноября 2012

Поскольку все публиковали здесь свой код, я тоже это сделаю ...

Мне нравится Крокфорд, потому что он ввел реальные объектно-ориентированные шаблоны в Javascript. Но он также придумал новое недоразумение, «это».

Так почему он использует «это = это»? Это не имеет никакого отношения к частным функциям вообще. Это связано с внутренними функциями!

Потому что, согласно Крокфорду, это ошибочный код:

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

Поэтому он предложил сделать это:

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

Итак, как я уже сказал, я совершенно уверен, что Крокфорд ошибся в его объяснении об этом и об этом (но его код, безусловно, правильный). Или он просто дурачил мир Javascript, чтобы узнать, кто копирует его код? Я не знаю ... я не фанат браузера; D

EDIT

Ах, вот что это такое: Что означает "вар это = это"; значит в JavaScript?

Значит, Крокки был действительно не прав с его объяснением ... но с его кодом, так что он все еще отличный парень. :))

0 голосов
/ 28 января 2015

Я знаю, что уже слишком поздно, но как насчет этого?

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 голосов
/ 30 марта 2013

В общем, я временно добавил частный объект _ в объект. Вы должны открыть конфиденциальность в «Power-constructor» для метода. Если вы вызываете метод из прототипа, вы будете быть в состоянии перезаписать метод-прототип

  • Сделать публичный метод доступным в «Power-constructor»: (ctx - контекст объекта)

    ctx.test = GD.Fabric.open('test', GD.Test.prototype, ctx, _); // is a private object
    
  • Теперь у меня есть openPrivacy:

    GD.Fabric.openPrivacy = function(func, clss, ctx, _) {
        return function() {
            ctx._ = _;
            var res = clss[func].apply(ctx, arguments);
            ctx._ = null;
            return res;
        };
    };
    
0 голосов
/ 17 мая 2013

Вы должны поместить замыкание вокруг вашей фактической функции-конструктора, где вы можете определить свои частные методы. Чтобы изменить данные экземпляров через эти закрытые методы, вы должны передать им «this» с ними, либо в качестве аргумента функции, либо путем вызова этой функции с помощью .apply (this):

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__);
0 голосов
/ 10 декабря 2013
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 голосов
/ 16 января 2014

Я создал новый инструмент, который позволит вам иметь настоящие приватные методы на прототипе 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
...