Инкапсуляция в javascript

Мне нужно создать простой многоразовый объект javascript, публикующий несколько методов и параметризованный конструктор. Прочитав несколько руководств «ООП в JavaScript», я сижу здесь с пустой головой. Как я могу это сделать?

Вот мой последний нерабочий код:

SomeClass = function(id) {
    this._id = id;
}
(function() {
    function intFun() {
        return this._id;
    }
    SomeClass.prototype.extFun = function() {
        return incFun();
    }
})();

Вы вырезали и вставили этот код? Есть пара опечаток: "functin" в строке 4, и я считаю, что "return incFun ();" должен быть return "intFun ();"

Patrick McElhaney 01.12.2008 05:17

Нет. Это упрощенная версия. Думаю, теперь я исправил все опечатки ...

Artem Tikhomirov 01.12.2008 05:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
375
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Это мой обычный подход:

MyClass = function(x, y, z) {
   // This is the constructor. When you use it with "new MyClass(),"
   // then "this" refers to the new object being constructed. So you can
   // assign member variables to it.
   this.x = x;
   ...
};
MyClass.prototype = {
    doSomething: function() {
        // Here we can use the member variable that
        // we created in the constructor.
        return this.x;
    },
    somethingElse: function(a) {
    }
};

var myObj = new MyClass(1,2,3);
alert(myObj.doSomething()); // this will return the object's "x" member
alert(myObj.x); // this will do the same, by accessing the member directly

Обычно ключевое слово this, когда оно используется в одном из методов объекта, относится к самому объекту. Когда вы используете его в конструкторе, он будет ссылаться на новый создаваемый объект. Таким образом, в приведенном выше примере оба оператора предупреждения будут отображать «1».


Исключение из этого правила - когда вы передаете одну из своих функций-членов в другое место, а затем вызываете ее. Например,

myDiv.onclick = myObj.doSomething;

В этом случае JavaScript игнорирует тот факт, что doSomething принадлежит myObj. В результате "this" внутри doSomething будет указывать на другой объект, поэтому метод не будет работать должным образом. Чтобы обойти это, вам нужно указать объект, на который должно ссылаться «this». Вы можете сделать это с помощью функции "call" в JavaScript:

myDiv.onclick = function() {
    myObj.doSomething.call(myObj);
}

Это странно, но со временем к этому привыкнешь. Суть в том, что при передаче методов вам также необходимо передать объект, для которого они должны быть вызваны.

Такой подход не мог скрыть внутреннюю часть класса.

Artem Tikhomirov 01.12.2008 05:11

JavaScript не может скрыть внутренности «класса».

EndangeredMassa 01.12.2008 05:23

Да, булочку можно заархивировать с помощью анонимной функции. Но в приведенном выше примере я потерял указатели "this".

Artem Tikhomirov 01.12.2008 05:26

Кстати, в этом примере я называю объект Мои занятия классом из-за его роли.

Artem Tikhomirov 01.12.2008 05:30

Артем: Вы можете скрыть внутреннее устройство, используя трюк с закрытием, но сначала я бы освоился с описанным выше подходом. Я редактирую сообщение, чтобы уточнить использование слова «это».

JW. 01.12.2008 05:47

Обычно я не слишком беспокоюсь о сокрытии внутренних компонентов, хотя я ставлю перед ними знак подчеркивания, чтобы пометить их как не предназначенные для использования вне «класса». Обычно я делаю следующее:

var MyClass = function() {};

MyClass.prototype = {
   _someVar : null,
   _otherVar : null,

   initialize: function( optionHash ) {
                _someVar = optionsHash["varValue"];
                _otherVar = optionsHash["otherValue"];
           },

   method: function( arg ) {
               return _someVar  + arg;  
           },
};

И используйте это так ...

var myClass = new MyClass( { varValue: -1, otherValue: 10 } );
var foo = myClass.method(6);
Ответ принят как подходящий

Все варс приватные:

SomeClass = function (id) {
    var THIS = this; // unambiguous reference
    THIS._id = id;

    var intFun = function () { // private
        return THIS._id;
    }

    this.extFun = function () { // public
        return intFun();
    }
}

Используйте THIS в частных методах, поскольку this не будет соответствовать тому, что вы могли ожидать.

Предпочитаю себя ЭТОМ.

AnthonyWJones 01.12.2008 16:40

От http://learn.jquery.com/code-organization/concepts/#the-module-pattern:

// The module pattern
var feature = (function() {

    // private variables and functions
    var privateThing = "secret";
    var publicThing = "not secret";

    var changePrivateThing = function() {
        privateThing = "super secret";
    };

    var sayPrivateThing = function() {
        console.info( privateThing );
        changePrivateThing();
    };

    // public API
    return {
        publicThing: publicThing,
        sayPrivateThing: sayPrivateThing
    };

})();

feature.publicThing; // "not secret"

// logs "secret" and changes the value of privateThing
feature.sayPrivateThing();

Таким образом, использование возврата объекта, который является псевдонимом его «методов», может быть другим способом сделать это.

Я читал из http://www.amazon.com/Programming-Oracle-Press-Poornachandra-Sarang-ebook/dp/B0079GI6CW, что всегда полезно использовать геттеры и сеттеры, а не обращаться к переменной напрямую извне объекта, чтобы исключить необходимость возврата переменных по ссылке.


Кстати, вы можете просто использовать this.variable для ссылки / объявления общедоступной переменной и var variable для объявления частной переменной.


Я знаю, что это запоздалый ответ, но надеюсь, что он поможет любому, кто прочтет его в будущем.

Другие вопросы по теме