好久没有写这玩意儿了;今天在工作中遇到了这个问题,就拿出来分享下,希望对需要的朋友有所帮助,若有不足的地方,还请大神多多指出!
1、什么是声明提前?
它是指当我们声明一个变量或是一个函数的时候,我们可以在起前面访问带该变量或函数;即:声明统一提前,赋值原地不变
2、变量声明提前
就是当我们声明一个变量的时候,我们可以在其前方访问到它:这里就要提到一个函数作用域的概念:变量在声明它的函数体以及这函数体嵌套的任意函数体内都始终可见;这也就是变量的声明提前
eg:
var a= 1
function test () {
console.log(a) // undefined
var a= 2
console.log(a) // 2
}
上面的这个例子可以解析成:
var a=1
function test() {
var a;
console.log(a)
a=2;
console.log(a)
}
3、函数声明提前
函数声明提前的原理和变量声明提前类似;但需要注意的是:只有函数声明格式的函数才会声明提前 (像函数表达式、构造函数不会声明提前)
a、函数声明格式: function fun() { console.log('函数')}
b、函数表达式:var fun = function () {console.log('函数')}
c、构造函数: var fun = new Function(console.log('函数'))
eg:
function test() {
console.log(a) //函数a 本生
function a() { console.log(a) }
console.log(a) //函数本生
a() //能够执行, 函数本生
}
test()
生面 的例子可以解析为:
function test () {
function a() { console.log(a)}
console.log(a)
console.log(a)
a()
}
test()
下面再看一个例子:
var sum=2
function add(n) {
return n= n+2;
}
var res= add(sum)
console.log(res)
function add(n) {
return n= n+4
}
var res= add(sum)
console.log(res)
这个例子的结果是两个6;原因也是函数的声明提前;其代码等同于一下代码:
var sum=2
function add(n) {
return n= n+2
}
function add(n) {
return n= n+4
}
var res= add(sum)
console.log(res)
var res= add(sum)
console.log(res)
4、声明提前的先后顺序
函数声明提前,变量声明提前,到底谁会提前的更前??
假设当两者的名字一样时,最后会输出什么呢? 看看下面这个例子
function test() {
console.log(a) // 是函数本身
var a='变量先输出'
function a() { console.log(‘函数先输出’)}
}
test()
通过上面这个例子我们将会看到:最终输出的结果是一个函数本生,这是为什么呢?
其实以上例子代码等同于一下代码:
function test() {
function a() {console.log('函数先输出')}
var a //上面的函数已经声明,相同的变量名声明会被忽略
console.log(a)
a='变量先输出'
}
test()
这样按理说应该是输出‘undefined’, 为何是函数本生呢?
这里是因为: 上面的函数已经声明,相同的变量名声明会被忽略 (而这里只是再次申明a,并未修改现有a的值)
这里可以举一个简单的例子:
var a= 1
var a
console.log(a) // 1
下面再看一个例子:
console.log(xxp) //‘undefined’
var xxp= 1
function fn() {
console.log(xxp) // 函数本身 function xxp() { console.log(xxp)}
var xxp= 2
function xxp() { console.log(xxp)}
console.log(xxp) // 2
xxp() //报错
}
fn()
上面的代码等同于下面的代码:
console.log(xxp) // ‘undefined ’ 声明提前
var xxp= 1
function fn() {
function xxp() {console.log(xxp)}
var xxp
console.log(xxp) // 函数本身 (当名字相同时,再次定义【没有赋值】会被忽略)
xxp=2
console.log(xxp) // 2 这里进行了赋值操作 (函数已经不存在了,只有变量xxp)
xxp() // 报错; 这里没有函数了,只有变量xxp
}
fn()
以上就变量、函数声明提前的概念和用法,以及之间的关系;若有不完善的地方,还望大佬指出,谢谢