Неопределенная ошибка при использовании объектов JavaScript - PullRequest
1 голос
/ 01 июля 2011

Я новичок в объектах javascript, и у меня возникла проблема. Я пытаюсь создать галерею изображений, но получаю сообщение об ошибке, что this.current, this.size & this.initial не определены, и поэтому скрипт не может работать. Пожалуйста, помогите мне решить эту ошибку. Ниже приводится полный сценарий.

function gallery()
{
    this.image = new Array(10);
    this.initial = 1;   
    this.current = 0;
    this.size = 10;
    this.frame_height = 400;
    this.frame_width = 600;
    this.initialize=function()
    {
        if(document.images)
        {
            var count = 1;
            for(count=1;count<=this.size;count++)
            {
               this.image[count] = new Image();
               this.image[count].src = 'images/'+count+'.jpg';                 
            }
        }

    divImg.id = "divImg";   
    divImg.setAttribute("Width",this.frame_width);
    divImg.setAttribute("align","center");   
    divImg.setAttribute("margin","0px auto"); 


    divBtn.id = "divBtn";    
    divBtn.setAttribute("align","center");  
    divBtn.setAttribute("backgroung-color","Black"); 
    divBtn.setAttribute("color","White"); 
    divBtn.style.margin = "0px auto";   
    divBtn.className ="btn";

    pictureFrame.src = this.image[this.initial].src;
    pictureFrame.setAttribute('Width',this.frame_width);
    pictureFrame.setAttribute('Height',this.frame_height);
    pictureFrame.name = 'img';

    btnNext.innerHTML='NEXT';
    btnPrevious.innerHTML='PREVIOUS';
    btnLast.innerHTML='LAST';
    btnFirst.innerHTML='FIRST';

    btnFirst.onclick=this.first;
    btnLast.onclick=this.last;
    btnPrevious.onclick=this.previous;
    btnNext.onclick=this.next;  

    myForm.appendChild(pictureFrame);
    divImg.appendChild(myForm);

    divBtn.appendChild(btnFirst);
    divBtn.appendChild(btnPrevious);
    divBtn.appendChild(btnNext);
    divBtn.appendChild(btnLast);

    pageBody.appendChild(divImg);
    pageBody.appendChild(divBtn);
    headerTag.appendChild(pageBody);
}

this.next=function()
{
    alert(this.size);
    alert(this.current);
    if (this.current < this.size) 
    {
        this.current +=1;
        pictureFrame.src = this.image[this.current].src;
    }
    else
    {
        alert("This is the last image");
    }
}   
this.previous=function()
{
    alert(this.current);
    alert(this.initial);
    if (this.current > this.initial) 
    {
        this.current = this.current-1;
        pictureFrame.src = this.image[this.current].src;
    }
    else 
    {
        alert("This is the first image");
    }

}
this.first=function()
{
    this.current=this.initial;
    pictureFrame.src = this.image[this.current].src;
}
this.last=function()
{
    alert(this.size);
    this.current=this.size;
    pictureFrame.src = this.image[this.current].src;
}

};

var divImg= document.createElement('div');
var divBtn = document.createElement('div');
var btnFirst= document.createElement('button');
var btnNext= document.createElement('button');
var btnPrevious= document.createElement('button');
var btnLast= document.createElement('button');
var divTop = document.createElement('div');
var headerTag = document.getElementsByTagName('html')[0];
var pageBody = document.createElement('body');
var myForm=document.createElement("form");
var pictureFrame = document.createElement('img');


var pics=new gallery();
window.onload=pics.initialize();

Ответы [ 2 ]

1 голос
/ 01 июля 2011

То, что сказал jAndy, правильно, когда объект window вызывает pics.initialise, this относится к window (this относится к вызывающей функции, если функция не является анонимной).

Однако есть более простое решение, которое вы можете предпочесть:

Вместо

var pics = new gallery();
window.onload = pics.initialize;

Вы можете сделать:

var pics = new gallery();
window.onload = function() {
    pics.initialize();
};

Поскольку он заключен в анонимную функцию, this будет ссылаться на экземпляр gallery вместо window.

Предложения Энди, безусловно, более надежны, но могут быть немного сложны для тех, кто все еще борется с Javascript.

1 голос
/ 01 июля 2011

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

Каждая функция имеет свой собственный контекст выполнения , и каждый контекст в ECMA- / Javascript имеет свою собственную this переменную контекста. Чтобы избежать этого, наиболее распространенным способом является сохранение ссылки на «внешнюю» переменную контекста this в локальной переменной:

function gallery()
{
    this.image = new Array(10);
    this.initial = 1;   
    this.current = 0;
    this.size = 10;
    this.frame_height = 400;
    this.frame_width = 600;

    var self = this;

    //...

    this.initialize=function()
    {
        if(document.images)
        {
            var count = 1;
            for(count=1;count<=self.size;count++)
            {
               self.image[count] = new Image();
               self.image[count].src = 'images/'+count+'.jpg';                 
            }
        }
    // ...

Это будет работать как в любой среде Javascript. Между тем, в ECMA есть «лучшие» (другие) способы избежать этой проблемы. Например, ECMAscript Edition 5 представляет метод .bind(), который позволяет вам «привязать» ссылку из this context variable к объекту по вашему выбору. Многие фреймворки javascript предлагают довольно похожий способ привязки this к объекту, даже сам Javascript позволяет вам сделать это с небольшими усилиями.

...