Доступ к переменным в объектах в JavaScript без "этого" - PullRequest
0 голосов
/ 23 ноября 2010
  <HTML>
    <HEAD>
      <SCRIPT LANGUAGE="JavaScript">
        function Peon(number) {
            this.number = number;

            this.inc = function() {
                number=number+1;
            };

            return true;
        }
        var p=new Peon(10);

        function returnNumber() {
            p.inc();
            alert(p.number);
        }
      </SCRIPT>
    </HEAD>
    <BODY>

      <INPUT id="b00" TYPE="button" Value="Click" onClick="returnNumber()">

    </BODY>
  </HTML>

Этот код не работает должным образом.Есть ли способ заставить его работать без необходимости писать

this.number=this.number+1;

Здесь это тривиальный выбор, но в больших кодах, не имеющих этого *, это сделало бы его намного более читабельным.Возможно ли это?

Ответы [ 5 ]

2 голосов
/ 23 ноября 2010

Вы можете сделать number "приватным", но тогда вам понадобится getter :

    function Peon(number) {
        var number = number;

        // increment
        this.inc = function() {
            number++;
        };

        // a simple getter
        this.getNumber = function() {
            return number;
        }
    }
    var p = new Peon(10);
    p.inc();
    alert(p.getNumber());

Вам следует прочитать Дугласа Крокфордса «Хорошие детали» для получения дополнительной информации о том, как использовать этот шаблон, есть (ограниченный) предварительный просмотр в Google Книги .

Также вам не нужно возвращать что-то из конструктора, ваш return true является лишним.

1 голос
/ 23 ноября 2010

Нет, вы должны использовать this для ссылки на свойства объекта this.Обратите внимание, что this в JavaScript сильно отличается от this в некоторых других языках, таких как C или Java.Больше здесь и здесь .

Ваш код выполняет доступ к аргументу number, который был передан в функцию конструктора Peon, а не к this.number свойство, которое вы создали в конструкторе.Вот почему он не работает должным образом, но и не дает сбоя.

Нет смысла определять вашу inc операцию в функции конструктора Peon, BTWи некоторые веские причины этого не делать (каждый отдельный объект, созданный с помощью Peon, получит свою собственную копию этой функции).Таким образом, вместо этого вы можете определить это так:

function Peon(number) {
    this.number = number;

    // Don't return values out of constructor functions, it's
    // an advanced thing to do. In your case, you were returning
    // `true` which was being completely ignored by the JavaScript
    // interpreter. If you had returned an object, the `this` object
    // created for the `new Peon()` call would have been thrown away
    // and the object you returned used instead.
}

Peon.prototype.inc = function() {
    ++this.number;
};

var p=new Peon(10);

function returnNumber() {
    p.inc();
    alert(p.number); // alerts 11
}
0 голосов
/ 17 июня 2017

Да, вам не нужно использовать «это» в JavaScript.Вы можете получить доступ к переменным через замыкание вместо 'this'

function createPeon(number) {

  function inc() {
      number=number+1;
  };
  function getNumber() {
      return number;
  }

  return { inc, getNumber };
}
var p=createPeon(10);
p.inc();
alert(p.getNumber());
0 голосов
/ 23 ноября 2010

Единственный читаемый способ, которым я могу видеть это, будет:

this.inc = function() {
   this.number++;
};

В противном случае, в своем постулате «больших кодов», вы можете сделать что-то вроде этого:

this.inc = function() {
   var number = this.number; // obviously simple here.  Imagine more complexity
   number++;
};
0 голосов
/ 23 ноября 2010

Не совсем, но это немного более кратко

this.number++

На самом деле, как примечание, вам лучше объявить .inc вне конструктора Peon.Вы можете сделать это с прототипом.Таким образом, функция inc не восстанавливается каждый раз, когда вы создаете объект типа Peon.

Peon.prototype.inc = function(){
    this.number++;
}

Или вместо использования p.inc() вы можете сделать p.number++.Это единственный способ избежать ключевого слова this.

...