1. 实例演示值传递与引用传递的区别与联系
值传递是指将变量a
的值赋值给变量b
,两个变量都是独立的变量,没有什么必然的联系。值传递后,再次更新变量a
,也不会影响变量b
的值。变量类型为原始类型的数据都是值传递;原始类型,string,number,bool
引用传递是将变量a
的数据的内存地址引用到变量b
中。两个变量数据的内存地址是同一个地址。所以更新变量a
后,变量b
中相对于的值也会发生变化。变量数据类型为对象、数组的就是引用传递
在传参时,不论什么类型的都是“值传递”。入参: 调用函数是传入的参数,简称:”入参”,
函数中对参数的更新,并不会影响到入参
对与引用类型,只有全新赋值才算是更新,修改属性不算的
值传递 demo
let a = 1;
let b = a;
console.log("a = %d, b = %d", a, b);
a = 2;
// 更新变量a的值不影响变量b
console.log("a = %d, b = %d", a, b);
引用传递 demo
//对象object
let obj1 = {
name: "tuduo",
id: "123456",
};
console.log(obj1);
let obj2 = obj1;
console.log(obj2);
console.log("更新对象obj1中的name值,两个对象name的值都更新");
obj1.name = "mumu";
console.log(obj1);
console.log(obj2);
console.log("--------------------------");
// 数组array
let arr1 = [1, 2, 3, 4, 5];
let arr2 = arr1;
console.log(arr1);
console.log(arr2);
console.log("更新数组arr1中的第2个数两个数组中的第二个值都更新");
arr1[1] = 20;
console.log(arr1);
console.log(arr2);
// 3. 传参
const f1 = (x) => (x = 10);
let m = 5;
console.log("m = %d", m);
f1(m);
console.log("m = %d", m);
const f2 = (x) => (x.a = 10);
let o = { a: 1, b: 2 };
console.log(o);
console.log("看上去函数中对于o.a的更新生效,实际上仍是值传递");
f2(o);
console.log(o);
2. 数组和对象解构的常用方法与函数传参
解构赋值可以快速的从数组和对象中提取值对变量进行赋值,被称之为解构赋值。
对于数组的解构赋值是按照数组索引和变量位置对应关系给变量赋值,和变量的书写顺序有关。
对于对象的解构赋值是按照对象的属性名和变量的变量名一一对应来赋值,变量必须与属性同名,才能取到正确的值,而对象的属性没有次序,与书写顺序无关。
数组的解构赋值 demo
// 等号两边的模式相同,左边的变量就会被赋予对应的值
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
//左边和右边不完全匹配时,变量的值就等于undefined
[a, b, c, d] = [1, 2, 3];
console.log(a, b, c, d);
//不完全解构,即等号左边的模式只匹配等号右边数组的一部分,解构依然可以成功
[a, b] = [1, 2, 3];
console.log(a, b);
//获取数组中的一个值
[, , a, ,] = [1, 2, 3, 4, 5];
console.log(a);
// 经典应用:交换两个变量的值
let x = 10;
let y = 20;
[x, y] = [y, x];
console.log(x, y);
对象的解构赋值 demo
let { id, name } = { id: 100, name: "手机" };
console.log(id, name);
({ name, id } = { id: 100, name: "手机" });
console.log(id, name);
let email = "admin@php.cn";
let { role, email: userEmail } = { role: "user", email: "user@php.cn" };
console.log(userEmail);
console.log(email);
3. call,apply,bind 的区别与联系
call,apply,bind 是函数自定义的静态方法,他们的区别在于通过绑定 bind()方法后不会立即执行,只会返回一个函数声明。call/apply 立即执行,他们两个的区别在于 apply()方法执行的参数是数组。
4. 访问器属性的原理与实现过程
访问器属性的原理是将方法伪造成一个属性
demo
<script>
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);
},
};
console.log("总金额 :", product.total);
</script>
5. 多分支与 swithc 转换的技巧
demo
let score = 80;
if (score >= 60 && score < 80) {
console.log("成绩合格");
} else if (score >= 80 && score <= 100) {
console.log("成绩优秀");
} else if (score < 0 || score > 100) {
console.log("无效成绩");
} else {
console.log("成绩不合格");
}
switch (true) {
case score >= 60 && score < 80:
console.log("合格");
break;
case score >= 80 && score <= 100:
console.log("成绩优秀");
break;
case score < 0 || score > 100:
console.log("无效成绩");
break;
default:
console.log("成绩不合格");
}
多分支与 switch 转换需要注意的是 switch 在判断结束后需要用关键字 break 跳出判断
6. 三元运算解决了什么问题,有什么限制?
三元运算解决了双分支的代码简化,其返回的结果只有两种,要么 a 要么 b,要么真要么假。