预解析
(1)变量预解析也叫做变量提升
(2)函数预解析也叫做函数提升
当html文件加载到script标签的时候 会将整个的js文件进行预解析、带var的变量会提升
函数提升
提升的function定义的函数
函数在调用的时候 也会做预解析
(1)变量和函数重名
函数在变量的下面----函数被忽略
函数预解析的优先级要高于变量预解析优先级
无论function写在哪都会在变量的上面
var a = 1;
function a(){
console.log('还有2天,就可以玩5天,再来9天');
}
console.log(a);
(2)函数重名会覆盖
(3)不同的函数定义方式的预解析
声明定义函数 整体都要提升
变量名字和函数名字重名 ---打印语句在最后
函数提升的优先级要高于变量提升的优先级
var a = 1;
function a(){}
console.log(a);
解析:
function a(){}
var a;
a = 1;
console.log(a); ==》1
变量名字和函数名字重名 ---
当函数提升之后 后面的变量声明但是未初始化的时候 就会被忽略
打印语句在最前
console.log(a);
var a = 1;
function a(){}
console.log(a);
解析:
function a(){}
var a;
console.log(a); ==》方法体 ƒ a(){}
a = 1;
console.log(a); ==》 1
console.log(a);
function a(){}
var a = function(){}
解析:
function a(){}
var a;
console.log(a); ==》ƒ a(){}
a = function(){}
<script>
// 总结:
// 预解析包含了变量提升和函数提升
// 变量提升:只能提升带var的变量 提升的变量的声明
// 不能提升不带var的变量
// 函数提升:只能提升function定义的函数
// 能提升var a = function(){}表达式定义的函数
// 但是能提升的函数的声明
// 函数提升的优先级要高于变量提升的优先级
// eg:
// var a = 1;
// function a(){}
// console.log(a) ===>1
// 如果函数和函数重名 那么会覆盖
// eg:
// function f1(){111}
// function f1(){222}
// console.log(f1) ===>222
// 如果函数和变量重复 那么
// 分2种情况
// 情况1:输出语句在后
// var a = 1;
// function a(){}
// console.log(a) ===>1
// 情况2:输出语句在前
// console.log(a) ===> function a(){}
// var a = 1;
// function a(){}
// console.log(a) ===>1
// 案例练习
// (1)不带var变量不提升
// console.log(a);
// a = 0;
// (2)带var的会提升
// console.log(a);
// var a = 0;
// console.log(a);
// (3)
// console.log(a);
// var a = '我是变量';
// function a() { console.log('我是函数') }
// console.log(a);
// 提升结果
// function a() { console.log('我是函数') }
// var a;
// console.log(a);
// a = '我是变量';
// console.log(a);
// (4)
// console.log(a);
// a++;
// console.log(a);
// var a = '我是变量';
// function a() {
// console.log('我是函数')
// }
// console.log(a);
// 解析后的代码
// function a() {
// console.log('我是函数')
// }
// var a;
// console.log(a);
// a++;
// console.log(a);
// a = '我是变量';
// console.log(a);
// (5)
// console.log(a);
// var a = 0;
// console.log(a);
// function fn() {
// console.log(a);
// var a = 1;
// console.log(a);
// }
// fn()
// console.log(a);
// 预解析的结果
// function fn() {
// var a;
// console.log(a);
// a = 1;
// console.log(a);
// }
// var a;
// console.log(a);
// a = 0;
// console.log(a);
// fn()
// console.log(a);
// (6)
console.log(a);
var a = 0;
console.log(a);
function fn() {
console.log(a);
a = 1;
console.log(a);
}
fn()
console.log(a);
// 预解析结果
// function fn() {
// console.log(a);
// a = 1;
// console.log(a);
// }
// var a;
// console.log(a);
// a = 0;
// console.log(a);
// fn()
// console.log(a);
</script>
IIFE--具名函数
有明确函数名字 的函数 叫做具名函数 也叫做有名函数
调用的时候 直接写函数名字就可以
function f1(){
console.log(11);
}
f1();
IIFE--简单的匿名函数
var sum = function(){
console.log(2222);
}
sum();
IIFE--匿名函数
IIFE 立即执行函数 、 匿名函数自调用
(function(){
console.log(1111);
})();
IIFE的结构
!function(){
console.log(2222);
}();
~function(){
console.log(3333);
}();
+function(){
console.log(4444);
}();
-function(){
console.log(5555);
}();
IIFE--作用
<script>
// var name = 'zs';
// var name = 'ls';
// console.log(name);
// 如果将你要自己的插件了 或者说是匿名函数自调用 注意
// 先写分号
// ;
// (function(){
// var name = 'zs';
// console.log(name);
// })();
// (function(){
// var name = 'ls';
// console.log(name);
// })()
</script>
函数参数的高级
<script>
console.log(f1.length);
function f1(a,b){
// 获取实参的个数,只能在函数的内部使用 因为在函数的外部
// 是不知道获取的是哪个函数的实参的
console.log(arguments.length);
// 使用函数对象的length属性可以获取形参的个数
// 可以在任意的位置使用
console.log(f1.length);
}
f1(1,2,3,4);
</script>
函数参数的高级-arguments的伪数组
<script>
function f1(){
console.log(arguments.length);
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
console.log(arguments[3]);
console.log(arguments[4]);
}
f1(1,2,3,4,5);
</script>
输入一组数字,求平均值的函数
<script>
// (1)输入一组数字,求平均值的函数
function avg(){
var sum1 = 0;
for(var i = 0; i < arguments.length; i++){
sum1 += arguments[i];
}
console.log(sum1 / arguments.length);
}
avg(1,2,3,4,5);
</script>
根据参数的不同执行不同的逻辑
<script>
// 如果是2个参数 那么久计算的是差值
// 如果是3个参数 那么久计算的是和值
function mix(){
if(arguments.length == 2){
return arguments[0] - arguments[1];
}else if(arguments.length == 3){
return arguments[0] + arguments[1] + arguments[2];
}
}
var result = mix(5,2);
console.log(result);
var result2 = mix(1,2,3);
console.log(result2);
</script>
计算3个参数的和
<script>
// 形参的默认值 如果传递了参数就不执行 如果没有传递就执行
function sum(a,b,c = 0){
return a + b + c;
}
// var result = sum(5,2,0);
// console.log(result);
var result = sum('5',2);
console.log(result);
</script>
通过参数的默认值来指定数据
<script>
function sum(a,b,c){
// console.log(typeof typeof c);
// console.log(typeof c == 'undefined');
c = typeof c == 'undefined' ? 0 : c;
return a + b + c;
}
var result = sum(1,2);
console.log(result);
</script>
callee属性
function f1(){
arguments.callee 可以获取到函数体
console.log(arguments.callee);
}
f1();
无限递归
function f1(){
console.log('大哥大哥你好吗?');
f1();
}
f1();
实现5的阶乘
<script>
// 5! 5*4*3*2*1
// var s = 1;
// for(var i = 5; i >= 1; i--){
// s *= i;
// }
// console.log(s);
function f(n){
if(n == 1){
return 1;
}
return n * f(n - 1)
}
var result = f(5);
console.log(result);
</script>