【Javascript】之作用域与预解析

1- 作用域

作用域指变量和函数可以被读写的范围,通常由函数来进行划分, 也叫作函数作用域。

1.1 作用域的分类

全局作用域 :

  • script标签下的就是全局
  • var声明的变量叫做全局变量
  • function声明的函数叫做全局函数
  • 全局变量和全局函数可以在整个作用域的任何位置被读取和写入

局部作用域:

  • 函数中{}的区域就是局部作用域
  • var声明的变量叫做局部变量
  • function声明的函数叫做局部函数
  • 局部变量和局部函数只能作用于当前的局部作用域中, 但凡出了{}就会被销毁
var a = 20;  // 全局变量
function sum(){ // 全局函数
    // 局部作用域
    console.log(a); // 全局的a
}
sum(); // 全局的sum
 
 
function s(){
    // 局部作用域
    var num = 30;
    console.log(num); // 局部变量的num
 
    function m(){
        console.log(1);
    }
    m();
}
s();
 
// console.log(num); // num is not defined  num未定义   报错
// m(); // 报错: m is not defined  m未定义

2- 作用域链

作用域链是js中的一种查找方式, 决定了变量和函数向上查找的方式。

先在自身作用域范围中查找变量和函数, 如果找到就直接返回, 如果找不到就往上一级作用域查找, 如果一直找到全局作用域都没有, 就会报错。

var a = 20;
function sum(){
   console.log(a); // 20
   // console.log(c);
}
sum();


var b = 30;
function s(){
   var b = 21;
   console.log(b); // 21
}
s();

3- 变量提升(预解析)

js的解析器在执行js代码的时候,会按照一定的顺序来执行

1.找 var function, 将var声明的变量,声明提前, 但是不赋值; 将function声明的函数整个存储在内存中;

2.逐行解析(从上到下)

在第一步中,找var的过程中,只声明,遇到 = += -= *= 赋值运算符的时候才会赋值且function只存函数。

3.1 例子1
console.log(a);
var a = 3;
console.log(typeof a);
function a() {
     alert('1');
}
a();
var a = 4;
console.log(a);
a();
function a() {
    alert(5);
};
a();
console.log(a);

执行过程:

var a;
var a;
function a() {
     alert('1');
}
function a() {
    alert(5);
};
console.log(a); // alert(5)的函数a
a = 3;
console.log(a); // number
a();// 报错
a = 4;
console.log(a); //4
a(); // 报错
a(); // 报错
console.log(a); // 4
3.2 例子2
console.log(a);
console.log(d);
var a = 3;

var d = function a() {
    alert('1');
};
console.log(a);
console.log(d);
a();

执行过程:

var a;
var d;
console.log(a); // undefined
console.log(d); // undefined 
a = 3;  
d = function(a){
	alert('1');
}
console.log(a); // 3
console.log(d); // function(a){ alert('1'); }
a(); // 报错, a是3, 不能被调用

函数调用时候, 执行函数内部的代码,代码执行的作用域是局部用域, 执行环境改变的时候,会重新执行预解析并且执行代码。

实参的赋值在声明完形参之后 var

3.3 例子3
function fn(a) { // 形参  a === var a
      console.log(a);
      var a = 3;
      console.log(a);
}
fn();

执行过程:

var a; //形参声明的时候, var a就执行了
console.log(a); // undefined
a = 3;
console.log(a); // 3
3.4 例子4
function fn(a) { // 形参  a === var a
    console.log(a);
    var a = 3;
    console.log(a);
}
fn(2);

执行过程:

var a; // 形参声明的时候 var a就执行了
a = 2; // 实参赋值给形参
console.log(a); // 2
a = 3;
console.log(a); // 3
3.5 例子5
var a = 4;
function fn(b) {
    console.log(a);
    var a = 3;
    console.log(a);
};

fn();
console.log(a);

执行过程:

var a;
function fn(b) {
    console.log(a);
    var a = 3;
    console.log(a);
};
a = 4;
fn()
/*
	var b;
	var a;
	console.log(a); undefined
	a = 3;
	console.log(a); 3
*/
console.log(a); // 全局变量 4 
3.6 例子6
var a = 4;
function fn(b) {
    console.log(a);
    a = 3;
    console.log(a);
  };
  fn();
  console.log(a);

执行过程:

var a;
function fn(b) {
    console.log(a);
    a = 3;
    console.log(a);
  };
a = 4;
f(n);
/*
	console.log(a); 全局变量 4
	a = 3;
	console.log(a); 全局变量 3
*/
console.log(a); // 全局变量3
3.7 例子7
var a = 4;
function fn(a) {
    console.log(a);
    a = 5;
};

fn(a);
console.log(a);

执行过程:

var a;
function fn(a) {
    console.log(a);
    a = 5;
};
a = 4;
fn(a)
/*
var a;
a = 4;
console.log(a); // 4
a = 5;
*/
console.log(a); // 4
3.8 例子8
function fn(a) {
    var s = a;
    s.name = 'United';
};

var json = {
    name: '小u'
};

fn(json);
console.log(json);

解析过程:

 var json;
 function fn(a) {
     var s = a;
     s.name = 'United'; 
  };
json = {
    'name': '小u'
 };
fn(json); // 小u
/* 
    var a;
    var s;
    a = {小u};
    s = a; {小u}
    s.name = 'United'
*/
console.log(json); // United
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值