@podkudahka
крутой

Зачем нужна инкапсуляция js?

Источники диктуют инкапсуляцию, как сокрытие состояния объекта от прямого доступа извне. Так вот в коде без инкапсуляции мы можем обратиться к какому-то значению вот так tom.name=34;
function User(pName, pAge) {
    this.name = pName;
    this.age = pAge;
    this.displayInfo = function(){
        document.write("Имя: " + this.name + "; возраст: " + this.age);
    };
};
var tom = new User("Том", 26);
tom.name=34;
console.log(tom.name);

А с инкапсуляцией мы все равно можем обратиться к значению tom.setAge(32);
function User (name) {
    this.name = name;
    var _age = 1;
    this.displayInfo = function(){
        console.log("Имя: " + this.name + "; возраст: " + _age);
    };
    this.getAge = function() {
        return _age;
    }
    this.setAge = function(age) {
        if(typeof age === "number" && age >0 && age<110){
            _age = age;
        } else {
            console.log("Недопустимое значение");
        }
    }
}
 
var tom = new User("Том");
console.log(tom._age); // undefined - _age - локальная переменная
console.log(tom.getAge()); // 1
tom.setAge(32);
console.log(tom.getAge()); // 32
tom.setAge("54"); // Недопустимое значение
tom.setAge(123); // Недопустимое значение

Я вижу смысл только в возможности прописать условие
this.setAge = function(age) {
        if(typeof age === "number" && age >0 && age<110){
            _age = age;
        } else {
            console.log("Недопустимое значение");
        }
    }

Объясните пожалуйста
  • Вопрос задан
  • 2063 просмотра
Решения вопроса 2
Athanor
@Athanor
Лайк + Решение: не жмись, нажми
Инкапсуляция нужна для защиты какой-то внутренней логики от случайного/намеренного изменения, которое может вызвать внутренние проблемы. Я думаю, вас просто сам пример смутил. Представьте себе, что внутри конструктора User был бы еще метод, в котором идет расчет на то, что age соответствует условию. Например, метод, который высчитывает год рождения пользователя. Соответственно, если кто-то не аккуратно записал в age что-то кроме number, этот метод вернет нам какой-то неожиданный результат(например, NaN).
Ответ написан
В данном примере вы, как мне кажется, путаете инкапсуляцию и сокрытие данных

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

Javascript использует прототипное наследование, и в его реализации, традиционно, с сокрытием данных есть некоторые проблемы. Даже в "строго-типизированных" надстройках (например, в typescript), где в систему классов добавлены ключевые слова private и protected, защищенные свойства объектов все равно будут доступны извне на рантайме:
// TypeScript
class Foo {
    private bar = "lol"; // приватное поле класса
    baz = 42;
}

const foo = new Foo();
console.log((foo as any).bar) // "lol"


Если сокрытие данных на рантайме все-таки необходимо, его можно добиться с помощью замыканий и символов:
const factory = () => {
    // используем замыкание, чтобы ограничить область видимости
    const privateProp = Symbol();

    function Foo() {
        // используем символ как идентификатор поля
        this[privateProp] = "lol";
        this.bar = 42;
    }

    return new Foo()
}

const foo = factory();

// foo[privateProp] использовать невозможно вне замыкания
console.log(foo.bar) // 42
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@RokeAlvo
Можно убрать сеттер и из вне нельзя будет изменить значение
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы