博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一次关于bug的自我否定
阅读量:5931 次
发布时间:2019-06-19

本文共 2418 字,大约阅读时间需要 8 分钟。

最近在学习JavaScript中的闭包,涉及到其中一个案例,想着改写一下。案例挺简单,但是改bug过程有些曲折,在此分享一下在改bug过程中的自我怀疑自我否定直到曲径通幽的心路历程。

需求说明:我们知道arguments对象如果想调用Array的push方法,需要使用Array.prototype.push.apply(argument,[1,2])这样的方式,但每次都写这么一长串代码特别繁琐,想着提取一个push方法,方便以后直接调用。
废话不多说,,直接贴代码。

//提取的方法var push = (function(){    return function(){        var obj = Array.prototype.shift.apply(arguments);        Array.prototype.push.apply(obj,arguments);        return arguments;    }})()

方法洋洋洒洒写完之后,进入自测阶段。为了偷懒,再次使用了自执行函数,代码如下:

//自测代码(function(){    push(arguments,4)    console.log(arguments);})(1,2,3)

在node环境中执行,结果抛错如下:

Array.prototype.push.apply(obj,arguments);                             ^TypeError: Cannot assign to read only property 'length' of function 'function (){    push(arguments,4)    console.log(arguments);}'

这个报错很明显,当给一个function调用Array.porotype.push方法时会抛出这样的错误,因为一个function的length属性是只读的,而push的源码中length属性是需要可以修改的,即一个对象具有可读写的length属性之后才可以调用Array.porototype.push方法。

回到我提取的push方法中分析,Array.prototype.push.apply(obj,arguments);此刻我的obj应该是一个类数组{ '0': 1, '1': 2, '2': 3 },所以报错提示无法直观解决问题。

首先为了排除测试案例的原因,我修改了我的测试案例,避免function的介入,代码如下:
//测试案例var fn = function(){    push(arguments,4);    console.log(arguments);}fn(1,2,3);

修改完成之后发现测试顺利通过,说明我提取的方法没有问题。到此,牵扯出了一个新问题,我使用自执行函数时为啥会导致出错。

首先来到我脑海的原因是自执行函数的执行顺序,是否有异步一说。因为我提取push方法也是用的自执行函数,测试案例也是自执行函数,有可能两自执行函数的先后执行顺序导致了问题,为了验证这个答案,我决定将自测案例延时执行,代码如下:
setTimeout(function(){    (function(){        push(arguments,4)        console.log(arguments);    })(1,2,3)},10);

测试发现顺利通过,这个测试结果更加怀疑了刚才的假设(虽然心里一万个不相信)。然后开始查js自执行函数的执行顺序的问题,未果,说明大家都没遇到这样的问题,那很有可能我这假设不对。没办法,只能继续修改测试,既然是因为调用push.apply时候出错,我先注释掉它试试。代码如下:

//提取方法代码var push = (function(){    return function(){        var obj = Array.prototype.shift.apply(arguments);        // Array.prototype.push.apply(obj,arguments);        return arguments;    }})()//测试案例代码(function(){    // push(arguments,4)    console.log(arguments);})(1,2,3)

运行结果,抛出了不一样的错误,不一样的烟花,错误如下

D:\github\jsStudy\heightFn.js:174    })(1,2,3)      ^TypeError: (intermediate value)(...)(...) is not a function

这个错误提示很容易定位到了问题,自执行函数结尾未写分号导致。

这个问题其实是一个小问题导致的,无关乎技巧。分享这个主要是想表达:在遇到问题时,我们看到的问题可能只是表象,寻找解决方案的过程就是一个不断自我猜想,验证猜想,不断否定的过程,需要持续不断的挖掘。
最后贴出最终代码:

var push = (function(){    return function(){        var obj = Array.prototype.shift.apply(arguments);        Array.prototype.push.apply(obj,arguments);        return arguments;    }})();//测试案例;(function(){    push(arguments,4)    console.log(arguments);})(1,2,3);

转载地址:http://isutx.baihongyu.com/

你可能感兴趣的文章
weblogic重置用户名密码。
查看>>
C语言扩展Python模块
查看>>
父类不能转换成子类
查看>>
李洪强iOS开发之带placeHolder的Textview
查看>>
编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议93~97)
查看>>
Android 高仿微信表情输入与键盘输入详解
查看>>
【faster-rcnn】训练自己的数据——修改图片格式、类别
查看>>
C#:额外知识点
查看>>
防止表单重复提交
查看>>
【iCore3应用开发平台】发布 iCore3 应用开发平台出厂代码rev0.0.6
查看>>
leetcode - First Missing Positive
查看>>
CentOS 7.0系统安装配置步骤详解
查看>>
深入学习semaphore
查看>>
eth0 eth0:1 eth0.1 的区别
查看>>
Code a simple telnet client using sockets in python
查看>>
海归人才网
查看>>
xdmcp配置_百度百科
查看>>
Android应用开发基础篇(11)-----ViewFlipper
查看>>
NEWS - AdminStudio 11.5发布
查看>>
博客园的“随笔、文章、新闻、日记”有啥区别
查看>>