值|引用传递-数组|对象解构-call|apply|bind-访问器-流程控制
- 实例演示值传递与引用传递的区别与联系;
- 数组和对象解构的常用方法与函数传参
- call,apply,bind的区别与联系,并试着实例演示一下
- 访问器属性的原理与实现过程,并实例演示;
- 多分支与switch转换的技巧
- 三元运算解决了什么问题,有什么限制?
1. 实例演示值传递与引用传递的区别与联系
- 值传递:原始类型 string, number, bool 等
- 引用传递:引用类型 object, array 等
- 深拷贝是值传递,浅拷贝是引用传递,传参是值传递
// 值传递
let a = 1;
let b = a;
// a = 1, b = 1
console.log('a = %d, b = %d', a, b);
a = 2;
// 更新 a ,不影响 b 返回 a = 2, b = 1
console.log('a = %d, b = %d', a, b);
// 引用传递
a = {x: 1, y: 2};
b = a;
// {x: 1, y: 2} {x: 1, y: 2}
console.log(a, b);
a.x = 2;
// 更新对象 a ,对象 b 也更新
// {x: 2, y: 2} {x: 2, y: 2}
console.log(a, b);
2. 数组和对象解构的常用方法与函数传参
// 数组解构
let [x, y, z = 3] = [1, 2];
// 解构到 x, y, z 变量中
// x = 1, y = 2, z = 3
console.log('x = %d, y = %d, z = %d', x, y, z);
// 对象解构
let {x1, y1, z1 = 'three'} = {x1: 'one', y1: 'two'};
// 解构到 x1, y1, z1 中
// x1 = one, y1 = two, z1 = three
console.log('x1 = %s, y1 = %s, z1 = %s', x1, y1, z1);
// 函数传参
// 数组传参
let linkArr = ([a, b, c]) => `${a} | ${b} | ${c}`;
// 1 | 2 | 3
console.log(linkArr([x, y, z]));
// 对象传参
let linkObj = ({x1, y1, z1}) => `${x1} | ${y1} | ${z1}`;
// one | two | three
console.log(linkObj({x1, y1, z1}));
3. call,apply,bind的区别与联系,并试着实例演示一下
- bind 绑定,返回一个函数声明,不会立即执行
- call 和 apply 立即执行
let test = function ( arg ) {
return arg;
};
const testObj = {
arg: 'args',
};
// 返回 Hi!
console.log(test('Hi!'));
// bind 返回一个函数声明,不会立即执行
let f1 = test.bind(testObj, 'bind');
// 返回 bind
console.log(f1());
// call | apply立即执行
let f2 = test.call(testObj, 'call');
// 返回 call
console.log(f2);
// 返回 apply
let f3 = test.call(testObj, 'apply');
console.log(f3);
4. 访问器属性的原理与实现过程,并实例演示
访问器:将方法伪造成一个属性,访问器属性优先级高于同名的普通属性
const result = {
data: {
id: 1,
meta: 'desc',
},
// 访问器,方法伪造成一个属性,取值
get getId() {
return this.data.id;
},
get getMeta() {
return this.data.meta;
},
// 访问器,方法伪造成一个属性,赋值
set setID(num) {
this.data.id = num;
},
set setMeta(value) {
this.data.meta = value;
},
}
// 访问器,伪造的属性赋值
result.setID = 2;
result.setMeta = 'test';
// 访问器,伪造的属性取值
// getID = 2, getMeta = test
console.log('getID = %s, getMeta = %s', result.getId, result.getMeta);
5. 多分支与switch转换的技巧
// If 多分支
let score = num => {
if (num >= 0 && num < 60) return '不及格';
else if (num >= 60 && num < 80) return '合格';
else if (num >=80 && num <= 100) return '优秀';
else if (num < 0 || num > 100) return '非法';
}
// 返回:非法 不及格 合格 优秀 非法
console.log(score(-1), score(50), score(60), score(100), score(101));
// switch来简化多分支
score = num => {
switch(true) {
case num >= 0 && num < 60:
return '不及格';
// return 无需 break;
case num >= 60 && num < 80:
return '合格';
case num >=80 && num <= 100:
return '优秀';
default:
return '非法'
}
}
// 返回:非法 不及格 合格 优秀 非法
console.log(score(-1), score(50), score(60), score(100), score(101));
// If 单值判断
let response = status => {
if (status.toLowerCase() === 'fail') {
return '请求失败!';
} else if (status.toLowerCase() === 'success') {
return '请求成功!';
} else {
return '非法请求!';
}
}
// 返回 请求成功!
console.log(response('SUCCESS'));
// switch 单值判断
response = status => {
switch(status.toLowerCase()) {
case 'fail': return '请求失败!';
case 'success': return '请求成功!';
default: return '非法请求!';
}
}
// 返回 请求成功!
console.log(response('SUCCESS'));
6. 三元运算解决了什么问题,有什么限制?
- 三元运算解决了双分支的简化,也可以多分支,但不适合于没有返回值的判断。
let status = 'SUCCESS';
let res = status.toLowerCase() === 'fail' ? '请求失败!' : (status.toLowerCase() === 'success' ? '请求成功!' : '非法请求!');
// 返回 请求成功!
console.log(res);