一、js值传递
js的值传递方式有2种,分别是赋值传递
、引用传递
。
1、赋值传递:
变量赋值,赋值后数据被更新,实现基本数据类型的传递,基本数据类型:string,number,boolean,null,undefined,symbol 。
let a = 1;
let b = a;
// 值传递,只在基本类型之间存在,数值,字符串。。。
console.log("a = %d, b = %d", a, b);
// 更新 a
a = 2;
console.log("a = %d, b = %d", a, b);
2、引用传递:
适用于引用类型:对象,数组。引用本身不会被修改,但其属性值可以被修改且只能通过属性修改。
let obj1 = {
a: 1,
b: 2,
};
console.log("obj1 = %o", obj1);
let obj2 = obj1;
console.log("obj2 = %o", obj2);
console.log(obj1 === obj2);
// 更新obj1
// 对象使用点语法来访问内部的成员
obj1.a = 10;
console.log("obj1 = %o", obj1);
console.log("obj2 = %o", obj2);
//传参: 永远是值传递
const f1 = (x) => (x = 10);
let m = 5;
// m: 入参
// 当前传入的是一个基本类型,原始类型,整数
f1(m);
console.log(f1(m));
console.log("m = %d", m);
// const f2 = (x) => (x.a = 10);
const f2 = (x) => (x = {});
let o = { a: 1, b: 2 };
f2(o);
console.log("o.a = ", o.a);
// 深拷贝: 值传递
// 浅拷贝: 引用传递
二、模板字面量及标签函数
1、模板字面量:
模板字面量常用特性支持字符串、插值,可以在一个连续定义中插入一个或多个变量的值。
// 1. 模板字面量: 将表达式/插值嵌入到字符串
// 0 1 2
let menus = ["首页", "视频", "文章"];
let htmlStr = `
<nav>
<a href="">${menus[0]}</a>
<a href="">${menus[1]}</a>
<a href="">${menus[2]}</a>
</nav>
`;
// 模板字面量内部有二部分组成: 字符串字面量, 变量插值
// <nav>
// <a href=""> </a></nav> //字符串字面量
// ${menus} //变量插值
console.log(htmlStr);
document.body.insertAdjacentHTML("beforeEnd", htmlStr);
2、标签函数:
标签函数本身就是一个常规函数,通过前缀到模板字面量来应用自定义行为。标签函数接受的参数依次时原始字符串数组和对每个表达式求值的结果,这个函数的返回值是对模板字面量求值得到的字符串。
// 2. 标签函数,自定义模板字面量的一些行为
// 参数约定
// 1. 第一个参数: 所有字符串字面量组成的数组
// 2. 第二个参数: 插值组成的数组
let sum = (strs, a, b) => {
console.log(strs);
console.log(a, b);
};
let a = 45;
b = 28;
sum`${a} + ${b} = `;
// rest: 归并参数
sum = (strs, ...args) => {
console.log(strs);
console.log(args);
};
let c = 38;
sum`${a} + ${b} + ${c} = `;
三、参数解构
解构赋值提供了一个方便的地从对象或数组中提取数据的方法,分数组解构
,对象解构
,参数解构
。
1、数组解构:
// 1. 数组解构
// 等号左边是右边的模板,必须长得一样
let [a, b, c] = [1, 2, 3];
console.log(a, b, c); //返回1 2 3
[a, b] = [1, 2, 3];
console.log(a, b); //返回1 2
[a, b, c = "js"] = [1, 2];
console.log(a, b, c); //反馈1 2 “js”
[a, b, ...c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, ...c); //返回1 2 3 4 5 6
[, , , a, ,] = [1, 2, 3, 4, 5, 6];
console.log(a); //返回 4
let x = 1,
y = 2,
t;
console.log(x, y);
t = x;
x = y;
y = t;
console.log(x, y);
let a = 10,
b = 20;
console.log("a = %d, b = %d", a, b);
[b, a] = [a, b];
console.log("a = %d, b = %d", a, b);
2、对象解构:
对象解构是获取对象并将其内部属性提取到对象外部变量的一种方法。
// 2. 对象解构
// 等号左边是右边的模板,必须长得一样
let item = { id: 10, name: "手机" };
let id = item.id;
let name = item.name;
console.log("id = %d, name = %s", id, name);
// {id,name} = { id: 10, name: "手机" }
({ id, name } = { id: 40, name: "电脑" });
console.log("id = %d, name = %s", id, name);
3、传参解构:
// 数组传参
let sum = ([a, b]) => a + b;
console.log(sum([30, 50]));
// 对象传参
let getUser = ({ name, email }) => [name, email];
console.log(getUser({ name: "小马", email: "admin@qq.com" }));
四、访问器属性
访问器属性不包含数据值,包含一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的。
// 对象成员: 属性, 方法
// 属性: 类似于变量
// 方法: 类似于函数
const product = {
// 属性
data: [
{ id: 1, name: "电脑", price: 5000, num: 5 },
{ id: 2, name: "手机", price: 4000, num: 15 },
{ id: 3, name: "相机", price: 1400, num: 10 },
],
// 计算总金额
// 方法
// es6的方法的简化,将冒号和function可以删除
getAmounts() {
return this.data.reduce((t, c) => (t += c.price * c.num), 0);
},
// 访问器属性: 将一个方法伪装/包装成一个属性
// get: 是读取,也叫读操作
get total() {
return this.data.reduce((t, c) => (t += c.price * c.num), 0);
},
// set: 访问器属性的写操作
set setPrice(price) {
this.data[1].price = price;
},
};
console.log("总金额 = %d 元 ", product.getAmounts());
// 不想用方法,想以属性的方式来获取总金额
console.log("总金额 = %d 元 ", product.total);
console.log(product.data[1].price);
product.setPrice = 8000;
console.log(product.data[1].price);