javascript 高级系列之变量提升与函数提升
2017-11-10 23:55
447 查看
文章开始之前,我们来先看一段代码
为什么在变量之前打印出来是 undefind 而在之后是 10 呢?
其实真正的执行是按一下步骤执行的;
那什么是变量提升呢?这就是变量提升;
使用var定义变量的时候,js解释器会将变量提升到该作用域的最顶部,这就是变量提升
看下一个例子:
不用觉得奇怪,结果本该就是这样;同样的我们来解析一遍;
为什么全局作用域那里已经定了啊了,并且也赋值了,而在函数f1里面打印的还是undefined,这是因为函数形成的函数作用域,已经是一个封闭性的作用域,只要它里面存在此变量,将不会去访问外层作用域的相同变量了。
所以这也解释的通为什么函数f1里面打印的还是undefined了;
再看下面一个例子:
这是为什么呢?后面明明有啊,为什么还报错了,这一点就要注意了,这里的a是直接赋值的,不是var 定义的变量,他就不存在变量提升了,所以请记住这句话
只有var命令定义的变量才存在变量提升
示例一为什么都可以打印出来正确的答案,而示例二为什么第一个打印会报错?
对比两个函数我们不难发现,示例一中的函数是声明式函数,示例二中函数是字面量式函数;
这能说明什么吗?当然,这能说明 函数的提升只对声明式函数有效,对字面量函数无效
也就是说,声明式函数才有函数提升这个概念;
我们来解析一下上面两个函数:
另外要强调的一句是,函数提升的优先级要高于变量提升,也就是函数会被优先放在顶部,而后才是变量
好了,这就是变量提升和函数提升,是不是感觉很简单呢,最后我们再来看一个例子;
这里是不是和之前说的冲突了?解析应该是下面这样;
好了,关于变量提升和函数提升就讲到这里了,如果本篇文章帮助到了你,那么荣幸之至
变量提升
console.log(a); //undefined var a = 10; console.log(a); //10;
为什么在变量之前打印出来是 undefind 而在之后是 10 呢?
其实真正的执行是按一下步骤执行的;
var a; //首先会检查该作用域中有没有变量,如果有,就提到作用的顶部来; console.log(a) //当我们打印的时候a已经存在了,此时并未赋值,所以是undefined a = 10; //在我们定义赋值的地方,才会给他赋值; console.log(a) //此时之前已经将10赋给a了,所以a打印出来就是10了
那什么是变量提升呢?这就是变量提升;
使用var定义变量的时候,js解释器会将变量提升到该作用域的最顶部,这就是变量提升
看下一个例子:
var a = 10; function f1(){ console.log(a); //undefined var a = 20; console.log(a); // 20 } f1()
不用觉得奇怪,结果本该就是这样;同样的我们来解析一遍;
var a; //变量提升 a = 10; //赋值处赋值 function f1(){ var a; //变量提升 console.log(a) //undefined a = 20; //赋值处赋值 console.log(a) //上面已赋值,所以结果是20 } f1();
为什么全局作用域那里已经定了啊了,并且也赋值了,而在函数f1里面打印的还是undefined,这是因为函数形成的函数作用域,已经是一个封闭性的作用域,只要它里面存在此变量,将不会去访问外层作用域的相同变量了。
所以这也解释的通为什么函数f1里面打印的还是undefined了;
再看下面一个例子:
console.log(a); // 报错: a is not defined a = 10;
这是为什么呢?后面明明有啊,为什么还报错了,这一点就要注意了,这里的a是直接赋值的,不是var 定义的变量,他就不存在变量提升了,所以请记住这句话
只有var命令定义的变量才存在变量提升
函数提升
同样先看下面代码//示例一 console.log(f1()) // 10; function f1(){ return 10; } console.log(f1()) // 10; //示例二 console.log(f2()) // 报错:f2 is not a function var f2 = function (){ return 20; } console.log(f2()) // 20;
示例一为什么都可以打印出来正确的答案,而示例二为什么第一个打印会报错?
对比两个函数我们不难发现,示例一中的函数是声明式函数,示例二中函数是字面量式函数;
这能说明什么吗?当然,这能说明 函数的提升只对声明式函数有效,对字面量函数无效
也就是说,声明式函数才有函数提升这个概念;
我们来解析一下上面两个函数:
//示例一 function f1(){return 10}; //函数提升是将整个函数提升到最顶部; console.log(f1()) //10 执行到这里,函数已经存在,所以打印出来是10 console.log(f1()) //10 同样函数已经存在,能打印出正确结果 10 //----------------分割线--------------------// //示例二 var f2;//是的,这里是个变量,所以要遵循变量提升 console.log(f2()) // 没错,在这里f2是个变量,还不是函数 //所以把他当做函数使用,当然会报错说他不是一个函数 f2 = function (){return 20} //在这里将匿名函数赋给f2 console.log(f2()) //在此之前已经将匿名函数赋值给f2了,所以f2代表的就是这个函数 //所以自然就可以将f2作为函数来调用了
另外要强调的一句是,函数提升的优先级要高于变量提升,也就是函数会被优先放在顶部,而后才是变量
好了,这就是变量提升和函数提升,是不是感觉很简单呢,最后我们再来看一个例子;
console.log(a); //function (){return} var a = 10; function a(){ return 10; } console.log(a); // 10;
这里是不是和之前说的冲突了?解析应该是下面这样;
function a(){return 4000 10} //首先函数被提升到最顶部 var a //变量名与函数名一致,但是并不会将函数a覆盖 //相反的此时的变量a将会被忽略;因为在内存中其实存的仅仅是函数名 //不是整个函数,将函数当做变量a去存储,所以当碰到一样的变量名a的时候 //将会被忽略; console.log(a) //因为变量a被忽略,所以这里不会打印出来undefined,而是会打印a函数; a = 10; //给a赋值,将会覆盖之前的a函数,之前说过,函数a仅仅是存储为函数名a, //将函数名a当成一个变量去存储,其实就相当于使用function定义了一个变量a //和var 定义变量是一个概念; console.log(a) //这个时候a的值是10,所以打印的结果是10;
好了,关于变量提升和函数提升就讲到这里了,如果本篇文章帮助到了你,那么荣幸之至
微信搜索关注公众号 【大前端js】,回复vue教程,react教程,webpack实战等等,获得不同的视频教程,大量视频教程等你来拿;
原创不易,总结不易,手打不易,转载时请注明出处,谢谢相关文章推荐
- JavaScript系列文章:变量提升和函数提升
- JavaScript系列文章:变量提升和函数提升
- JavaScript高级程序设计之函数表达式之闭包之闭包与变量第7.2.1讲笔记
- js高级——变量和函数提升
- javascript变量提升和函数提升
- 浅谈JavaScript中变量和函数声明的提升
- javascript中的变量提升和函数声明提升
- JavaScript中变量和函数声明的提升
- JavaScript高级程序设计之函数表达式之私有变量之增强的模块模式第7.4.3讲笔记
- JavaScript系列二:变量、数组、流程控制、函数以及事件响应
- javascript的变量声明和函数声明提升
- 全面了解JavaScript的函数声明与函数表达式、变量提升
- javascript的变量声明和函数声明提升
- JavaScript 中的变量和函数提升
- javascript的变量声明和函数声明提升
- 详解javascript中的变量提升和函数提升
- JavaScript难点——变量提升和函数提升(三)
- 【JavaScript学习笔记】7:函数提升,变量提升,异常抛掷和捕获,ES6的Map和Set
- JavaScript中Hoisting详解 (变量提升与函数声明提升)
- javascript的变量声明和函数声明提升