函数提升优先级高于变量提升
例1.
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
//打印undefined
function fun() {
var num;
console.log(num);
num = 20;
}
var num;
num = 10;
fun();
例2.
var a = 18;
fn();
function fn() {
var b = 9;
console.log(a);
console.log(b);
var a = '123'
}
//以上代码相当于
function fn() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123'
}
var a;
a = 18;
fn()
//打印 undefined,9
例3.
例3涉及到的知识点
1.连等赋值
var a=b=10;
等价于var a
a=10
b=10(b没有用var定义)
var a=10,b=10,c=10;
等价于
var a=10;
var b=10;
var c=10;
2.全局变量和局部变量
在函数内没有声明直接赋值的变量属于全局变量
3.函数提升和变量提升
(function() {
var a = b = 5;
})();
console.log(b);//5
console.log(a);//Uncaught ReferenceError: a is not defined
//a是定义在函数里面的局部变量
//b是全局变量
fn();
console.log(c);
console.log(b);
console.log(a);
function fn() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
//相当于
function fn() {
var a;
a = 9;
b = 9;
c = 9;
console.log(a);
console.log(b);
console.log(c);
}
fn()
console.log(c);
console.log(b);
console.log(a);
例4.
console.log(v1);
var v1 = 100;
function foo() {
console.log(v1);
var v1 = 200;
console.log(v1);
}
foo();
console.log(v1);
//相当于
function foo() {
var v1
console.log(v1); //undefined
v1 = 200;
console.log(v1); //200
}
var v1;
//函数和变量声明提升,但是函数还没有执行,从下面开始执行
console.log(v1); //undefined
v1 = 100;
foo()//调用函数再去执行函数里面的内容,函数里面先后打印undefined 200
console.log(v1); //100
例5.
非常重要:
函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被同名变量赋值后覆盖
var a = 100;
function a() {
var a = 200;
console.log(a);
}
a();
function a(){
var a;
a=200;
console.log(a);
}
var a;
a=100;//整个函数体从这里开始执行,函数声明不会被同名变量声明时覆盖,但是会被同名变
量赋值后覆盖
a();//再执行a(),所以报错
例6.
console.log(a) // ƒ a(){} 变量a赋值前打印的都会是函数a
var a=1;
function a(){}
console.log(a) // 1 变量a赋值后打印的都会是变量a的值
function a(){} // 函数声明提升 a-> f a (){}
var a; // 变量提升
console.log(a) // 此时变量a只是声明没有赋值所以不会覆盖函数a --> 输出函数a f a (){}
a=1; //变量赋值
console.log(a) // 此时变量a赋值了 --> 输出变量a的值 1
例7.
只有函数声明才会提升函数表达式不会提升,所以在函数表达式后面的代码会输出1,因为变量a赋值后把提升的函数a覆盖了。
1.函数声明:
function fnName(){……};
使用function关键字声明一个函数,再指定一个函数名,叫函数声明
2.函数表达式var fnName=function(){……};
使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式
3.匿名函数function(){…}; 使用function关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式
原文链接:https://blog.youkuaiyun.com/Mr_Kingyn/article/details/109130955
a(); // 2
var a = function(){ // 看成是一个函数赋值给变量a
console.log(1)
}
a(); // 1
function a(){
console.log(2)
}
a(); // 1
function a(){ // 函数提升
console.log(2)
}
var a; // 变量提升
a(); // 2
a = function(){ // 变量a赋值后覆盖上面的函数a
console.log(1)
}
a(); // 1
a(); // 1
例8.
a();
function a(){
console.log(1)
}
function a(){
console.log(2)
}
打印的是2,先声明的会被后声明的覆盖
例9.
(function() {
var x = foo();
var foo = function foo() {
return "foobar"
};
return x;
})();
(function() {
var x;
var foo;
x = foo();
foo = function foo() { //看成是一个函数赋值给变量foo,只有函数声明会提升
return "foobar"
};
return x;
})();
// Uncaught TypeError: foo is not a function
例10
var m = 1,
j = k = 0;
function add(n) {
return n = n + 1;
}
y = add(m);
function add(n) {
return n = n + 3;
}
z = add(m);
console.log(y);
console.log(z);
//以上代码相当于
function add(n) {
return n = n + 1;
}
function add(n) {
return n = n + 3;
}
var m = 1,
j = k = 0;
y = add(m);
z = add(m);
console.log(y);
console.log(z);
//输出4 4
考察两个知识点:
1.函数声明提升,浏览器解析的时候会首先对声明函数优先解析,记住是声明函数,而不是匿名函数!因此调用函数的位置可以放在前面!
2.考察函数没有重载的问题。简单的说没有重载就是每个函数的函数名只是指向函数的指针,因此再次命名相同函数名的函数时,就相当于改变了指针内的内容。看起来就像是第二个把第一个覆盖了。
例11
var foo=function(x,y){
return x-y;
}
function foo(x,y){
return x+y;
}
var num=foo(1,2);
function foo(x, y) {
return x + y
}
var foo;
var num;
foo = function(x, y) {
return x - y;
}
num = foo(1, 2)
// 返回 -1
当出现相同名称时,优先级为:变量声明(foo#1) < 函数声明(foo#2) < 变量赋值(foo#3)