分配给匿名函数的变量未定义

发布于 2024-12-17 18:49:58 字数 1481 浏览 3 评论 0原文

我使用分配给变量的匿名函数来最小化全局变量的使用。在此函数中,有嵌套函数:一个用于预加载图像和调整图像大小,另外两个用于导航的嵌套函数(下一个和上一个)。下面的代码会生成错误,指出分配给匿名函数的变量未定义: 无法读取未定义的属性“preload_and_resize” 如果您发现问题,请告诉我。非常感谢。

<html>
<head>
<script type="text/javascript">
var runThisCode=(function(){
 var myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 var imageObj = new Array();
 var index=0;
 var preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i<myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

    document.pic.style.height=(document.body.clientHeight)*0.95;
};
 var next_image=function(){
    index++;
    if(index<imageObj.length){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=0;
        document.pic.src=imageObj[index].src;
    }
 };
 var prev_image=function(){
    index--;
    if(index>=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };
})();
</script>
</head>
<body onload="runThisCode.preload_and_resize();">
<div align="center">
<img name="pic" id="pic" src="img/01.jpg"><br />
<a href="JavaScript:runThisCode.prev_image()">Prev</a><a href="JavaScript:runThisCode.next_image()">Next</a>
</div>
</body>
</html>

I am using anonymous function assigned to a variable to minimize use of global variables. Within this function there are nested functions: one to preload and resize images, and two other nested functions for navigation (next and previous). The code below generates error that the variable to which the anonymous function is assigned is not defined:
Cannot read property 'preload_and_resize' of undefined
If you spot the problem please let me know. Thank you very much.

<html>
<head>
<script type="text/javascript">
var runThisCode=(function(){
 var myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 var imageObj = new Array();
 var index=0;
 var preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i<myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

    document.pic.style.height=(document.body.clientHeight)*0.95;
};
 var next_image=function(){
    index++;
    if(index<imageObj.length){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=0;
        document.pic.src=imageObj[index].src;
    }
 };
 var prev_image=function(){
    index--;
    if(index>=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };
})();
</script>
</head>
<body onload="runThisCode.preload_and_resize();">
<div align="center">
<img name="pic" id="pic" src="img/01.jpg"><br />
<a href="JavaScript:runThisCode.prev_image()">Prev</a><a href="JavaScript:runThisCode.next_image()">Next</a>
</div>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

岁月苍老的讽刺 2024-12-24 18:49:58

您的匿名函数不会返回任何内容,因此当您运行它时,会返回 undefined 。这就是 runThisCode 未定义的原因。不管怎样,按照您编写的方式,preload_and_resize 将是本地,因此您无论如何都无法访问它。

相反,您希望此匿名函数构造一个对象,并返回那个。像这样的东西应该有效,或者至少让你接近:

var runThisCode=(function(){
 var result = {};
 result.myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 result.imageObj = new Array();
 result.index=0;
 result.preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i< result.myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

    document.pic.style.height=(document.body.clientHeight)*0.95;
};
 result.next_image=function(){
    index++;
    if(index<imageObj.length){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=0;
        document.pic.src=imageObj[index].src;
    }
 };
 result.prev_image=function(){
    index--;
    if(index>=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };

 return result;
})();

Your anonymous function doesn't return anything, so when you run it, undefined gets returned. That's why runThisCode is undefined. Regardless though, with the way you've written it, preload_and_resize will be local, so you wouldn't be able to access that anyway.

Instead, you want this anonymous function to construct an object, and reutrn that. Something like this should work, or at least get you close:

var runThisCode=(function(){
 var result = {};
 result.myImages=new Array("img/01.jpg","img/02.jpg","img/03.jpg");
 result.imageObj = new Array();
 result.index=0;
 result.preload_and_resize=function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i< result.myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

    document.pic.style.height=(document.body.clientHeight)*0.95;
};
 result.next_image=function(){
    index++;
    if(index<imageObj.length){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=0;
        document.pic.src=imageObj[index].src;
    }
 };
 result.prev_image=function(){
    index--;
    if(index>=0){
        document.pic.src=imageObj[index].src;
    }
    else{
        index=myImages.length-1;
        document.pic.src=imageObj[index].src;
    }
 };

 return result;
})();
赢得她心 2024-12-24 18:49:58

