标签:预编译 测试 外部 定义 名称 表达式 匿名函数 def define
之前总是对变量提升,函数提升一知半解,随着时间的推移,理解的越来越深刻,接下来就写一写,有不对的地方请大家指出来。
1) 变量提升
1. 通过var定义(声明)的变量, 在定义语句之前就可以访问到
2. 值: undefined
console.log(a)//undefined var a = 1111; console.log(a)//1111
等同于
var a = undefined console.log(a) //undefined a = 1111; console.log(a) //1111
即:变量提升。你在一个作用域任何一个地方声明变量,都会被提升到作用域开始
2) 函数提升
1. 通过function声明的函数, 在之前就可以直接调用
2. 值: 函数定义(对象)
例子:
(1)var和函数
<script> console.log(a)//function a(){} var a=1; console.log(a)//1 function a(){
} console.log(a)//1 </script>
等同于以下代码:
其过程:变量a先声明,给a赋值为undefined,后来预编译函数function a(){}再声明;输出a为function a(){} ; 之后给a赋值为1;输出a为1
<script> var a; a = function a(){} console.log(a)//function a(){} a=1; console.log(a)//1 console.log(a)//1 </script>
(2)var和函数参数
<script> var a=8; function fn(a,b){ console.log(a)//undefined 当前函数作用域能够找到a,其值是undefined。 所以不会向外查找 var a=10; console.log(a)//10 } fn(); </script>
<script> function fn(a,b){ console.log(a)//hello var a=10; console.log(a)//10 } fn(‘hello‘); </script>
调用fn的时候传入参数a,b。 a和b会预编译赋值undefined,调用fn,传入"hello", a就被赋值为hello。
函数里面变量a的默认值就是参数a的值了,输出a即参数a值。给a赋值为10,输出a为10。
<script> var a=1; function fn(a,b){ console.log(a)//undefined 当前作用域能够找到a的 a=2; console.log(a)//2 } fn(); </script>
foo(); function foo(){ console.log("aaa"); }
function foo(){ console.log("aaa"); } foo();
foo(); var foo = function(){ console.log("aaa"); }
报错运行结果是: foo is not a function
原因是:js解析遇到 foo()时会默认当做函数来解析
var foo; console.log(foo); //undefined foo(); //foo is not a function foo = function(){ console.log("aaa"); }
如果函数声明和变量声明使用同一变量名称,函数声明的优先级高于变量
<script> var a=10; function fn(a,b){ console.log(a)//function a(){} 这里输出function a(){}, 不是参数a的值 var a=10; console.log(a)//10 function a(){} console.log(a)//10 } fn(15); </script>
fn里面有参数a,也有变量a,也有函数a,这种迷惑性更高。其实当你知道三者先后顺序之后就不迷惑了
经过测试,我发现:参数a会覆盖预编译变量a的默认值,如果有函数,函数会覆盖参数a的值,就是先后顺序而已。
函数形参声明--->函数声明---->变量声明
<script> a();//1 var a = c = function() { console.log(2) }; a();//2 function a() { console.log(1) } a();//2 (function(b) { b();//2 其实就是外部的a c();//2 c为什么是2? 也许有人以为这里会报错,其实不会。 原因就在于var b=c=xxx。 c相当于没有加var 不会预编译,这里c直接查找到外部作用域的c var b = c = function a() { console.log(3) } b()//3 })(a);//走到这里 a已经被赋值表达式重新赋值 c();//3 由于没加var 的原因 c已经被立即执行函数内部的赋值表达式改变了值 这里是3 </script>
console.log(typeof foo); console.log(typeof bar); console.log(typeof add); //函数的声明 function foo(){ alert(‘foo‘); } //命名函数表达式 var bar = function(){ alert(‘bar‘); }; // 函数表达式-匿名函数 var add = function(a,b){ return a+b; }
输出结果为 function undefined undefined
console.log(b); console.log(b()); var b=1; function b(){ return 2; }
输出结果为
function b(){
return 2;
}
2
console.log(a) // f a() { console.log(a) } console.log(b) //undefined function a() { console.log(a) } var b = function(){ console.log(b) }
标签:预编译 测试 外部 定义 名称 表达式 匿名函数 def define
原文地址:https://www.cnblogs.com/renzm0318/p/8966018.html