Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:很认真
js 变量传递有那些类型?
这两种传递有什么区别?
如下代码 1 赋值给 a, 再把 a 的值赋给 b,修改 a 的值不会改变 b 的值,这就是值传递
let a = 1;
let b = a;
a = 2;
console.log(a, b);
如下代码,其实两个变量访问的都是同一个变量内存地址,所以修改一个变量的数据,引用相同内存地址的数据也会直观的看到变化
let arr = [1, 2, 3, 4, 5, 6, 0];
let arr1 = arr;
arr[0] = 9;
console.log(arr[0], arr1[0]);
那么传递参数又是什么类型?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let a = 1;
let b = a;
a = 2;
console.log(a, b);
let arr = [1, 2, 3, 4, 5, 6, 0];
let arr1 = arr;
arr[0] = 9;
console.log(arr[0], arr1[0]);
//传递的原始类型时
//函数的传参对于函数内部对变量的更新无影响
const f1 = (x) => (x = 1);
let o = 10;
//入参:调用函数传入的参数
f1(o);
console.log(o);
//传递的是引用类型时
const f2 = (y) => (y.a = 9);
let ob1 = { a: 1, b: 2 };
f2(ob1);
//此时会发现对象中a的值被更新为9,这是为什么呢?
console.log(ob1);
//函数中对于ob1.a的更新生效了,实际上仍是值传递
//对于引用类型,只有全新赋值才算是更新,修改属性不算更新
const ob2 = { a: 10, b: 20 };
ob2.a = 0;
//ob2为一个常量,按理说修改会报错但是是正常的,说明修改对象中的一个属性不算更新
//ob2 = {};
//此时报错
const f3 = (z) => (z = {});
let c = { a: 1, b: 2 };
f3(c);
console.log(c);
//此时可以看到函数内对引用类型传递的更新也不会影响入参,所以函数中传参都是值传递
</script>
</body>
</html>
用途:快速从集合数据(数组/对象)解构出独立变量
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
//支持默认值
[a, b, c, d = "XXX"] = [1, 2, 3];
let { name, id } = { id: "a100", name: "手机" };
console.log(name);
let email = "admin@php.cn";
({ user, email } = { user: "name", email: "cp@php.cn" });
console.log(email);
//此时我们并不想更新email变量,可以给变量起一个别名
email = "admin@php.cn";
({ user, email: useremail } = { user: "name", email: "cp@php.cn" });
console.log(useremail);
console.log(email);
//数组传参
let sum = ([a, b]) => a + b;
console.log(sum([10, 11]));
//对象传参
let ar = ({ c, d }) => [c, d];
console.log(ar({ c: "我是C", d: "我是D" }));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>解构赋值</title>
</head>
<body>
<script>
//解构赋值:快速从集合数据(数组/对象)解构出独立变量
//1.数组
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
//支持默认值
[a, b, c, d = "XXX"] = [1, 2, 3];
//2.对象
let { name, id } = { id: "a100", name: "手机" };
console.log(name);
//3.对象解构赋值支持别名,避免同名变量被更新
//这里声明一个与对象解构变量同名的变量
let email = "admin@php.cn";
({ user, email } = { user: "name", email: "cp@php.cn" });
console.log(email);
//此时我们并不想更新email变量,可以给变量起一个别名
email = "admin@php.cn";
({ user, email: useremail } = { user: "name", email: "cp@php.cn" });
console.log(useremail);
console.log(email);
//参数解构
//数组传参
let sum = ([a, b]) => a + b;
console.log(sum([10, 11]));
//对象传参
let ar = ({ c, d }) => [c, d];
console.log(ar({ c: "我是C", d: "我是D" }));
</script>
</body>
</html>
作用是改变函数运行时 this 的指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>click</button>
<script>
function hello(name) {
this.name = name;
console.log(this.name);
}
const obj = { name: "admin" };
//经典调用
hello("朱老师");
//bind()不会立即执行,只返回一个函数声明
let f = hello.bind(obj, "bind");
console.log(f);
f();
//call/apply立即执行
f = hello.call(obj, "call");
console.log(f);
// apply要求第二个参数必须是数组
f = hello.apply(obj, ["apply"]);
console.log(f);
//bind()用处
//动态改变this指向
document.querySelector("button").addEventListener(
"click",
function () {
console.log(this);
console.log(this.name);
}.bind({ name: "bind啊" })
);
</script>
</body>
</html>
set
,get
将方法伪造成一个属性get
用于访问 set
用于传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>访问器属性</title>
</head>
<body>
<script>
const product = {
data: [
{ name: "电脑", price: 5000, num: 5 },
{ name: "手机", price: 4000, num: 9 },
{ name: "相机", price: 5500, num: 1 },
],
getAmounts() {
return this.data.reduce((t, c) => (t += c.price * c.num), 0);
},
//将方法伪造成一个属性
get getprice() {
return this.data.reduce((t, c) => (t += c.price * c.num), 0);
},
//设置价格
set setprice(price) {
this.data[1].price = price;
},
};
//普通方式访问
console.log(product.getAmounts());
//访问器方法访问
console.log(product.getprice);
//设置价格
product.setprice = 200;
console.log(product.getprice);
//访问器优先级高于普通属性
let us = {
name: "朱老师",
get name() {
return "不是朱老师";
},
set name(value) {
this.name = value;
},
};
console.log(us.name);
//解决同名优先级问题
let us1 = {
data: { name: "朱老师" },
get name() {
return this.data.name;
},
set name(value) {
this.data.name = value;
},
};
us1.name = "000";
console.log(us1.name);
</script>
</body>
</html>
分支用于逻辑判断,让代码有了灵魂
if...else
常用区间判断
let score = 81;
//单分支
if (score >= 60) {
console.log("及格");
}
//双分支
if (score >= 60) {
console.log("及格 ");
} else {
console.log("不及格");
}
//多分支
score = 101;
if (score > 100 || score < 0) {
console.log("成绩不合法");
} else if (score >= 60 && score < 80) {
console.log("合格");
} else if (score >= 80 && score <= 100) {
console.log("优秀");
} else {
console.log("不及格");
}
switch
一般用于单值判断
score = 19;
//switch 来简化分支
//多值区间断送
switch (true) {
case score > 100 || score < 0:
console.log("成绩不合法");
break;
case score >= 60 && score < 80:
console.log("合格");
break;
case score >= 80 && score <= 100:
console.log("优秀");
break;
default:
console.log("不及格");
}
//switch 单值判断
let response = "success";
switch (response.toLowerCase()) {
case "fail":
console.log("请求失败");
break;
case "success":
console.log("请求成功");
break;
default:
console.log("未知错误 ");
}
条件 ? true : false
用于二分支运算三元运算简化了代码,但是只有用于二分支
// 语法:条件 ? true : false
console.log(score >= 60 ? "及格" : "不及格 ");
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>javascript分支</title>
</head>
<body>
<script>
let score = 81;
//单分支
if (score >= 60) {
console.log("及格");
}
//双分支
if (score >= 60) {
console.log("及格 ");
} else {
console.log("不及格");
}
//多分支
score = 101;
if (score > 100 || score < 0) {
console.log("成绩不合法");
} else if (score >= 60 && score < 80) {
console.log("合格");
} else if (score >= 80 && score <= 100) {
console.log("优秀");
} else {
console.log("不及格");
}
score = 19;
//switch 来简化分支
//多值区间断送
switch (true) {
case score > 100 || score < 0:
console.log("成绩不合法");
break;
case score >= 60 && score < 80:
console.log("合格");
break;
case score >= 80 && score <= 100:
console.log("优秀");
break;
default:
console.log("不及格");
}
//switch 单值判断
let response = "success";
switch (response.toLowerCase()) {
case "fail":
console.log("请求失败");
break;
case "success":
console.log("请求成功");
break;
default:
console.log("未知错误 ");
}
//三元运算
// 语法:条件 ? true : false
console.log(score >= 60 ? "及格" : "不及格 ");
</script>
</body>
</html>