JavaScript中函数的变量提升问题
函数的大体分三种,一种是函数的声明,一种是函数表达式(又称为函数的字面量)
1.函数的声明 => function myFn(){};
2.函数的表达式 => var myFn = function() {};
3.函数对象方式 => var myFn = new Function('n1','n2','return n1 + n2 '); // tip: 参数必须加引号
以上:3和其他的两项用法差别较大,不作比较;主要介绍1与2的区别:
先看二个简单的例子:
var myFn = function () {
console.log('mm');
}; myFn(); //mm var myFn = function () {
console.log('nn');
}; myFn(); //nn
在看下这个:
function myFn() {
console.log('mm');
};
myFn(); //nn function myFn() {
console.log('nn');
};
myFn(); //nn
为什么会出现以上两种情况呢? 我们知道JavaScript的代码是一行一行执行的,但是在代码执行之前,浏览器会有一个预解析的过程,会把声明的变量,函数的表达式提升,然后再一行一行的执行代码;但是为什么两个打印的结果不一样呢? 因为第一个是变量的提升,函数本身并没有提升,而第二个函数表达式会整个提升,所以myFn()写在哪,结果都是一样的;
我们这个时候可能回想,如果他们在一起的时候,哪个先执行?
第一种情况:
var myFn = function () {
console.log('nn');
}
myFn(); // nn function myFn() {
console.log('mm');
}
myFn(); // nn
第二种情况:
function myFn() {
console.log('mm');
}
myFn(); // mm var myFn = function () {
console.log('nn');
}
myFn(); // nn
这里注意的一点是,变量的提升高于函数表达式;在第一种情况下,var = myFn 会提升最高的优先级,其次是函数的声明。
在第一种情况里,函数的声明会提升,然后会被函数表达式覆盖,所以会打印两次一样的;第二次该提升的会提升,代码会一步一的执行;
看一下,下面的一段的代码执行情况,检验一下:
myFn();
function myFn() {
console.log('mm');
}
myFn();
var myFn = function () {
console.log('nn');
}
这里可以很明显的看到结果 =>打印两次 // mm
下面我们在介绍一种,在函数内部的变量提升(先看一段代码)
function myFn(a) {
var a = 2;
console.log(b);
console.log(a);
var b = 0 ;
}
myFn(1); // undefined 2
在函数的内部,如果函数有参数的话,就相当于在函数内部声明了这个变量,如上面例子:先声明 var a;调用的时候传来参数,则 a =1 ,若果在函数内部把a在赋值,那么a就等于新赋值的值;而b是不是参数,但在函数内部定义了,由于变量的提升,会打印underfind,这是变量定义,但是没有赋值,只有在函数赋值后,才能打印该值;
最新文章
- placeholder的样式设置
- CentOS7下zip解压和unzip压缩文件
- c# mybatis net +mysql
- .gitignore
- maven 控制台乱码
- ORA-12012 error on auto execute of job 8887
- ThinkPHP 3.1.2 视图-2
- 自定义radio图标
- ios根据颜色返回图片
- ElasticSearch — 集群搭建
- MFC常见问题以及解决方法(1)_MFC下文本编辑框按下回车后窗口退出
- BZOJ 1041: [HAOI2008]圆上的整点【数论,解方程】
- Lambda的使用与实战
- python基本概念
- echarts入门
- 修改CKplayer.js 源码解决移动端浏览器全屏不能限制快进的问题
- .net 使用HtmlAgilityPack做爬虫
- [转]Understanding Weak References
- 「Python-Django」Django中使用数据库的 9 个小技巧
- Unity3D入门工具介绍(一)
热门文章
- Android-ActionBar-与Menu结合
- [ASP.NET]大文件无法上传排查经验分享
- C# 灵活用法拾遗
- MYsql 之多表查询.
- CRUSH map 定制实例解析
- 【bug记录】jpa 解决org.hibernate.lazyinitializationexception could not initialize proxy - no session
- 欢迎使用CSDN-markdown编辑器u
- AVL树的实现——c++
- Python爬虫之关于登录那些事
- iOS-消除CocoaPods内容警告