这应该解释你做错了什么:

var foobar = (function (){
   var priv1, priv2 = 'sum' , etc;
   return {
      pub_function: function() {},
      another: function() {
          console.log('cogito ergo ' + priv2 );
      }
   };

})();

foobar.another();

This should explain what you are doing wrong :

var foobar = (function (){
   var priv1, priv2 = 'sum' , etc;
   return {
      pub_function: function() {},
      another: function() {
          console.log('cogito ergo ' + priv2 );
      }
   };

})();

foobar.another();
人心善变 2024-12-24 18:49:58

您已将该函数分配给变量 next_image,该变量的作用域为自调用匿名函数。

您分配给 runThisCode 的值是该匿名函数的返回值,该值(因为没有 return 语句)是 undefined

要使代码正常工作,您需要将一个对象分配给 runThisCode 并使 next_image 成为它的成员。

将以下内容添加到匿名函数的末尾:

return {
    "next_image": next_image
}

You've assigned the function to the variable next_image which is scoped to the self-invoking anonymous function.

The value you assign to runThisCode is the return value of that anonymous function, which (since there is no return statement) is undefined.

To get the code to work you need to assign an object to runThisCode and make next_image a member of it.

Add the following to the end of the anonymous function:

return {
    "next_image": next_image
}
夏夜暖风 2024-12-24 18:49:58

删除匿名函数,并将您的函数公开。您将仅创建一个全局变量:对象 runThisCode

var runThisCode = function () {
    var myImages = new Array("img/01.jpg", "img/02.jpg", "img/03.jpg");
    var imageObj = new Array();
    var index = 0;
    this.preload_and_resize = function () {
        var i = 0;
        var imageArray = new Array();
        for (i = 0; i < myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src = myImages[i];
        }

        document.pic.style.height = (document.body.clientHeight) * 0.95;
    };
    this.next_image = function () {
        index++;
        if (index < imageObj.length) {
            document.pic.src = imageObj[index].src;
        } else {
            index = 0;
            document.pic.src = imageObj[index].src;
        }
    };
    this.prev_image = function () {
        index--;
        if (index >= 0) {
            document.pic.src = imageObj[index].src;
        } else {
            index = myImages.length - 1;
            document.pic.src = imageObj[index].src;
        }
    };
};

然后,稍后在您的代码中:

runThisCode.preload_and_resize();

应该可以工作。

Remove the anonymous function, and make your function public. You will only create one global variable: the object runThisCode.

var runThisCode = function () {
    var myImages = new Array("img/01.jpg", "img/02.jpg", "img/03.jpg");
    var imageObj = new Array();
    var index = 0;
    this.preload_and_resize = function () {
        var i = 0;
        var imageArray = new Array();
        for (i = 0; i < myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src = myImages[i];
        }

        document.pic.style.height = (document.body.clientHeight) * 0.95;
    };
    this.next_image = function () {
        index++;
        if (index < imageObj.length) {
            document.pic.src = imageObj[index].src;
        } else {
            index = 0;
            document.pic.src = imageObj[index].src;
        }
    };
    this.prev_image = function () {
        index--;
        if (index >= 0) {
            document.pic.src = imageObj[index].src;
        } else {
            index = myImages.length - 1;
            document.pic.src = imageObj[index].src;
        }
    };
};

And then, later in your code:

runThisCode.preload_and_resize();

should work.

乙白 2024-12-24 18:49:58

从您在 body onload 属性中获得的调用来看,它看起来像是您试图使用 IIFE 实现的目标(立即调用函数表达式) 返回一个具有方法preload_and_resize 的对象。

正如其他人指出的那样,您不会从 IIFE 返回任何内容,因此实际上发生的只是您将其内部的所有内容都关闭在自己的命名空间中,而不是“导出”任何内容。

如果你想从你的 IIFE 中“导出”这些函数,你可能会添加最后一点,看起来像这样:

return { 
    'preload_and_resize': preload_and_resize, 
    'next_image': next_image,
    'prev_image': prev_image
}

它本质上创建了一个新的 JavaScript 对象文字,然后将其属性分配给来自本地范围。

