2016-06-20 2 views
-1

Учитывая следующее заявлениеОшибка создания и доступа массив объектов

function Func1(a, b) { 
    this.a = a; 
    this.b = b; 
}; 

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

var Func2 = function() { 
    var items = []; 

    this.addItem = function (a, b) { 
     items.push(new Func1(a, b)); 
    } 

    var function2 = new Func2(); 
    function2.addItem(2, 'test'); 
    window.alert(function2.items[0].b); // this gives error "Unable to get property '0' of undefined or null reference. I'd like to be able to show 'test' here. 

Я также изменил код, чтобы использовать объявить 'this.items = []' вместо 'вар элементов = []', это дает мне другую ошибку, следующим образом:

var Func3 = function() { 
    this.items = []; 

    this.addItem = function (a, b) { 
     items.push(new Func1(a, b)); // this gives error 'items' is undefined 
    } 
}; 

var function3 = new Func3(); 
function3.addItem(3, 'test'); 
window.alert(function3.items[0].b); // I want to show 'test' here 

я изменил функцию AddItem снова, все еще получаю ошибку

var Func4 = function() { 
    this.items = []; 

    this.addItem = function (a, b) { 
     items[items.length] = new Func1(a, b); // this gives error 'items' is undefined, too 
    } 
}; 

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

ответ

2

При использовании this.items = [];, вы должны использовать this.items вместо items. Не существует глобальной или локальной переменной , определяемой как items в опубликованном коде, и именно поэтому вы получаете такую ​​ошибку.

this.items.push('...'); 

При использовании var items = []; в конструкторе, переменная локальной функции конструкторы, поэтому внешняя сфера не может получить доступ к переменной. Вы должны либо определить метод, который возвращает значение, либо определить items как свойство экземпляра (объекта).

Эти два варианта:

var Option1 = function() { 
    var items = []; 

    this.addItem = function (a, b) { 
     items.push(new Func1(a, b)); 
    } 

    this.getItems = function() { 
     return items; 
    } 
} 

И:

var Option2 = function() { 
    this.items = []; 

    this.addItem = function (a, b) { 
     this.items.push(new Func1(a, b)); 
    } 
} 
+1

Объяснение вместо просто передачи готового кода. +1 – Cerbrus

+0

@Cerbrus Спасибо! Здесь все еще есть много возможностей для улучшения :) – undefined

+0

Вопрос: в варианте 1, почему нам не нужны «this.items»? Они будут вызывать путаницу с глобальными предметами (если они есть)? –

1

Это выглядит как вопрос области, следует использовать "это" при объявлении элементов и при вызове его. Проверьте фрагмент кода:

function Func1(a, b) { 
 
    this.a = a; 
 
    this.b = b; 
 
}; 
 

 
var Func2 = function() { 
 
    this.items = []; 
 

 
    this.addItem = function (a, b) { 
 
     this.items.push(new Func1(a, b)); 
 
    } 
 
} 
 

 
var function2 = new Func2(); 
 
function2.addItem(2, 'test'); 
 
window.alert(function2.items[0].b);

0

если вы хотите пунктов, которые будут скрыты за пределами функции, то вам нужно добавить функцию геттер, чтобы получить доступ к элементам переменной:

function Func1(a, b) { 
    this.a = a; 
    this.b = b; 
}; 

var Func2 = function() { 
    var items = []; 

    this.addItem = function (a, b) { 
     items.push(new Func1(a, b)); 
    } 

    this.getItem = function(index) { 
     return items[index]; 
    }; 
} 

var function2 = new Func2(); 
function2.addItem(2, 'test'); 
console.log(function2.getItem(0).b); 
0

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

var Func2 = function() { 
    var self = this; 

    self.items = [] 

    self.addItem = function (a, b) { 
     self.items.push(new Func1(a, b)); 
    } 
} 

Таким образом, правильный контекст кэрри в AddItem(), и он должен работать независимо от того, где она вызывается из.

0

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

  • var items, только относится к функции конструктора поэтому случаи не получит копию. Поэтому используйте функцию this.items в функции конструктора (Func2), поэтому, когда вы создаете экземпляр Func2, экземпляр имеет эту переменную экземпляра.

  • Я вижу, что вы иногда используете items, а иногда и this.items, всегда используете this.items. Таким образом, в Func3 и Func4, изменить код, чтобы быть похожим так:

    this.addItem = function (a, b) { 
        this.items[items.length] = new Func1(a, b); 
    } 
    

Я надеюсь, что помогает.

+0

всегда использовать "this.items"? Да, даже в скобках. – undefined

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