2016-04-28 4 views
2

Я пытаюсь сделать объект закрытым, но не уверен, как это сделать. Поскольку вы можете видеть, что переменная name является частной, я не могу ее редактировать, но когда дело доходит до объекта, который я возвращаю, я могу редактировать. Я не хочу, чтобы это было возможно. Я совершенно новый для объектно-ориентированных и частных методов в javascript, так что кто-то может сказать мне, что здесь правильно и что не так. :) Как я могу это решить? Спасибо!Почему мой объект не является приватным, когда моя переменная?

var User = function() { 

    var name = 'bob'; 
    this.getName = function() { 
    return name; 
    } 

    var otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return otherInfo; 
    } 

} 

var person = new User(); 

var name = person.getName(); 
name = 'jenny'; 
console.log(person.getName()); // bob 

var other = person.getOther(); 
other.age = 'wtf?'; 
console.log(person.getOther()); // { age: 'wtf?', human: true } 
+0

Если вы не хотите изменять возвращаемое значение 'person.getOther()' для изменения значения 'otherInfo', тогда вам нужно вернуть его копию. – forgivenson

+0

Как это сделать? –

+0

http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object – Jonathan

ответ

0

Это происходит, потому что в объекте JS проходит по ссылке - там не справляются с исходным объектом.

Просто попробуйте объект копирования:

var User = function() { 

    var name = 'bob'; 
    this.getName = function() { 
    return name; 
    } 

    var otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return Object.assign({}, otherInfo); 
    } 

} 

var person = new User(); 

var name = person.getName(); 
name = 'jenny'; 
console.log(person.getName()); // bob 

var other = person.getOther(); 
other.age = 'wtf?'; 
console.log(person.getOther()); // { age: 20, human: true } 
+0

Это действительно не копирует объект. Вместо этого он использует 'this.otherInfo' в качестве прототипа для нового объекта. – forgivenson

+0

ОК. это был быстрый ответ. Я изменил его на Object.assign –

+0

Ваш код все еще не работает. Проверьте это. – forgivenson

1

Примитивные значения, такие как струны передаются по значению. Это означает, что когда вы назначаете String вашей переменной, вы устанавливаете фактическое значение String для переменной.

Объекты прошли по ссылке. Это означает, что когда вы назначаете объект своей переменной, вы просто делаете ссылку объекту, а не его фактическое значение. Если у вас был один объект и присвоен его 6 различным переменным, каждая переменная имела бы ссылку на тот же базовый объект.

В вашем примере, ваш метод getOther возвращается в ссылку на otherInfo объекта. Поэтому, когда вы устанавливаете свойство age в «wtf», вы устанавливаете его на объекте, на который ссылается ваша переменная.

0

Вы также объявляете var name дважды.

Когда вы var person = new User(); a var name объявлен в рамках функции пользователя.

Когда вы объявляете переменную с тем же именем за пределами функции пользователя.

Итак, когда вы name = 'Jenny'; интерпретатор связывает эту строку с переменной name вне сферы действия Пользователь.

В общем, это плохая идея использовать такие переменные с общими именами (имя, название, идентификатор, ...) в качестве глобальных переменных. Я бы назвал атрибуты объекта this. и определл setters, а также getters. Вы можете также игнорировать setters и ссылаться на атрибуты пользователя с person., как это:

function User() { 
    this.name = 'bob'; 
    this.getName = function() { 
    return this.name; 
    } 

    this.otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return this.otherInfo; 
    } 

} 

var person = new User(); 

console.log(person.getName()); // bob 
person.name = 'jenny'; 
console.log(person.getName()); // jenny 

console.log(person.getOther(); // { age: 20, human: true } 
person.otherInfo.age = 'wtf?'; 
console.log(person.getOther()); // { age: 'wtf?', human: true } 
0

Вы не «частные» вещи в области объекта в JavaScript. Единственный способ скрыть вещи извне - это область функций, как и с name (локальная переменная в функции User).

Чтобы каждый раз возвращать объект с тем же контентом, вы можете сделать объект внутри функции.Как это, например:

this.getOther = function() { 
    var otherInfo = { 
     age: 20, 
     human: true, 
    } 
    return otherInfo; 
} 

Или просто:

this.getOther = function() { 
    return { 
     age: 20, 
     human: true, 
    }; 
} 

В обоих случаях вы будете создавать новый объект с каждым вызовом.