2016-04-05 4 views
0

У меня довольно простой объект JavaScript с некоторыми объектными методами, и я пытаюсь получить доступ/изменить информацию в массиве (хранящемся в глобальной переменной) изнутри один из этих методов. Вот мой код:Доступ к глобальной переменной изнутри метода объекта в Javascript

var list= []; 
function person(firstname, age){ 
    this.firstname = firstname; 
    this.age = age; 

this.addPerson = function(){ 
list.push({firstname, age }); 
} 

this.addPerson(); 

this.changeName = function (name, newname) { 
    var i = 0 
    for (i; i < list.length; i++);{ 
     if (list[i].firstname === name){ 
      list[i].firstname = newname; 
     } 
     } 
    } 
} 

var person = new Bunny('Jim', 20); 
var person = new Bunny('Sally',40); 
person.changeName('Jim', 'John'); 

Когда новый человек создан, они автоматически добавляются в мой список. Когда я вызываю changeName, я хочу ввести имя, которое я хочу изменить, и новое имя, которое оно должно быть. Тем не менее, я получаю сообщение об ошибке «Не могу прочитать свойство« firstname »undefined», что заставляет меня думать, что changeName не может получить доступ к моему списку.

+0

В чем смысл функции 'addPerson'? Почему бы вам не «толкнуть» человека непосредственно внутри конструктора? – Lewis

+0

Я написал addPerson, потому что я хотел подтолкнуть человека к списку, как только создаю новый. Я не мог заставить его работать без вызова addPerson(); внутри конструктора .... Я уверен, что есть лучший способ сделать это. Что бы вы сделали? – bjorkland

+0

Просто посмотрите мой ответ для лучшего подхода. – Lewis

ответ

1

Вы различные проблемы,

  1. Проблема с использованием ; после того, для скобкой передачи контура в. Это фактически заставляет тело цикла запускаться один раз с последним добавочным значением вашего цикла for.

    for (i; i < list.length; i++);{ 
    //---------------------------^ Remove it 
    

    Вот почему вы получаете не может прочитать свойство не определено ошибки

    for(var i=0;i<list.length; i++); //this will run repeatedly as per for loop semantics 
    
    { } //and this body will be executed only once with the final updated value of i 
    
  2. Вы ошибочно инициируя объект с помощью Bunny. Это должно be person в нашем случае.

    var person1 = new person('Sally',40); 
    person1.changeName('Jim', 'John'); 
    
+1

Good catch :) ... –

+0

@FelixKling Извините, я смутился. Нашел настоящую причину и обновил ее. –

+0

Ах! Это сработало! Кроме того, «Банни» был глупым артефактом, оставленным чем-то другим ... должен был поймать это ... facepalm. Спасибо!! – bjorkland

0

попробовать это:

var list = []; 

var Bunny = function (firstname, age){ 
    //this.firstname = firstname; 
    //this.age = age; 

this.addPerson = function(){ 
list.push({'firstname':firstname,'age': age }); 
} 

this.addPerson(); 

this.changeName = function (name, newname) { 
    var i = 0 


    for (i; i < list.length; i++){ 

     if (list[i].firstname === name){ 
      list[i].firstname = newname; 
     } 
     } 
    } 
} 

var person = new Bunny('Jim', 20); 
var person = new Bunny('Sally',40); 
person.changeName('Jim', 'John'); 
console.log(list[0]); 

у вас ';' в цикле, это была проблема.

0

В дополнение к @ rajaprabhu Замечаний:

У вас есть метод конструктор, человек(). Вы должны переименовать его в Person(), чтобы соответствовать общепринятым стандартам кодирования для метода конструктора.

Вы создаете 2 экземпляра Person (неправильно в вашем коде с помощью Bunny). В контексте объекта Person вы имеете доступ к своей собственной области видимости, то есть можете изменять свои собственные свойства напрямую. Когда вы перебираете массив списка в методе changeName, вы достигаете внешнего вида области. Замените петлю следующей 1 строкой кода:

this.firstName = newName; 

Кроме того, вы не нажимаете ни одного человека в свой массив списков. Вместо

var person = new Bunny('Jim', 20); 

ли это:

list.push(new Person('Jim', 20); 

Это добавит новый объект Person в массив списка.

Полное редактирование:

var list = []; 

function Person(firstname, age) { 
    this.firstname = firstname; 
    this.age = age; 

    this.addPerson = function() { 
    list.push({ 
     firstname, 
     age 
    }); 
    } 

    this.addPerson(); 

    this.changeName = function(name, newname) { 
    var i = 0 
    if (this.name == newname) { 
     this.name = newName; 
    } 
    } 
} 

// add the Person objects directly to the list array 
list.push(new Person('Jim', 20)); 
list.push(new Person('Sally', 40)); 

// now you can select an object in the list to change its name 
list[1].changeName('Jim', 'John'); 
+0

Спасибо! Это действительно полезно! – bjorkland

1

Кроме того, некоторые синтаксические ошибки, код по-прежнему плохо проработан. Вот лучший.

function People(){ 
    this.list = []; 
} 
People.prototype.add = function(person){ 
    this.list.push(person); 
}; 
People.prototype.changeName = function(name,newName){ 
    for(var i=0;i<this.list.length;i++){ 
     var person = this.list[i]; 
     if(person.firstname === name){ 
      person.firstname = newName; 
     } 
    } 
}; 
function Person(firstname,age){ 
    this.firstname = firstname; 
    this.age = age; 
} 

//Usage 
var jim = new Person('Jim', 20); 
var sally = new Person('Sally',40); 

var people = new People(); 
people.add(jim); 
people.add(sally); 
people.changeName('Jim', 'John'); 
+0

Ах, это действительно полезно. Я немного боролся с прототипами. Итак, People.prototype.add/People.prototype.changeName просто определяет методы «add» и «changeName» для человека и создает встроенные методы для объекта person? Надеюсь, это было ясно ... Я все еще немного новичок в этом. – bjorkland

+0

@ Lisa Нет, это не работает. Эти 2 метода не будут назначены каждому человеку. Я добавляю 'add' и' changeName' в класс 'People' просто потому, что имеет смысл. – Lewis

+0

ОК, спасибо ... но тогда вам все равно придется добавлять add отдельно, вместо автоматического добавления вновь созданного Person для списка, что я и хотел сделать изначально. Думаю, это просто лучшая форма? – bjorkland

Смежные вопросы