常见的调试报错 - 错误:xxx not defined

  • 作者:KK

  • 发表日期:2016.11.09


先上示例代码:

<script>
alert(xxx);
</script>

报错消息是:xxx is not defined

翻译成中文:xxx是还没被定义过的

很明显,这里就是变量未定义的提示,直接用一个未定义过的变量就会这样,注意是直接用


基础知识:间接用则不报错

怎么间接呢,前面尽量不产生全局变量里我已经提到过,当使用一个当前作用域没有的变量时,JS引擎会往window里找这个属性

var xxx = 11;
alert(window.xxx); // 11

这是很正常的运行,那其实下面的代码都在访问全局变量xxx:

alert(window.xxx); //间接访问————提示 undefined

alert(xxx); //直接访问————报错

可是第一句不报错第二句却是报错了,原因就是:第一行是间接访问

先是通过window再访问它的xxx属性,访问某对象的属性时,有值就输出这个值,没值就会输出“未定义”(undefined)的提示

这是个很重要的概念,心中没有这个概念的话平时调试就吃大亏了

其实不止是全局变量,在函数里访问局部变量都遵守这样的规律:

function test(){
	alert(this.qqq); // undefined
	
	alert(qqq); //报错  其实也是由于本作用域没有,它尝试去window里找了
}

test();

缩小排查范围

好了,回到主题,我是要分享xxx is not defined这个未定义错误提示的程序调试技巧嘛

  • 肯定不是调用函数

    如果是alert(xxx())这样的话会报错xxx is not a function,所以只要报错不是这句话,就肯定了调用代码不是一个函数执行,起码是xxx而不是xxx()

  • 可能的代码是

    既然咱们已经清楚了,通过一个对象访问不存在的属性不会报错,而会返回undefined

    那么意味着出现xxx is not defined提示的时候,这个引发错误的代码也肯定不会是alert(某某对象.xxx),而是某函数(xxx)var 取值 = xxx这样的赋值语句


排查 xxx 如何产生

如果程序是你设计的,你肯定很清楚原来是如何产生xxx的,去定义的地方看看遭遇了怎样的逻辑变革

然而使程序员长时间调试这些问题的原因恰恰却是这段程序不是他写的,这个非常关键,我们“小时候”经常就把调试时间花在调试别人的程序上,但这又是成长过程中要掌握的本领

那我们先要知道有什么办法能定义xxx这个东西,这其实要看xxx是如何被使用的

  • 使用情景1:直接当普通变量值使用 alert(xxx)

    这种情况不多见,如果真的有,那这段代码企图使用的肯定是一个全局变量,所以排查位置首先就看看全局变量声明的地方有没有它(直接搜变量名吧,搜出所有var xxx或者xxx = 的地方)

    但不一定能找出来,只是很可能会找出来,然而如果一个都没有的话,基本可以确定:这是一块失误的代码,直接就是调用了不存在的变量,它应该删除掉

    要么就可能是:这个变量被删除了,但使用的代码遗漏了,也应该删除这块代码


  • 使用情景2:从xxx对象中访问了属性 var a = xxx.yyy

    可是xxx对象不存在,这是xxx加载失败,一般不会是删除了xxx对象的定义造成的,不大可能、

    所以这时候要排查对象的加载流程,确认xxx的定义点被加载