“这小娃娃到真是好大的口气,一口气说了函数有七重关,这老夫倒要好好品鉴一番。”尹曾琪目录精光,口气中带着一丝丝嘲讽,却也有一丝好奇。
林元青也被叶小凡的话吓了一跳,全场更是炸开了锅。
“这个叶小凡,说话还真是狂妄,什么函数七重关,我倒要看看他能够说出个什么来!”
罗丹面色凝重,眼睛更是一眨不眨地盯着叶小凡。叶小凡也愣了一下,讲真,这实在是怨不得叶小凡,这函数七重关,可是叶老亲自教导自己的。在平时和叶老的交流中,叶小凡也早已习惯把函数七重关挂在嘴边。谁知道,自己把函数七重关一讲,会引起这么大的轰动!
“好,叶小凡,你就说说,你所谓的函数七重关究竟是什么吧!”林元青也微笑着摇了摇头,对叶小凡说道。
“是,弟子遵命。函数七重关,这第一重关,自然指的是函数的定义。”叶小凡小声说道。
“函数的定义需要用到function关键字,定义函数的语法方才这位师兄也已经讲过了,我这边不再赘述。只是,我这边需要提一下的是,除了刚才那位师兄提到的定义函数的方法,其实还有另一种方法。”说着,叶小凡随手打出一段代码流。
//定义函数 function myFunction(){ //函数体 document.write("This is My First Function!<br>"); }
“这是第一种定义函数的方法,也是最为常用的方法。哦,对了里面的document.write方法表示用JavaScript向页面输出一段话。接下来,我再来讲讲第二种方法。”说着,叶小凡又随手打出一段代码流。
var a = function(){ document.write("This is My Second Function!"); }
“这便是第二种定义函数的方法了,和第一种方法有所不同,体现在第二种定义函数的方法需要先定义一个变量,比如var a,然后还是用function关键字去定义一个函数,再把这个函数赋值给变量a。因为最后要赋值给变量a的,因此这里定义函数的时候就不需要加上函数的名字了,这就是其中一个区别。用这种方法定义出来的函数,函数的名字就是变量的名字,也就是说,我要去调用这个函数,就这样做。”
a();
“哗众取宠,这两种方法本质上有什么区别,不都是一样调用么?”对面弟子对叶小凡的讲解嗤之以鼻。
“这自然是有区别的,刚才我讲了第一个区别,现在说第二个区别,这第二个区别,就体现在函数的调用上。”说着,叶小凡又随手打出一段代码流。
a(); var a = function(){ document.write("This is My Second Function!"); }
“这位师兄,你说我这段代码可以成功调用函数a么?”
“你这不废话么,当然可以了!”
“好,那师兄请看。”叶小凡开始执行代码。
函数七重关(1).html?__hbt=1539409418311:38 Uncaught TypeError: a is not a function
at 函数七重关(1).html?__hbt=1539409418311:38
众人看得亲切,之间代码直接报错了!对面弟子瞬间不说话了,场面一度有点尴尬。
“如果是用第一种方法定义的函数,把调用语句放在前面,是可以成功调用的。”
myFunction(); //定义函数 function myFunction(){ //函数体 document.write("This is My First Function!<br>"); }
代码运行,成功在页面上打印出:This is My First Function!
众人一下子又炸开了锅,有的大弟子一脸得难以置信。就连尹曾琪也对叶小凡稍微侧目,场外的罗丹面色则更加凝重。
“导致这种情况的原因是,如果用第一种方法去定义的函数,会被提前加载,因此调用语句可以写在函数的定义之前,因为那个时候函数已经被加载完毕了。而用第二种方式定义的函数,是不会被提前加载的。换句话说,必须要执行到函数定义的语句时,才会加载这个函数,正因为这个道理,刚才的代码才会直接报错。因为在调用a函数的时候,a函数还没有加载啊,那么强行调用一个不存在的函数,自然是不被允许的咯!”
“接下来,我再举一个例子来说明这个情况吧。”说着,叶小凡又随手打出一段代码流。
console.log(a); var a = function(){ alert("函数被调用了!"); } console.log(a);
代码运行后的结果,一如叶小凡所言,第一个a打印出来是undefined,表示未定义。第二个a打印出来就是具体的函数了,说明这个时候函数a已经被加载完毕!
“我有问题,为什么第一个a打印出来是undefined,而不是直接报错呢?”对面弟子疑惑得问到,接着他又侃侃而谈:“我之前遇到过这种情况,就是去引用一个从来没有被定义过的变量,得到的结果是直接报错的!比如...”
console.log(apple);
ReferenceError: apple is not defined
“看吧,这样写的话就直接报错了,因为我从来没有在任何地方顶一个apple这个变量。你刚才调用一个还未被加载的函数,为什么是打印出来undefined还不是报错呢?”
“是啊,这是为什么呢,看看叶小凡怎么说?”场外又窃窃私语起来。
“你混淆了概念,函数有没有被加载,跟变量有没有被定义是不同的事情,不要放在一起谈论。就比如说我刚才打的代码。”
console.log(a); var a = function(){ alert("函数被调用了!"); } console.log(a);
“注意看,函数有没有被加载,可以看成function有没有赋值给变量a。从代码上来看,自然是没有的。因为console.log语句是写在var a = function... 的前面啊。也就是说,调用a变量的时候,a变量并没有被赋值。但是不管a变量有没有被赋予一个funciton函数,我就问你一个问题,a有没有定义?”
“额,这个,定义是定义了,可是...它并没有被运行到啊!”对面弟子一脸的不服气。
“这个就要说到JavaScript代码的运行机制了。”叶小凡淡淡地说到,丝毫没有慌乱,而且,在叶老给自己灌输函数七重关的时候,自己也有过一样的疑问。