📌 函数参数默认值
初始化参数 默认值:undefined
- ES6支持形参赋默认值写法 ```javascript // ES6 支持直接在形参赋默认值
function test(a = 1, b ){
console.log(a);
console.log(b)
}
test(undefined,2) // 打印结果:1 2
function test(a = undefined, b ){
console.log(a);
console.log(b)
}
test(1,2) // 打印结果:1 2
** ****形参不设默认值即undefined,通过实参赋值****;****实参undefined,会使用形参设置的默认值 **<br />**
- **ES5默认值写法**
```javascript
// ES5 设置初始化值方法-----------------------------
//短路运算写法
function test(a, b){
var a = arguments[0] || 'a设默认值',
b = arguments[1] || 'b设默认值';
console.log(a, b)
}
test();
//使用typeof() 方法------------------------------
function test(a, b){
var a = typeof(arguments[0]) == 'undefined' ? 'a设默认值' : arguments[0],
b = typeof(arguments[1]) == 'undefined' ? 'a设默认值' : arguments[1];
console.log(a, b)
}
test();
📌 递归函数
递归函数实现形式 递归函数就是在函数体内部调用自己,使用时要注意函数终止条件,避免死循环 递归两个必要因素:递归方程,递归结束条件
function getSum(x) {
if (x==1) return 1
return x + getSum(x - 1);
};
getSum(5)
getSum(5) = 5 + getSum(5 - 1)
getSum(4) = 4 + getSum(4 - 1)
getSum(3) = 3 + getSum(3 - 1)
getSum(2) = 2 + getSum(2 - 1)
getSum(1) = 1 ——>当x == 1时,通过if条件直接返回数值1
//解析
getSum(5) = (5 + (4 + (3 + (2 + getSum(1))))
getSum(5) = 5 + (4 + (3 + (2 + 1)))
结果:15
递归技巧
- 假设递归函数已经写好
- 寻找递推关系
- 将递推关系的结构转换为递归体
- 将临界条件加入到递归体中
小试牛刀——递归函数实现深拷贝
// 使用递归方式,实现深拷贝
//【深拷贝】:将数据的所有引用结构都拷贝一份, 数据在内存中独立
//【浅拷贝】:只针对当前对象的属性进行拷贝, 属性引用类型不考虑
1.假设已经实现 clone ( o1, o2),将对象 o2 的成员拷贝一份交给 o1
2.寻找递推关系
function clone( o1, o2){
for(var key in o2){
o1[key] = o2[key]; //需要考虑o2[key]时引用类型,再次使用clone函数,否则直接赋值
}
}
3.临界条件: 因为时for in 循环,没有成员遍历,自动结束
4.递归函数
function clone(o1,o2){
for(var key in o2){
if(typeof o2[key] == 'object'){
o1[key] = {};
clone(o1[key],o2[key])
}else{
o1[key] = o2[key];
}
}
}
📌 预编译
JavaScript运行三部曲
**
- 语法分析:通篇检查低级语法错误,不执行
- 预编译:内存中开辟空间,存放一些变量与函数
- 解释执行:解释一行,执行一行
JavaScript预编译分析
预编译不仅仅发生在script内代码块执行前,大部分会发生在函数执行前
- 页面产生便创建了GO全局对象【Global Object】—— window对象
- 第一个脚本文件加载至完成
- 通篇分析语法是否合法
- 开始进行预编译GO【脚本代码块script执行前】
1、查找全局变量声明(包括隐式全局变量声明),变量名作为全局对象GO属性,值赋予undefined
2、查找function函数声明,函数名作为全局对象GO属性,值赋予函数体
- 函数调用AO【函数执行前】
1、创建AO对象【Active Object】
2、查找函数形参即函数内变量声明,形参名即变量名作为AO对象属性,值为undefined
3、实参形参相统一,实参值赋给形参
4、查找函数声明,函数名作为AO对象属性,值赋予函数体
**
📌 暗示全局变量
暗示全局变量基于JavaScript 的两个特性
- 可直接使用变量,甚至无需声明
- 任何变量,如果未经声明,就为全局对象所有
var a = 1; //函数体外声明的变量称为全局变量
b = 2; // 无论函数体外或函数体内未声明的变量都称为暗示全局变量
function fn() {
var c = 3; //函数体内声明的变量称为局部变量
d = 4; // 暗示全局变量
}
fn(); // 若不执行函数,则不会进行函数预编译,d 就不会提升为全局变量
console.log(c); // error: c is not defined
console.log(d); // 4
暗示全局变量与明确定义全局变量的不同之处?**
- 使用var声明创建的全局变量,不能删除
- 暗示全局变量,可以删除
暗示全局变量非变量:严格来讲暗示全局变量不是真正的变量,而是全局对象属性,属性可以通过delete操作符删除,但变量不可以
1 var global_var = 1;
2 global_novar = 2;
3 (function(){
4 global_fromfunc = 3;
5 });
6
7 //企图删除
8 delete global_var; //false
9 delete global_novar; //true
10 delete global_fromfunc; //true
11
12 typeof global_var; //"number"
13 typeof global_novar; //"undefined"
14 typeof global_fromfunc; //"undefined"
📋 课后作业
分析下列代码预编译过程
【题一】------------------------------------------------------------------
function test() {
return a;
a = 1;
function a() { }
var a = 2;
}
console.log(test());
【分析过程】:
GO:{
test:function test(){.....}
test-AO:{
a: undefined ——> function a(){}
}
}
【结果】:"function a(){}"
return后面的a的赋值操作不执行
【题二】--------------------------------------------------------------------
function test() {
a = 1;
function a() { }
var a = 2;
return a;
}
console.log(test());
【分析过程】:
GO:{
test:function test(){...}
test-AO:{
a: undefined ——> function a(){} ——> 1 ——> 2
}
}
【结果】:2
1-执行test()函数会在GO中创建test的AO局部作用域,开始进行预解析
2-首先将var声明的a变量提升当前AO顶部,赋值undefined
3-其次将声明的a函数作为值,赋给已声明的a变量,开始执行当前AO代码
4-自上而下,首相将1赋值给变量a,其次又将2赋值给变量2
5-最终a变量的值为2,return变量a的值为2
【题三】--------------------------------------------------------------------------
a = 1;
function test(e) {
function e() {}
arguments[0] = 2;
console.log(e);
if (a) {
var b = 3;
}
var c;
a = 4;
var a;
console.log(b);
f = 5;
console.log(c);
console.log(a);
}
var a;
test(1)
console.log(a);
console.log(f);
【分析过程】:
GO:{
a:undefined ——> 1
f: 5
test: function test(e) {...}
test-AO:{
b: undefined
c: undefined
a: undefined ——> 4
e: undefined ——> 1 ——> function e() {} ——> 2
}
}
【结果】:2
undefined
undefined
4
1
5