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

variable assigned to anonymous function is not defined

本文关键字:函数 变量 分配 未定义      更新时间:2023-09-26

我使用匿名函数分配给一个变量,以尽量减少使用全局变量。在这个函数中有嵌套函数:一个用于预加载和调整图像大小,另外两个嵌套函数用于导航(next和previous)。下面的代码生成匿名函数所赋值的变量未定义的错误:无法读取未定义的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>

你的匿名函数没有返回任何东西,所以当你运行它时,undefined返回。这就是为什么runThisCode没有定义。无论如何,根据您编写的方式,preload_and_resize将是local,因此无论如何您都无法访问它。

相反,您希望这个匿名函数构造一个对象,并返回该的。像这样的东西应该可以工作,或者至少让您接近:
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;
})();

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

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

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

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

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

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

return {
    "next_image": next_image
}

删除匿名函数,并使您的函数公开。您将只创建一个全局变量:对象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();

从你在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;
        }
    }
}

关于之前的回答,我的版本:

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();