模板字面量与标签函数
1. 模板字面量: 模版字符串
- 语法
在 JavaScript 中编写字符串时,通常使用 ( ‘ )或者 ( “ ),而模板字符串使用 (`)。
例如:const str3 =`hello world`;
- 字符串拼接
普通字符串拼接非常复杂,模版字符串可以简化拼接方式。直接使用 ${value} 嵌入表达式
例如:
直接可以打印出hello adminlet username = "admin";
let str = `Hello ${username}`;
换行
模板字符串还有一个很方便的功能是不再需要插入换行符 \n。let username = "admin";
let str = `Hello
${username}`;
在模板字符串中所有的换行、tab、空格等字符都是字符串的一部分。
使用场景:如在页面中大量html生成代码
let nav = ["首页", "教学视频", "文章"];
let html = `
<nav>
<a href="">${nav[0]}</a>
<a href="">${nav[1]}</a>
<a href="">${nav[2]}</a>
</nav>
`;
console.log(html);
document.body.insertAdjacentHTML("beforeend", html);
2. 标签函数: 自定义模板字面量的行为
标签函数的语法是函数名后面直接带一个模板字符串,并从模板字符串中的插值表达式中获取参数。
例如:
let hello = name => alert("Hello " + name);
//一般方式
// hello("co");
// 换一种方式来调用
// hello(`co`);
或者
// hello`co`;
// 其实这就是"标签函数"
- 参数的约定
第一个部分:模板字面中的原始字符串的内容组成的数组
第二个部分:插值组成的数组
例如:定义一个 greet 函数接收三个参数。
function greet(arg1, arg2, arg3){
console.log(arg1);
console.log(arg2);
console.log(arg3);
}
// 普通函数
greet(["I'm ", ". I'm ", " years old."], name, age);
//标签函数
greet`I'm ${name}. I'm ${age} years old.`、
- 当参数非常多时,可以通过…的方式将参数打包成数组
解构赋值与对象字面量的简化方式
解构赋值
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
传统方式和解构赋值对比
- 传统方式
将需要将一个数组中每个元素,分别创建一个变量来存储它let arr = [10, 20, 30];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log(a, b, c);
- 解构赋值
let [a, b, c] = [10, 20, 30];
console.log(a, b, c);
基本使用
常用的使用方式就是以字面量[]或者{}来获取 array或者 object的值
- 数组解构赋值
当数组内容过多时,可以用…打包[a, b, c, ...d] = [10, 20, 30, 40, 50, 60];
console.log(rest);
// expected output: Array [30,40,50]
- 对象解构赋值
({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
- 数据交换
传统方式在数据交换时需要使用中间变量,解构则不需要let a = 10,
b = 20;
[b, a] = [a, b];
console.log("a = %d, b = %d", a, b);//a=20,b=10
- 数组传参
参数的各式要和模版统一let sum = ([a, b]) => a + b;
console.log(sum([10, 20]));
只想传递独立参数的话,可以用归并参数spread解压缩
sum = (...[a, b]) => a + b;
console.log(sum(10, 20));
对象字面量的简化
关于this的使用
this指向当前对象,当对象名称发生变化时,可以不用修改对象中属性的内容.
例如:
let person = {
name: "jason",
email: "1234@qq.com",
getInfo: function () {
return `${this.name} : ( ${this.email} )`;
},
};
对象解构
let { name, email } = person;
console.log(name,email)
//jason 1234@qq.com
person 中的属性name,email 分别传给变量name,email
let user = {
name: name,
email: email,
getInfo: function () {
return `${this.name} : ( ${this.email} )`;
},
};
新的对象user中,属性name的值是jason,email的值是1234@qq.com
- 如何简化上述user的解构
- 对象字面量中的属性值,如果引用了相同作用域中的”同名变量”,则可以省去不写
2.可将方法后面的冒号和’function’删除user = {
name,
email,
getInfo: function () {
return `${this.name} : ( ${this.email} )`;
},
};
3.利用箭头函数user = {
name,
email,
getInfo () {
return `${this.name} : ( ${this.email} )`;
},
};
user = {
name,
email,
getInfo: () => `${this.name} : (${this.email})`,
},
};
js中按值传递和按引用传递
值传递
Q:变量a赋了某个值,变量b引用了变量a,此后我们修改了b的内容,却发现有时a的值也变了,有的时候却不变,这是什么原因?
- JavaScript影响引用传递结果的是值的类型。
JavaScript值有两大类型:基本类型与引用类型。基本类型包括数字、字符串、布尔、null、undefined。
引用类型包括对象数组和函数。基本类型值是简单的数据段,直接保存在内存中。
引用类型值是对象,可以添加、修改和删除属性或方法,但无法直接访问,需要通过内存地址访问。
1.当为变量引用基本类型的值时,实际上会拷贝一个值副本给新的变量,引用相同基本类型值的变量相互独立,
例如:
let x = 10;
let y = x;
x = 20;
console.log(x, y);
打印出x为20,y没有变还是10
2.而当为变量赋予引用类型的值时,拷贝的是内存地址,不同的变量指向的是同一个对象。因此当变量修改了某些属性时会改变其内存地址指向的对象:
let person = {
name: 'Jackson'
}
let man = person
man.name = 'blackstar'
console.log(person.name) // blackstar
let arr1 = [1,2,3]
let arr2 = arr1
arr2.push(4)
console.log(arr2) // [1,2,3,4]
console.log(arr1) // [1,2,3,4]
需要注意的是
修改变量会改变内存地址指向的对象,由此会影响所有引用同一地址的变量。但前提是修改对象属性,而不是重新赋值新的引用类型值
重新赋值改变了内存地址,指向了一个新的对象,从原本共同引用的对象中脱离开来,自立门户,自然也就不会影响其他变量了。
例如:
let person = {
name: 'Jackson'
}
let man = person
man = {
name: 'blackstar'
}
console.log(person.name) // Jackson
let arr1 = [1,2,3]
let arr2 = arr1
arr2 = [4,5,6]
console.log(arr2) // [4,5,6]
console.log(arr1) // [1,2,3]
总结:基本类型按值传递,引用类型按引用传递(容易相互影响)
函数参数也一样。