1. 实例演示值传递与引用传递的区别与联系
值传递
将a的值传递给b,此时更新a,b并不会随之变化。
//值传递: 原始类型,string,number,bool
let a = 1;
let b = a;
console.log("a = %d, b = %d", a, b);
a = 2
console.log("a = %d, b = %d", a, b);
//更新a,不影响b。 b还等于1。
引用传递
将a的值传递给b,此时更新a,b同样变化。
// 引用传递: 引用类型, object,array
let obj1 = { a: 1, b: 2 };
console.log(obj1);
let obj2 = obj1;
obj1.a = 10;
// 更新obj1。 obj2同步更新。 a变成了10
// 因为引用传递传递的是一个地址,其中内容变化会影响所以引用的。
传参
//传参时,不论什么类型,都是"值传递"
const f1 = x => (x = 10);
m = 1;
f1(m)
console.log("m=%d", m);
// m依旧等于1。
// 函数中对参数的更新,并不会影响到入参
// 入参: 调用函数是传入的参数,简称:"入参"
const f2 = x => (x.a = 10);
let o = { a: 1, b: 2 };
console.log(o);
f2(o);
// 看上去函数中对于o.a的更新生效,实际上仍是值传递
// 对与引用类型,只有全新赋值才算是更新,修改属性不算的
console.log(o);
2. 数组和对象解构的常用方法与函数传参
解构赋值:将数组或对象里面的东西结构到一个变量里面。
数组:按照数组索引和变量位置对应关系给变量赋值,和变量的书写顺序有关
// 将1、2、3结构赋值给a、b、c。
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
//赋值对象数量不一致也可以
[a, b] = [1, 2, 3];
console.log(a, b);
[a, b, c, d = "xxxx"] = [1, 2, 3];
console.log(a, b, c, d);
// 变成集合
[a, b, ...c] = [1, 2, 3, 4, 5];
console.log(a, b, c);
// 单独取出
[, , a, ,] = [1, 2, 3, 4, 5];
console.log(a);
对象:按照对象的属性名和变量的变量名一一对应来赋值,变量必须与属性同名,才能取到正确的值,而对象的属性没有次序,与书写顺序无关。
let { name, id } = { id: 1, name: 3 }
console.log(name, id);
let email = "admin@php.cn";
// email名字冲突会覆盖数据,解决方法,起一个useEmil的别名就行了
let { role, email: userEmail } = { role: "user", email: "user@php.cn" };
console.log(userEmail);
console.log(email);
参数结构
// 数组传参
let sum = ([a, b]) => a + b;
console.log(sum([10, 20]));
// 对象传参
let getUser = ({ name, email }) => [name, email];
console.log(getUser({ email: "qq.cn", name: "张三" }));
3.call,apply,bind 的区别与联系
bind()方法后不会立即执行,只会返回一个函数声明。
call/apply 立即执行,他们两个的区别在于 apply()方法执行的参数是数组。
function hello(name) {
this.name = name;
console.log(this.name);
}
const obj = {
name: "admin",
};
//普通调用
console.log(hello("张三"));
// bind()不会立即执行,只返回一个函数声明
let f = hello.bind(obj, "李四");
console.log(f());
4. 访问器属性的原理与实现过程
访问器属性的原理是将方法伪造成一个属性
const product = {
data: [
{ name: "电脑", price: 5000, num: 5 },
{ name: "手机", price: 4000, num: 10 },
{ name: "相机", price: 8000, num: 3 },
],
get total() {
return this.data.reduce((t, c) => (t += c.price * c.num), 0);
},
};
// 通过属性total访问。
console.log("总金额 :", product.total);
5. 多分支与 swithc 转换的技巧
// 多分支
score = 90;
if (score >= 60 && score < 80) {
console.log("合格");
} else if (score >= 80 && score <= 100) {
console.log("学霸");
}
else if (score > 100 || score < 0) {
console.log("非法数据");
} else {
console.log("补考");
}
// switch简化多分支
// switch是严格匹配
score = 999;
switch (true) {
case score >= 60 && score < 80:
console.log("合格");
break;
case score >= 80 && score <= 80:
console.log("学霸");
break;
case score > 100 || score < 0:
console.log("非法数据");
break;
default:
console.log("补考");
}
</script>
6. 三元运算解决了什么问题,有什么限制?
简化双分支。
score = 80;
//使用“ ? ”
console.log(score >= 60 ? "及格" : "补考");