作用域
<1>全局作用域
全局作用域中定义的变量和方法都会被绑定到
window
上(除了let
、const
)
var a = 1; //全局变量
function fnScope() {
console.log(a); //1 函数作用域中可以访问到
}
{
console.log(a); //1 块级作用域中也可以访问到
}
<2>块级作用域
{}
包裹的就是块级作用域(es6
新增的let
、const
定义的)
{
let a = 1; //let const只能在块级作用域里用 不能变量提升
const b = 2;
console.log(a); //1 只有在块级作用域中才能访问到a
}
console.log(a); //找不到 出了块级作用域访问不到a了
console.log(b); //找不到
{
var a = 1; //因为是var 所以变量提升了
}
console.log(a); //1
if (false) {
var a = 1; //如果是false只是变量提升了,但是执行阶段没有赋值
}
console.log(a); //undefined
{
function init() { }
}
console.log(init); // ? init() { }
if (false) {
function init() { }
}
console.log(init); // ? init() { }
{
function init() { }
init = 3;
}
console.log(init); // ? function init() { }
{
function init() { }
init = 3;
console.log('kuai', init); //? 3
}
console.log(init); //? function init() { }
{
init = 4;
function init() { }
init = 3;
console.log(init); //? 3
}
console.log(init); //? 4 输出的是最后一个函数的上一个的值
function fn() {
console.log('out');
}
if (false) {
function fn() {
console.log('inner');
}
}
fn(); //?out 如果为true那么就输出inner
思考
{
init = 4;
function init() { }
init = 3;
console.log(init); // ?3
function init() { }
init = 5;
}
console.log(init); // ?3 因为取最后一个函数的上一个值
{
init = 4;
function init() { }
init = 3;
console.log(init); // ?3
function init() { }
init = 5;
function init() { }
}
console.log(init); // ?5
<3>函数作用域
在
function
函数中的就是函数作用域
function fnScope() {
var a = 1;
console.log(a); //在此函数作用域中能访问到a
}
fnScope() //1
console.log(a); //找不到 出了函数作用域就访问不到a了
function fn() {
console.log('out');
}
function init() {
if (false) {
function fn() {
console.log('inner');
}
}
fn(); // Uncaught TypeError: fn is not a function
}
init();
/*
因为函数作用域下fn会提升,但如果为false的话,方法体不会提升。所以最终变为了:
function init() {
var fn;
if (false) {
}
// fn为undefined
fn(); // Uncaught TypeError: fn is not a function
}
*/
思考
function fn() {
console.log('out');
}
function init() {
if (true) {
function fn() {
console.log('inner');
}
}
fn();
}
init();//? inner
<4>词法作用域
无论函数在哪里被调用,如何被调用,它的词法作用域都只由函数被声明时所处的位置决定(小技巧:除了
this
定义和调用的值,其他都是在词法作用域中),没有this
var a = 123;
function parent() {
var a = 321;
function child() {
console.log(a); //做词法分析的时候就已经确定了调用parent的词法作用域中的a
}
child(); //321
return child
}
const p = parent(); //无论调用位置在哪里
p(); //321
this
绑定的效果:
var a = 123;
function parent() {
var a = 321;
function child() {
console.log(this.a); //运行时才能确定this的指向,确定了this的指向后才能确定a的值
}
child(); //123 this指向window
return child
}
const p = parent();
p(); //123