定义提升(1)
来源:互联网 发布:数据库系统设计与实现 编辑:程序博客网 时间:2024/05/01 02:13
在《JavaScript权威指南》第六版的4.3节和5.3节中分别讲了函数的两种定义方式:
函数声明方式: function foo(){}函数表达式方式:var foo= function(){}
两者的区别在于函数声明的方式会有一个“定义提升”(hoisting),即将函数声明提升到顶部,这样之后的代码也都可以访问到它。函数表达式的方式则不存在定义提升。通过下面两个例子展示两者的区别:
例子1:foo();//调用成功:function foo(){ console.log('ok');}
例子2: foo();//调用失败,"uncaught TypeError: Property 'foo' of object [object Object] is not a function"var foo = function(){ console.log('ok');}
例子1中虽然是先调用foo,然后才声明的foo函数,但是由于定义提升,foo的声明被提高到顶部,因此foo调用成功。例子1的代码等价于:
function foo(){ console.log('ok');} foo();//调用成功
例子2中,foo是函数表达式,不存在定义提升,所以先调用后定义的方式是行不通的。和函数声明同样有定义提升的效果的还有var关键字定义的变量,请看下面例子:
例子3: console.log(i);//undefinedvar i = 1;console.log(i);//1var i =1;可以看成变量定义和初始化两部分,var i; i =1;其中变量定义提升,放在了最开始的部分,而初始化还是留在原地,所以第一次输出的是undefined,第二次输出的是1;
因此之前的例子2等价于下面的代码:
var foo; foo();//调用失败 foo = function(){ console.log('ok');}这也就说明了为什么报错的内容是“foo不是一个函数”。由于有定义提升,在同一作用域下所以要特别注意函数同名覆盖的问题。由于多次用var声明一个变量是无所谓的(《JavaScript权威指南》第六版的5.3.1节),这里只需要讨论函数之间同名覆盖、函数与变量同名覆盖两个问题。请看下面的例子:
例子4:function fun1(){alert('A');}fun1(); //结果为 Bfunction fun1(){ alert('B');}可以看到函数声明的提升,会按照出现的顺序进行覆盖。
例子5:(function(a){ console.log(a);//输出函数a的内容 function a(){}; var a=10;}(100))可以看到函数声明和变量声明的提升,会以函数声明为主。因为在函数执行上下文中,变量声明不会干扰已经存在的同名变量,形参和函数声明。说到执行上下文(EC)又是一个比较大的话题,我把它放到下一篇,这里就略过。
最后再看一个比较综合的例子:
例子6:function Foo() { getName = function () { alert (1); }; return this;}Foo.getName = function () { alert (2);};var getName = function () { alert (4);};function getName() { alert (5);}问:Foo.getName();getName();Foo().getName();getName();
答案:Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
参考文章:
1、JavaScript函数声明和函数表达式的区别:函数声明的提升
2、一道常被人轻视的JS前端面试题
1 0
- 定义提升(1)
- 定义提升(2)
- 如何定义性能”提升“了多少?
- Java内功提升之定义方法
- 软件工程视频总结(1)--思想提升
- C#程序性能提升篇2 类型(字段类型、class和struct)的错误定义所影响性能浅析
- Java提升1
- Dagger2-渐入二(提升)
- 提升
- 提升
- 提升
- 提升
- 提升
- 预解释(变量提升)(1-1-1)
- mysql5.1通过分区(Partition)提升MySQL性能
- 中小企业提升产品可靠性的设计方法(1)
- 《统计学习方法,李航》:8、提升方法Boosting(1)
- 神经网络的提升方法(1)——交叉熵
- Redis学习笔记
- java 获取、修改文件属性
- android将xml文档中自定义标签中的内容取出
- Ubuntu下安装SVN服务
- Hadoop Namenode不能启动 dfs/name is in an inconsistent
- 定义提升(1)
- AJAX实现计算器
- 实现简单的输入编辑,录入正确的字符串,出现‘$’,表示撤销前一个输入, 发现连续的‘$’,表示连续撤销前面的输入;发现‘%’,表示放弃前面所有录入; 生成最终结果。
- C语言练习题
- hadoop 集群常见错误解决办法
- View事件分发源码分析
- MySQL Varchar的新认识
- Greenplum节点增加
- org.hibernate.AssertionFailure: null id in X.XX.XXX 原因及解决方案