一些开发人员会发现这是多余的,而不是完成这种显式导出,可能只是在声明对象文字时定义函数,例如:

return { 
    preload_and_resize: function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i<myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

        document.pic.style.height=(document.body.clientHeight)*0.95;
    },
    next_image: function() {
        index++;
        if(index<imageObj.length){
            document.pic.src=imageObj[index].src;
        }
        else {
            index=0;
            document.pic.src=imageObj[index].src;
        }
    },
    prev_image: function() {
        index--;
        if(index>=0){
            document.pic.src=imageObj[index].src;
        }
        else {
            index=myImages.length-1;
            document.pic.src=imageObj[index].src;
        }
    }
}

From the invocation you've got in body onload property, it looks like what you're trying to achieve with the IIFE (immediately invoked function expression) is return an object that has a the method preload_and_resize.

As others have pointed out, you're not returning anything from the IIFE, so really all that's happening is you're closing up everything inside it in its own namespace, but not "exporting" anything.

If you want to "export" those functions, from your IIFE, you'd probably add a final bit to it that looked something like this:

return { 
    'preload_and_resize': preload_and_resize, 
    'next_image': next_image,
    'prev_image': prev_image
}

which essentially creates a new JavaScript object literal, and then assigns its properties to the function values from the local scope.

Some developers would find this redundant and rather than finishing out with this sort of explicit export would probably just define the functions while declaring the object literal, something like:

return { 
    preload_and_resize: function(){
        var i = 0;
        var imageArray = new Array();
        for(i=0; i<myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src=myImages[i];
        }

        document.pic.style.height=(document.body.clientHeight)*0.95;
    },
    next_image: function() {
        index++;
        if(index<imageObj.length){
            document.pic.src=imageObj[index].src;
        }
        else {
            index=0;
            document.pic.src=imageObj[index].src;
        }
    },
    prev_image: function() {
        index--;
        if(index>=0){
            document.pic.src=imageObj[index].src;
        }
        else {
            index=myImages.length-1;
            document.pic.src=imageObj[index].src;
        }
    }
}
樱花落人离去 2024-12-24 18:49:58

关于以前的答案,我的版本:

function(self) {
    let myImages = new Array("img/01.jpg", "img/02.jpg", "img/03.jpg");
    let imageObj = new Array();
    let index = 0; // if you need to expose this call with self.index

    self.preload_and_resize = function() {
        let i = 0;
        let imageArray = new Array();
        let (i = 0; i < myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src = myImages[i];
        }
        document.pic.style.height = (document.body.clientHeight) * 0.95;
    };
  
    var next_image = function() {
        index++;
        if (index < imageObj.length) {
            document.pic.src = imageObj[index].src;
        } else {
            index = 0;
            document.pic.src = imageObj[index].src;
        }
    };
  
    var prev_image = function() {
        index--;
        if (index >= 0) {
            document.pic.src = imageObj[index].src;
        } else {
            index = myImages.length - 1;
            document.pic.src = imageObj[index].src;
        }
    };
})(window.myCurrentPage = window.myCurrentPage || {});

// now you canll myCurrentPage.preload_and_resize();

In respect of previous answers, my version:

function(self) {
    let myImages = new Array("img/01.jpg", "img/02.jpg", "img/03.jpg");
    let imageObj = new Array();
    let index = 0; // if you need to expose this call with self.index

    self.preload_and_resize = function() {
        let i = 0;
        let imageArray = new Array();
        let (i = 0; i < myImages.length; i++) {
            imageObj[i] = new Image();
            imageObj[i].src = myImages[i];
        }
        document.pic.style.height = (document.body.clientHeight) * 0.95;
    };
  
    var next_image = function() {
        index++;
        if (index < imageObj.length) {
            document.pic.src = imageObj[index].src;
        } else {
            index = 0;
            document.pic.src = imageObj[index].src;
        }
    };
  
    var prev_image = function() {
        index--;
        if (index >= 0) {
            document.pic.src = imageObj[index].src;
        } else {
            index = myImages.length - 1;
            document.pic.src = imageObj[index].src;
        }
    };
})(window.myCurrentPage = window.myCurrentPage || {});

// now you canll myCurrentPage.preload_and_resize();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文