JavaScript中的变量提升详解

一、什么是作用域?

指的就是变量起作用的范围。在JS中有且只有函数可以创建作用域。

JS中的作用域是词法作用域。词法作用域就是一旦代码写好,可以根据代码的结构就可以看出的变量作用域就是词法作用域。JS中没有动态作用域。


二、js执行分两个阶段:

1.预解析阶段:会将函数声明,以及变量的声明提升到其所在的作用域的最顶上。

2.执行阶段

注意几点:函数声明会被提升;但是函数表达式不会被提升;new Function这种形式创建的函数不能被提升


三、变量提升中的特殊情况处理:

1.当函数同名的时候,都会被提升,但是后面的会把前面的给覆盖掉。

2.当函数和变量同名的时候,只会提升函数声明,忽略变量。


四、作用域链:

函数可以创造作用域,函数中又可以声明函数,这样就形成了作用域套作用域的链式结构,称作作用域链。


五、变量的搜索原则:

1.当遇到一个变量的使用的时候,首先在当前的作用域中去找这个变量,如果找到了,就直接使用;

2.如果没有找到,就去外层的作用域中进行查找,如果找到了就直接使用;

3.如果没有找到就继续沿着作用域链往上查找,直到找到0级作用域链。


六、条件式函数声明:

在条件语句中声明的函数 就是条件式函数声明。能否被提升,取决于浏览器,现在的浏览器 都不会进行提升


七、案例分析:

1.案例1:

var scope = "global";
function foo() {
  console.log(scope); //undefined
  var scope = "local";
  console.log(scope); //local
}
foo();

变量提升后的代码为:

var scope;
function foo() {
var scope;
console.log(scope); //
scope = "local";
console.log(scope); //
}
scope="global";
foo();

所以结果就显而易见了。

案例2:

function Foo() {
     getName = function(){ alert(1); };
     return this;
}
Foo.getName = function() { alert(2); };
Foo.prototype.getName = function(){ alert(3); };
var getName = function() { alert(4); };
function getName(){ alert(5); }

Foo.getName(); // ? 

getName(); // ? 

Foo().getName(); //?

new Foo.getName(); // ? 

new Foo().getName(); // ? 

new new Foo().getName(); // ?


首先进行改写变量提升后的代码:

function Foo() {
    getName = function(){ alert(1); };
    return this;
}
function getName(){ alert(5); }
Foo.getName = function() { alert(2); };
Foo.prototype.getName = function(){ alert(3); };
getName = function() { alert(4); };

1.Foo.getName(); //2

2.getName(); //4

3.Foo().getName(); //1  

构造函数如果当构造函数来调用,也就是和new一起使用的时候,this指向的是new创建的对象;但是如果构造函数不和new一起使用,像普通函数一样去调用的时候,这个this就指向window对象。调用Foo()就是返回this,就是window,然后Foo().getName()就相当于window.getName();所以getName=function(){ alert(1) };就相当于定义了全局getName函数返回1.

4.new Foo.getName();//2 (执行顺序是先Foo.getName()后new)

5.new Foo().getName(); //3 (执行顺序是先new Foo()后getName(),去原型中找到了)

6.new new Foo().getName(); //3 (执行顺序是先new Foo().getName()后new)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值