2017-02-19 34 views
0

Уважаемые сообщества и Javascript волшебники,Modulepattern и экземпляры объектов - неожиданное изменение propertyvalues ​​

я столкнулся с поведением я не могу иметь смысл.

Мое намерение состоит в создании модуля, который имитирует частные переменные и управляет созданием объектов.

Надеюсь, следующий пример иллюстрирует то, что я хочу и что моя проблема.

const ex = (() => { 
 

 
    // Creating the constructor for points 
 
    function Point() { 
 
    let x; 
 
    let y; 
 
    
 
    // I think using prototype is a good idea, because it can be expected that a lot of points are created. So I do not waste memory with a lot of function duplications. 
 
    Point.prototype.setX = xValue => { 
 
    x = xValue; 
 
    } 
 
    
 
    Point.prototype.setY = yValue => { 
 
    y = yValue; 
 
    } 
 
    
 
    Point.prototype.getY =() => { 
 
    return y; 
 
    } 
 
    } 
 
    
 
    // Returning an interface to create points 
 
    // but hide their properties. 
 
    return {createPoint: (x,y) => { 
 
    let point = new Point(); 
 
    point.setX(x); 
 
    point.setY(y); 
 
    return point; 
 
    }} 
 
})(); 
 

 

 

 
p1 = ex.createPoint(1,2); 
 
console.log(p1.getY()); // Result is '2' as expected 
 

 
p2 = ex.createPoint(3,4); 
 
console.log(p2.getY()); // Result is '4' as expected 
 

 
console.log(p1.getY()); // Result is '4'..Wait...'4' what? Why?!

Я думаю, что очевидный источник мое озеро понимание сферы ... Мои предположения были/есть, что если я создаю функцию в качестве прототипа-свойства: 1. функция предназначена для всех объектов созданного вида. 2. Функция прототипа работает с областью действия объекта, который его использует.

Из моих результатов я сомневаюсь, что номер 2 верен.

Так что я дал ему еще один выстрел и присвоены свойства и методы непосредственно на вновь созданный объект (я надеюсь, что я так и сделал ...)

const ex = (() => { 
 

 
    // Creating the constructor for points 
 
    function Point() { 
 
    this.x; 
 
    this.y; 
 
    
 
    // I think using prototype is a good idea, because it can be expected that a lot of points are created. So I do not waste memory with a lot of function duplications. 
 
    this.setX = xValue => { 
 
    x = xValue; 
 
    } 
 
    
 
    this.setY = yValue => { 
 
    y = yValue; 
 
    } 
 
    
 
    this.getY =() => { 
 
    return y; 
 
    } 
 
    } 
 
    
 
    // Returning an interface to create points 
 
    // but hide their properties. 
 
    return {createPoint: (x,y) => { 
 
    let point = new Point(); 
 
    point.setX(x); 
 
    point.setY(y); 
 
    return point; 
 
    }} 
 
})(); 
 

 

 

 
p1 = ex.createPoint(1,2); 
 
console.log(p1.getY()); // Result is '2' as expected 
 

 
p2 = ex.createPoint(3,4); 
 
console.log(p2.getY()); // Result is '4' as expected 
 

 
console.log(p1.getY()); // Result is '4'..Wait...'4' what? Why?!

Но результат не изменить, и я не могу понять смысл поведения. Перечитывая главы о замыканиях и прототипах в моей js-библии, я понятия не имею, где я могу искать или находить помощь, чем спрашивать вас.

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

Сердечные приветы

Джим

ответ

0

Есть некоторые проблемы на код:

  • , как вы используете функции со стрелками. В стрелочных функциях нет собственного «этого» объекта. Поэтому использование их для определения прототипа приведет к странным результатам.

  • Говоря об этом? Ах, да, вам нужно использовать «this» для хранения значения где-нибудь в экземпляре класса.

  • Похоже, что нет необходимости использовать ES2015 (ES6) в вашем случае. Почему бы не использовать ES2015's 'Class' для определения класса? (Это не дает вам реальных частных реквизитов, но синтаксис очень сильно улучшен)

  • Создание экземпляра класса в функции в другой функции или закрытии на самом деле не скрывает свойства этого класса. Поскольку вы возвращаете этот объект, значения могут быть доступны через него.

Строгое обеспечение обязательных частных свойств/методов объектов класса не является чем-то действительно необходимым.Рекомендуется дать им некоторый префикс (_ является общим), и всякий раз, когда вы нажимаете этот префикс на свой код, используйте этот var только в частном порядке.

const ex = (() => { 
 

 
    // Creating the constructor for points 
 
    function Point() { 
 
    }; 
 

 
    Point.prototype.setX = function(xValue) { 
 
    console.trace('hmm'); 
 
    this.x = xValue; 
 
    }; 
 

 
    Point.prototype.setY = function(yValue) { 
 
    this.y = yValue; 
 
    }; 
 

 
    Point.prototype.getY = function() { 
 
    return this.y; 
 
    }; 
 
    
 
    return { 
 
    createPoint: (x, y) => { 
 
     let point = new Point(); 
 
     point.setX(x); 
 
     point.setY(y); 
 
     return point; 
 
    } 
 
    } 
 
})(); 
 

 

 

 
const p1 = ex.createPoint(1, 2); 
 
console.log(p1.getY() + " (Result is '2' as expected)"); 
 

 
const p2 = ex.createPoint(3, 4); 
 
console.log(p2.getY() + " (Result is '4' as expected)"); 
 
console.log(p1.getY() + " (Result is '2' as expected)");

А вот пример, чтобы иметь класс с некоторыми реальными частными членами:

const Point = function(valueX, valueY) { 
 
    let x = valueX; 
 
    let y = valueY; 
 
    this.getY =() => { 
 
    return y; 
 
    }; 
 
}; 
 

 
const p1 = new Point(1, 2); 
 
console.log(p1.getY() + " (Result is '2' as expected)"); 
 

 
const p2 = new Point(3, 4); 
 
console.log(p2.getY() + " (Result is '4' as expected)"); 
 

 
console.log(p1.getY() + " (Result is '2' as expected)");

+0

Дорогой Бюлент ВУРАЛ, спасибо большое за ваши ответ. Ваш намек на функции стрелок - отличная помощь и новая ценная информация (= Ваше предлагаемое решение, без сомнения, является улучшением, но одна функция (которая ранее работала для одного объекта) потерялась. Теперь x и y уже не являются невидимыми из снаружи. К ним можно обратиться напрямую с помощью p1.x (я сожалею о том, что не сделал это явным в кодах). По этой причине я попытался в первой попытке «позволить x», чтобы они были скрыты в области. – Jim

+0

Я обновил свой ответ с дополнительной информацией. Есть способы сделать действительно частных членов, но это действительно не стоит. Я все-таки привел пример. –

+0

Большое вам спасибо! Ваш ответ был очень полезным и является хорошим моментом от который я могу продолжить дальше (= – Jim