参考:
https://www.bilibili.com/video/BV1uK411H7on
https://www.bilibili.com/video/BV1GA411x7z1
https://juejin.cn/post/6940945178899251230#heading-24
var let const
var未执行赋值语句前是undefined
let const 未执行赋值语句前打印提示
Cannot access 'x' before initialization(翻译:不能再初始化前访问x)
var声明的变量会添加到window上,node里会添加到global上
暂时性死区: 在使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,
称为暂时性死区。使用var声明的变量不存在暂时性死区。
指针指向:let创建的变量是可以更改指针指向(可以重新赋值)。
但const声明的变量是不允许改变指针的指向。
var let const 区别:
答:
1.let const不存在变量提升,不会添加为全局属性,不能重复声明,var这三点都可以
2.let const有块级作用域
3.let const 声明变量之前,该变量都是不可用的
4.const 必须有初始值
5.const 声明后地址就不能改变
const对象的属性可以修改吗
const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。
对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。
如果new一个箭头函数的会怎么样?
箭头函数是ES6中的提出来的,它没有prototype,也没有自己的this指向,更不可以使用arguments参数,所以不能New一个箭头函数。
new操作符的实现步骤如下:
1.创建一个对象
2.将构造函数的作用域赋给新对象(也就是将对象的__proto__属性指向构造函数的prototype属性)
3.指向构造函数中的代码,构造函数中的this指向该对象(也就是为这个对象添加属性和方法)
4.返回新的对象
所以,上面的第二、三步,箭头函数都是没有办法执行的。
箭头函数与普通函数区别
答:
1.箭头函数的this永远指向函数声明时所在作用域下this的值,不像普通函数的this值可以用call、apply、bind改变
2.箭头函数不能使用arguments参数
3.箭头函数没有prototype,所以它不能作为构造函数实例化对象
箭头函数特点:
//1.this永远指向函数声明时所在作用域下this的值,
//更准确的说是没有自己的this,会捕获所在上下文中的this,且永远不变
//call()、apply()、bind()等方法不能改变箭头函数中this的指向
name='快乐星球';
const xingqiu={
name:"kuailexingqiu"
}
let getName=function(){
console.log(this.name);
}
let getName2=()=>{
console.log(this.name);
}
getName(); //快乐星球
getName2(); //快乐星球
getName.call(xingqiu); //kuailexingqiu
getName2.call(xingqiu);//快乐星球
//2.箭头函数不能作为构造函数 实例化对象
//3.箭头函数不能使用arguments
//4.箭头函数没有prototype
//5.箭头函数的简写
//(1)当形参有且只有一个的时候可以省略小括号
let add=n=>{
return n+n;
}
console.log(add(6));//12
//(2)省略花括号,当代码体只有一条语句的时候,省略花括号,语句执行结果就是函数返回值
let pow=n=>n*n;
console.log(pow(8)); //64
模板字符串
//内容可以出现换行符号,之前使用''需要用+拼接
let a=`<ul>
<li>沈腾</li>
<li>玛丽</li>
</ul>`;
//3.变量拼接,之前使用''需要用+拼接
let lovest='艾伦';
let out=`${
lovest}是我心目中最搞笑的演员`
扩展运算符
//1.对象的扩展运算符
//(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
let bar = {
a: 1, b: 2 };
let baz = {
...bar }; // { a: 1, b: 2 }
//等价于
let baz = Object.assign({
}, bar); // { a: 1, b: 2 }
//同名的情况下后面会覆盖前面
let bar = {
a: 1, b: 2};
let baz = {
...bar, ...{
a:2, b: 4}}; // {a: 2, b: 4}
//2.数组扩展运算符
//...能将数组转化为逗号分隔的参数序列,每次只能展开一层数组
console.log(...[1, [2, 3, 4], 5]) // 1 [2, 3, 4] 5
//2.1将数组转化为参数序列
function add(x, y) {
return x + y;
}
const numbers = [1, 2];
add(...numbers) // 3
//2.2数组克隆/数组合并
const arr1 = [1, 2];
const arr2 = [...arr1];
const arr3=[0,...arr1,...arr2,3,4 ];//[0,1,2,1,2,3,4]
//2.3扩展运算符与解构赋值结合起来,用于生成数组
const [first, ...rest] = [1, 2, 3];//first: 1 rest: [2, 3, 4, 5]
//tip:扩展运算符用于数组赋值,只能放在参数的 最后 一位,否则会报错。
const [...rest, last] = [1, 2, 3, 4, 5]; //报错
//3.将字符串转化为数组
[...'hello'] // [ "h", "e", "l", "l", "o" ]
//4.将伪数组转化为数组
const divs=document.querySelectorAll('div');
console.log(divs); //NodeList(3)
const divArr=[...divs];
console.log(divArr);//Array(3)
function foo() {
const args = [...arguments];//将arguments转化为真数组
}
变量的解构赋值
//1.数组的变量的解构赋值
const F4=['小沈阳','刘能','赵四','宋小宝'];
let [xiao,liu,zhao,song]=F4;
console.log(xiao); //小沈阳
//也可以通过中间空位的方式来赋值
const [a,,c] = [1,2,3] // a:1 c:3
//2.对象的变量的解构赋值
console.log("---------对象的解构")
const zhaoben={
name:'赵本山',
xiaopin:function(){
console.log("我可以演小品");
}
};
//使用{XXX,XXX}的方式来获解构赋值
let{
name,xiaopin}=zhaoben;
console.log(name); //赵本山
//可以直接调用函数,zhaoben.xiaopin()等效于xiaopin()
xiaopin(); //我可以演小品
//3.通过解构赋值拿到高度嵌套的对象里的属性
const school = {
classes: {
stu: {
name: 'Bob',
age: 24,
}
}
}
//通过 :xxx{}的嵌套来拿 xxx必须与原来的一致
const {
classes: {
stu: {
name } }} = school,
console.log(name) //Bob
函数参数的默认值
//ES6允许给函数参数赋值初始值
//1.形参初始值
let add=(a,b,c=10)=>a+b+c;
let result=add(1,2);
console.log(result);
//2.与解构赋值相结合
function connect({
host="127.0.0.1",username,password,port}){
//解构,同上文{xxx,XXX}=obj的形式
//使用解构赋值,就不需要host:host;直接可以使用变量
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
let obj={
// host:'home',
username:'root',
password:'root',
port:3306
}
connect(obj);
对象的简化写法
//ES6里,允许在大括号里,直接写入变量和函数,作为对象的属性和方法
let name='快乐大本营';
let change=function(){
console.log("我们可以给你带来快乐");
}
const team={
//等效于name:name,change:change,
name,
change,
//等效于improve:function(){ console.log("可以给你带来快乐")}
improve(){
console.log("可以给你带来快乐")
}
}
console.log(team); //Object{name:'快乐大本营',change:f,improve:f}
rest参数
//ES6引入rest参数,用于获取函数的实参,用于代替arguments
//ES5,arguments是一个伪数组
function date(){
console.log(arguments);
//Arguments(2) ["白芷", "阿娇",callee:f...]
}
date('白芷','阿娇');
//ES6,结果是一个数组
function date1(...args){
console.log(args); //['白芷','阿娇']
}
date1('白芷','阿娇');
//rest参数必须放到参数的最后,这种方式可以将多余的参数存到数组里
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6)
Set和Map
参考:https://es6.ruanyifeng.com/#docs/set-map
//3.Map: Object 提供了“字符串—值”的对应,Map 提供了“值—值”的对应,是一种更完善的 Hash 结构
//3.1基本使用
const m = new Map();