js内父级函数调用子函数出现函数未定义问题

首先定义了一个全局函数Locating,又在Locating内定义了一个局部函数pageScroll,然后我全局函数调用pageScroll时,报错Uncaught ReferenceError: pageScroll is not defined。

 function Locating(locate,time){
        console.log(locate+' -- '+time);
        var div_locate=document.getElementById(locate);
        var window_top_y = document.body.scrollTop;//获取滚动条顶部距离页面顶部的距离
        var element_top_y = div_locate.offsetTop;//获取某元素顶部距离页面顶部的距离
        var distance =   window_top_y-element_top_y;//当前窗口与顶部的距离
        var time = time;
var move_distance = time>50?Math.ceil((distance/Math.ceil(time/50))):distance;//每次移动的距离
        //每次移动的位移应为distance/duration,要移动的位置为element_top_y,
          function pageScroll() {
            var top = document.body.scrollTop;//获取滚动条顶部距离页面顶部的距离
            var dis_top = top - element_top_y;
                window.scrollBy(0,-move_distance);
                scrolldelay=setTimeout('pageScroll()',50);
                if(dis_top<=0){
                    clearTimeout(scrolldelay);
                }
//              console.log(dis_top);
            }
         pageScroll();
    }

请问除了将pageScroll定义为全局的函数,各位前辈还有哪些其他解决方法可以借鉴学习一下的

5个回答

结构一样,没有报错

 function a(){
        console.log("a")
        function b() {
                console.log("b")
            }
        b()
}
qq_32225989
748038347 回复2b0x: 闭包也会造成内存泄漏,所以最好在每次最后调用完毕了函数将其清空是比较好的办法.
2 年多之前 回复
SoulArbiter
2b0x 回复当作看不见: 就是对闭包这些引用很不熟悉,所以写起来才很是吃力,闭包练习不知该练习什么好
2 年多之前 回复
qq_29594393
当作看不见 回复2b0x: 可以用闭包解决这个问题
2 年多之前 回复
SoulArbiter
2b0x 好像setTimeout和setInterval都有这个情况存在。
2 年多之前 回复
SoulArbiter
2b0x 我知道哪里错了,执行延迟函数setTimeout后,会默认把执行环境切换到window对象下,所以在window对象下捕捉不到pageScroll(),这个函数,所以提示函数未定义
2 年多之前 回复

原型模式可以试试啊。

SoulArbiter
2b0x 没怎么用过原型模式,很是不熟呀。可以试试
2 年多之前 回复

你应该把在全局调用pageScroll的部分也贴出来看看。就你这个函数而言,里面的setTimeout是可以访问pagescroll的。你想在Locating函数外访问它的局部函数pageScroll,定义成全局pageScroll是可以的,但是这样随便给全局加变量不太好,既然你已经把Locating定义为全局函数,不妨把Locating作为对象,把pageScroll写到Locating.prototype里面,这样便于以后的修改也便于重复调用。

SoulArbiter
2b0x pageScroll有贴出来了 就写在locating里面,把locating写成对象?但是我按钮的触发函数是locating,把它写成对象感觉不太合适吧
2 年多之前 回复

查看一下setTimeout调用规范:
setTimeout(code, milliseconds, param1, param2, ...)
setTimeout(function, milliseconds, param1, param2, ...)

scrolldelay=setTimeout(pageScroll,50);
这样试一式

先说解决办法吧 和楼上一样 setTimeout(pageScroll,50) 这样能解决的原因就是闭包

再说说为什么你那样不行,你直接用setTimeout('pageScroll()',50) 这段代码的意思就是50秒之后执行pageScroll这个函数。但是你得知道垃圾回收这个机制
当你函数Locating执行完毕之后,Locating这个函数的局部变量,凡事没有在被引用的就会被垃圾回收机制回收,就是注销掉。
你的延时定时器是50ms之后再全局作用域下执行的,当50ms之后,pageScroll这个函数就已经被注销了,所以调用失败。

从全局作用域不能调用局部作用域来解释也可以,因为pageScroll函数就是局部作用域,至于证明setTimeout是什么作用域,console一下this你就能明白一点,至少setTimeout是window对象的方法,在window对象上面是访问不到你的pageScroll这个函数的

所以从上面两点都是不能访问的,来源的话,可以看看javascript作用域链规则以及垃圾回收机制
至于为什么用setTimeout(pageScroll,50) 可以执行,因为pageScroll就是对函数作用域pageScroll函数的引用。闭包原理让他得不到释放,自然就能调用了

stopllL
white_g 恩 函数体也被传递过去了,所以访问也是能访问的,就是正常的回调函数一样
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