15 作用域和预解析

作用域
全局作用域
局部作用域(私有作用域)

全局作用域:网页一打开就形成了全局作用域,在函数外面就形成了全局作用域
全局变量:在全局作用域下面定义的变量,在函数外面定义的变量

局部作用域:函数一执行就形成了局部作用域
局部变量:在局部作用域下定义的变量,在函数里面定义的变量,形参也是局部变量

var num = 10; //全局变量
function fun(){
    var num = 20; //局部变量
    return num;
}
var result = fun();
console.log(result); //20
console.log(num); //10

this关键字

console.log(this); //在全局作用域下this指向window
function fun(){
    console.log(this); //普通函数中的this指向window
}
fun();

作用域链:由内往外一层一层查找

var num = 10;
  function f1(){
   var num = 20;
    function f2(){
     var num = 30;
      function f3(){
       var num = 50;
         console.log(num);//50
            }
            f3();
        }
        f2();
    }
    f1();

注:会先输出50,由内向外逐一输出

变量提升(预解析)

当网页一打开,浏览器首先会读一遍代码,浏览器会先把带var和function提前声明

1.如果带var浏览器会提前声明,但是只是声明不去赋值,默认结果为undefined

2.变量提升,只提升等号左面的,不会提升等号右面的,即会直接把左面的声明提升到前面去

3.如果是function会声明加定义,就是把整个function提升到代码前面去

练习:
1.

console.log(a); //undefined
var a = 123;
console.log(a); //123
console.log(f); //函数体
function f(){
    console.log("函数声明提升");
}
伪代码:
var a;
function f(){
    console.log("函数声明提升");
}
console.log(a); //undefined 此时a提升了声明变量但是并未赋值
a = 123;
console.log(a); //123 此时已赋值
console.log(f); //函数体已提升
console.log(a); //undefined
var a = 123;
console.log(a); //123
console.log(f()); //undefined
function f(){
    console.log("函数声明提升");
}
f(); //函数声明提升
伪代码:
var a;
console.log(a); //undefined 此时a提升了声明变量但是并未赋值
a = 123;
console.log(a); //123 此时已赋值
console.log(f()); //undefined 就相当于var result = f()                                      //console.log(result);此函数没有返回值所以为undefined
function f(){
    console.log("函数声明提升");
}
f();
f(); //3
function f(){
    console.log("1");
}
f(); //3
function f(){
    console.log("2");
}
f(); //3
function f(){
    console.log("3");
}
伪代码:
function f(){
    console.log("1");
}
function f(){
    console.log("2");
}
function f(){
    console.log("3");
}
//最后一个3覆盖了前面的两个函数
f(); //3
f(); //3
f(); //3
console.log(a); //undefined
var a = 123;
console.log(a); //123
function f1(){
    console.log(a); //undefined
    var a = 456;
    console.log(a); //456
}
f1();
console.log(a);
伪代码:
var a;
console.log(a); //undefined
a = 123;
console.log(a); //123
  function f1(){
    var a;
    console.log(a); //undefined
    a = 456;
    console.log(a); //456
}
f1();
console.log(a); //123
console.log(a); //undefined
var a = 123;
console.log(a); //123
var a = 456;
console.log(a); //456
伪代码:
var a;
console.log(a); //undefined
a = 123;
console.log(a); //123
a = 456;
console.log(a); //456
console.log(a); //函数体
var a = 123;
console.log(a); //123
function a(){}
console.log(a); //123
function a(){}
console.log(a); //123
伪代码:
 function a(){}
 console.log(a); //函数体
 var a = 123;
 console.log(a); //123
 console.log(a); //123
 console.log(a); //123

注:函数和变量同名,函数提升,变量声明不提升

console.log(fn1); //函数体
function fn1() {}
console.log(fn2); //undefined
var fn2 = function() {};
console.log(fn2); //函数体
伪代码:
var fn2;
function fn1() {};
console.log(fn1); //函数体
console.log(fn2); //undefined
fn2 = function(){};
console.log(fn2); //f()匿名函数
console.log(a, b); //undefined undefined
var a = 12;
var b = 13;
sum(); //1
function sum() {
console.log(1);
}
伪代码
var a;
var b;
console.log(a, b); //undefined undefined
a = 12;
b = 13;
function sum() {
     console.log(1);
}
sum(); //1
console.log(a); //undefined
var a = 12;
function fn() {
console.log(a); //undefined
var a = 13;
}
fn();
console.log(a); //12
伪代码:
function fn(a) {//此时a为局部的
console.log(a); //undefined
var a = 13; //修改局部的跟全局没关系
}
var a;
console.log(a); //undefined
a = 12;
fn();
console.log(a); //12
console.log(a);// 报错
a = 12;
function fn(){
console.log(a);
var a = 13;
    }
fn();
console.log(a)//12
伪代码:
console.log(a);// 前面没有东西,直接报错
a = 12;
var a;
console.log(a); //undefined
a = 12;
function fn(a) {
console.log(a); //12
a = 13;
  }
fn(a);
console.log(a); //12
伪代码
function fn(a) { //形参就是变量,变量为局部
console.log(a); //12
a = 13;
  }
var a;
console.log(a); //undefined
a = 12;
fn(a);//此时a为实参
console.log(a); //12 拿到了全局的
var foo = 1;
function bar() {
不管判断有没有成立,都要进行变量提升
if (!foo) {
     var foo = 10;
      }
  console.log(foo);
    }
bar(); //10
伪代码:
var foo = 1;
function bar() {
var foo;
不管判断有没有成立,都要进行变量提升
if (!foo) {
  foo = 10;
   }
console.log(foo);
   }
bar(); //10
var n = 13;
function fn(n) {
alert(n); //13
var n = 14; //
alert(n); //14
  }
fn(n);
console.log(n); //13
伪代码:
function fn(n) {
alert(n); //13
var n = 14; //
alert(n); //14
  }
var n;
n = 13;
fn(n);
console.log(n); //13
console.log(a); //undefined
var a = 12;
function fn(a) {
console.log(a); //12
  a = 13;
 }
fn(); 
var a;
console.log(a); //13
伪代码:
var a;
console.log(a); //undefined
a = 12;
function fn() {
      console.log(a); //12 自身没有找全局,修改也修改了全局的
      a = 13;
    }
fn(); 
console.log(a); //13
console.log(a,b,c); //undefined
var a = 10;
    b = 20;
    c = 30;
function f(a){
console.log(a,b,c); //10,undefined,30
var b = a = c = 100;
    console.log(a,b,c); //100,100,100
}
f(10,20);
console.log(a,b,c); //10,20,100
伪代码:
var a;
var b;
var c;
console.log(a,b,c); //undefined undefined undefined
   a = 10;
   b = 20;
   c = 30;
function f(a){
var b;
console.log(a,b,c); //10,undefined,30
    b = a = c = 100;
console.log(a,b,c); //100,100,100
    }
f(10,20);
console.log(a,b,c); //10,20,100
console.log(num,str);//undefined undefined
var num = 18;
var str = "lily";
function fn2(){
   console.log(str,num);//lily undefined
   num = 19;
   str = "candy";
   var num = 14;
     console.log(str,num);//candy 14
 }
 fn2();
 console.log(str,num);//candy 18
伪代码:
function fn2(){
var num;
console.log(str,num);//lily undefined
num = 19;
str = "candy";//修改全局的 没有var
num = 14;//局部的 有var 
console.log(str,num);//candy 14
  }
var num;
var str;
console.log(num,str);//undefined undefined
num = 18;
str = "lily";
fn2();
console.log(str,num);//candy 18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值