定义提升(1)

在《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);//undefined
	var i = 1;
	console.log(i);//1
var 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(); //结果为 B
function 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前端面试题


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值