2013-06-10 10 views
5

Jestem całkiem nowy w pisaniu OO JS, ale to mnie zaskoczyło. Tak więc ustawiłem nowy obiekt Call, a następnie zdefiniuję, co uważam za puste tablice. Kiedy zadzwonić AddFieldQueryToArray() otrzymujęJavaScript Array zdefiniowany w konstruktorze jest niezdefiniowany w prototypie

Uncaught TypeError: Cannot call method 'push' of undefined 

Na this.fieldArray.push(field)

ja naprawdę nie wiem, dlaczego. Próbowałem też this.fieldArray = fieldArray; w konstruktorze.

function Call() 
    {  
     var fieldArray = new Array(); 
     var queryArray = new Array(); 
    } 

    Call.prototype.AddFieldQuerysToArray = function(field,query) 
    { 
     if(field !== 'undefined') 
     {    
      this.fieldArray.push(field); 
     } 

     this.queryArray.push(query); 

    } 
+0

Tylko jeden komentarz, w JavaScript pls zawsze umieścić otwarcie szelki na tej samej linii pisma: to znaczy 'wywołania funkcji() {' 'if (pole == 'niezdefiniowany'!) {'. Ma to pewne skutki uboczne w niektórych przypadkach, takie jak "return" i prawidłowy kod JS powinien zachować ten formularz. –

Odpowiedz

10

Należy odwołać właściwości instancji z this. wewnątrz konstruktora:

function Call() 
{  
    this.fieldArray = []; 
    this.queryArray = []; 
} 

new Array() ma skrót [] którego użyłem powyżej.

Jeśli używasz var fieldArray = []; by utworzyć lokalną zmienną, która jest zniszczona raz instancja została utworzona, chyba że korzysta z tego rodzaju konstrukcji:

function Call() 
{ 
    var fieldArray = []; 

    this.AddFieldQuerysToArray = function(field, query) { 
     // ... 
     fieldArray.push(field); 
    } 
} 

Stwarza to zamknięcie dla każdej instancji, w którym fieldArray jest "utrzymywane przy życiu" przez całe życie instancji.

+0

"zniszczony po utworzeniu instancji" - chyba że jest odwołany z zamknięcia –

+0

@JanDvorak Podany kod nie dał tej sugestii, ale dodałem przykład takiego warunku. –

+0

Zawsze uważam, że dodawanie metod do 'this' wewnątrz konstruktora wygląda brzydko, z wyjątkiem czegoś takiego jak' function Constr() {var env = {}; this.getEnv = function (x) {if (x) return env [x]; return env;};} ' –

1
function Call() 
{ 
    this.fieldArray = []; 
    this.queryArray = [];  
} 


Call.prototype.AddFieldQuerysToArray = function(field,query) 
{ 
    if(field !== 'undefined') 
    { 
     alert('field==='+this.fieldArray); 
     this.fieldArray.push(field); 
    } 
    alert('field==='+this.fieldArray); 
    this.queryArray.push(query); 
alert(this.queryArray);// to check 
alert(this.fieldArray);// to check 
}; 

field = 'exampleField'; 
query = 'exampleField'; 

var cally = new Call(); 
cally.AddFieldQuerysToArray(field,query); //change 

Jedynym problemem jest to, że pan dzwoni Call.prototype.AddFieldQuerysToArray() metodę i tutaj faktycznie tę wartość, o której mowa kontekście wykonanie Call.prototype obiektu, który nie miał tablic fieldArray i queryArray.

Wywołanie metody prototypu AddFieldQuerysToArray() kodując cally.AddFieldQuerysToArray(field,query); odnosi się do kontekstu wykonania instancji cally który ma obie tablice zadeklarowane w nim przez jego konstruktora.

+0

alert (Object.getOwnPropertyNames (Call.prototype)); Ten prosty kod pomoże ci zrozumieć, że tablice fieldArray i queryArray nie są obecne w kontekście wykonania Call.prototype –

0

To bardzo stary post. & odpowiedź została udzielona przez Jacka. this musi być użyty, aby uniknąć błędu.

Ale istnieje blok anty wzór używany w bloku kodu. new Array() należy unikać. Lepszym podejściem jest użycie Array Literal Notation. Postępuj zgodnie z tą odpowiedzią StackOverflow What’s the difference between "Array()" and "[]" while declaring a JavaScript array?, aby uzyskać szczegółowe informacje.

Ale istotą jest to, że jeśli konstruktor macierzy poda tylko jeden parametr, to zostanie to zinterpretowane jako długość tablicy, ale NIE będzie to PIERWSZY element w tablicy.

console.log(new Array(10).length);//10 
console.log(new Array(10)[0] === undefined);//true 
Powiązane problemy