预解释
先来看一段简单的代码:
var a = 1;
var obj = {
name:'zhansan',
age:18
};
function fn() {
console.log('keep moving');
}
console.log(fn); // 把整个函数的定义部分(函数本身)在控制台输出。
console.log(fn()); // 把当前函数执行的返回结果return返回啥就是啥,没有return,默认返回。undefined
分析代码的执行过程:
当浏览器加载html页面的时候,首先会提供一个供全局JS代码执行的环境 ->全局作用域(window/global)。
-
预解释:
在当前的作用域中,JS代码执行之前,浏览器首先会默认的把所有带var和function的进行提前的声明或者定义。1)理解声明 和 定义
- 声明 (declare)
var a : 告诉浏览器在全局作用域中有一个num的变量,如果一个变量只是声明了但是没有赋值,默认的值是undefined
- 定义(define)
a=1 : 给变量进行赋
2)对带var和function关键字的在预解释的时候操作还是一样的
var 在预解释的时候只是提前的声明
function 在预解释的时候提前的声明+定义都完成了3)预解释只发生在当前的作用域下,例如:开始只对window下的进行预解释,只有函数执行的时候才会对函数中的进行预解释
- 声明 (declare)
JS中内存的分类
栈内存:用来提供一个供JS代码执行的环境 -> 作用域(全局作用域和局部作用域)
堆内存:用来存储引用数据类型的值 -> 对象存储的是属性名和属性值,函数存储的是代码字符串
几道面试题:
题一:
console.log(a);
var a = 1;
total(1,2)
function total(n1,n2) {
var total = n1 + n2;
console.log(total)
}
题二:
var b = 1;
console.log(b)
function b() {
}
console.log(b)
预解释的特殊情况
- 预解释的时候不管你的条件是否成立,都要把带var的进行提前的声明
if(!("num" in window)) {
var num = 12
}
console.log(num)
- 预解释的时候只预解释“=”左边的,右边的是值,不参与预解释
匿名函数之函数表达式:把函数定义的部分当做一个值赋值给我们的变量或者一个事件
fn();
var fn = function() {
console.log(1111)
}
- 执行函数定义的那个function在全局作用域下不进行预解释,当代码执行到这个位置的时候定义和执行一起完成
自执行函数:定义和执行一起完成
((function(){}) (123)
- 函数体中return下面的代码虽然不在执行了,但是需要进行预解释;return后面跟着的都是我们返回的值,所以不进行预解释
function fn() {
console.log(n);
return function() {
}
var n = 1;
}
fn();
- 在预解释的时候,如果名字已经声明过了,不需要重新的声明,但是需要重新的赋值
fn()
function fn() { console.log(2)}
fn()
var fn = 10;
fn()
function fn() { console.log(2)}
fn()