let 和 const
var
- 没有块级作用域
- 变量的预处理和作用域的提升
- 可以定义重名的变量
let
- 存在块级作用域
- 不能重名
- 不会预处理
const
- 用来声明常量,不能被重新赋值
- 在声明的同时必须赋值
for(var i = 0; i < 5; i++){
console.log(i)
}
for(var i = 0; i < 5; i++){
(function(index){
setTimeout(function(){
console.log(index)
})
})(i)
}
for(let i = 0; i < 5; i++){
console.log(i)
}
变量的解构赋值
对象解构赋值
let p = {
name: 'tom',
phone: 123,
age: 18
}
// 对象解构赋值
let {name, phone, age} = p;
console.log(name,phone,age)
// 解构赋值应用场景
let data = {
code: 8,
count: 20,
name: 'tom',
state: "1"
};
function callBack({name, code}){
console.log(name, code);
}
callBack(data);
数组解构赋值
let arr = [1, 2, 3, 'a', 'b',];
let [v, x, y, z] = arr;
console.log(v, x, y, z); 1 2 3
let [,,h,j] = arr;
console.log(h,j) 3 'a'
// 使用场景 给函数添加可变的多个返回值,根据需求去获取指定返回值。
function test(){
return ['hello', 'world'];
}
let [res1] = test();
console.log(res1)
模版字符串
作用
简化字符串拼接
用法
- 使用``号包含内容
- 使用${}占位符来引用变量
使用场景
// 使用get方式提交参数
// url?username=''&phone=123
let user = {
username: 'tom',
pwd: 123,
phone: 13222222222,
}
let str = `localhost:8080?username=${user.username}&pwd=${user.pwd}&phone=${user.phone}`
console.log(str)
let menu = {
id: 0,
name: '测试',
url: '111.html',
state: 'normal'
}
let html = `<a id="${menu.id}" href="${menu.url}">${menu.name}</a>`
console.log(html)
数组的扩展
三点运算符
- 三点运算符: rest参数,将一个数组转化为逗号分隔的字符串
- 三点运算: 把数组转换成一个用逗号连接的序列
三点运算符使用场景
// 作用一: 合并数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr = [...arr1, ...arr2];
console.log(arr)
// 作用一: 数组插入
let arr3 = [1, 2, ...arr2];
console.log(arr3)
静态方法
- Array.from() 将伪数组变为整数组
常见伪数组:html元素(document.querySelectorAll('div')),arguments
- Array.of() 将多个元素组合成数组
let arr = Array.of(1,2,3);
console.log(arr);
- Array.prototype.copyWithin(target, start, end)
- Array.prototype.find()查找符合条件的第一个元素,否则返回undefined
- Array.prototype.findIndex()查找符合条件的第一个元素的索引,否则返回-1
- Array.prototype.fill(value, start, end)数据填充
- Array.prototype.entries() keys() values()
let res = ['a', 'b', 'c', 'd', 'e', 'f'];
for(let [index, value] of res.entries()){
console.log(index, value)
}
for(let value of res.values()){
console.log(value)
}
for(let index of res.keys()){
console.oog(index)
}
- Array.prototype.includes() 数组是否包含某个元素 true/false
NaN == NaN //false
includes()方法可以识别NaN
数值的扩展
- 新增二进制八进制表示方法
- Number.isFinite() 判断一个数字是否有限
- Number.isNaN() 判断一个值是否是NaN
- Number.isInterger() 判断一个数字是否是整数
- Number.EPSILON 2的-52次方 表示js中最小的数
- Math.trunc() 去除小数部分
- Math.sign() 判断一个数字是否为正数 正数返回1 负数返回-1 0返回0 NaN返回NaN
- Math.cbrt() 求一个数的立方根
- 指数运算符
console.log(10 ** 2) 100
console.log(2 ** 3 ** 2) 512
函数的扩展
三点运算符实现reset可变参数
function addAll(...args){
let res = 0;
args.forEach(function(item){
res += item;
})
console.log(res);
}
addAll(1, 2, 3, 4);
// 根据形参的第一个值,将不定格式的参数传入函数
// 注意:三点运算的reset可变参数,必须是最后一个形式参数
function saveData(code, ...args){
let arr1 = [];
let arr2 = [];
if(code === 1){
arr1 = [...args];
} else {
arr2 = [...args];
}
console.log(arr1, arr2)
}
saveData(1, 'a', 'b', 'c', 'd');
函数参数默认值
- 当调用函数时,没有传入对应的实际参数,可以设定该参数的默认值
function sayHello(name, sex = 'm'){
if(sex == 'm') {
console.log('男')
} else {
console.log('女')
}
}
sayHello('tom')
console.log(sayHello.length) 没有默认值的形式参数个数
name属性
- 方法的name 属性会返回变量名
function test1(){
}
let test2 = function(){}
console.log(test1.name);
console.log(test2.name);
箭头函数
//格式1
let fun1 = (a, b) => {console.log(a, b)};
fun1('a', 'b')
// 格式2 当形式参数只有一个的时候, 小括号可以省略
let fun2 = a => {console.log(a)};
fun1('a')
// 格式3 当方法体只有一句代码的时候,大括号可以省略
// 并且系统会将这一句的运算结果return出来
let fun3 = a => a + 3;
console.log(fun3(5))
使用场景
// 回调函数
setTimeout(function(){
console.log(a)
}, 1000)
setTimeout(() => {
console.log('a')
}, 1000);
箭头函数没有自己的this this指向它声明所处的环境
对象的扩展
let name = 'tom';
let age = '15';
let person_es5 = {
name: name,
age: age,
intro: function(){
console.log('es5')
}
};
let person_es6 = {
name,
age,
intro(){
console.log('es6')
}
};
console.log('person_es5',person_es5);
console.log('person_es6',person_es6)
扩展运算度 ...
super关键
新增方法
- Object.is(obj1 obj2) 相当于===
- Object.assign() 浅拷贝
- Object.entries() keys() values()
Set Map
let mSet = new Set();
// 增加
mSet.add('tom');
// 删除
mSet.delete('tom')
// 不可重复添加数据
// 查询是否包含某个值
mSet.has('tom');
// 清空
mSet.clear();
// 长度后面不要加括号
mSet.size
// 作用
let str = 'hello world';
let new = new Set(str);
console.log(new)
//map 实例化
// map 实例化并存入数据时使用的是二维数组
// 其中的一维只需要两个元素
let mMap = new Map([['张小慧','13'],['shasha', 12],['ceshi', 12]]);
console.log(mMap)
// 添加元素
mMap.set('eva', 4);
console.log()
// 存入的key 一样的时候,value 会被覆盖
// 获取数据
mMap.get('eva');
// 删除数据
mMap.delete('eva')
// 是否存在
mMap.has('eva');
// 清空
mMap.clear();
// 获取长度size
mMap.size
symbol
- symbol是一个数据类型。表示一个不会重复的值,不是函数,不能通过new调用。
- Symbol.for() Symbol.keyFor()
- 作用: 1.定义不会重名的属性 2.定义常量 3.内置symbol值
- Symbol定义的属性不会被for in for of所遍历.需要使用reflect来遍历获取全部的属性。
Iterator 接口机制
- 可以对不同的数据结构使用统一的遍历方法。
- 只要一个对象部署了iterator接口,这个对象就可以用for...of遍历。
- 可以用for...of遍历的对象:当一个对象中有Symbol.iterator这个方法的时候。
let arr = [1, 3, 5];
for(let value of arr){
console.log(value)
}
let mySet = new Set(arr)
for(let value of arr){
console.log(mySet)
}
let obj = {
name: '1234',
age: 11
}
for(let item of obj){
console.log(item) // 报错
}
//先获取数组中的迭代器
let arr = [1, 3, 5]
// 调用容器的Symbol.iterator方法,并调用获取容器的迭代器对象
// 会产生一个指针 指向容器的第一个值
let ite = arr[Symbol.iterator]();
// 每次调用迭代器的next方法时,都会返回容器中下一个值和是否遍历结束done: false 结束了 done:true
console.log(ite.next())
console.log(ite.next());
console.log(ite.next());
Proxy Reflect
let person = {
name: "tom",
age: 16
}
// 参数一: 操作对象 参数二: handler{}
let personProxy = new Proxy(person, {
// 代理目标对象的取值操作
get: function(target, key){
// 重要 这里面可以对key目标访问做一些拦截
console.log(`petson的${key}属性被读取了`)
return target[key];
},
set: function(target, key, value){
console.log(`person的${key}属性被修改了`)
target[key] = value;
return true
}
})
// 通过代理对象 来操作代理对象
console.log(personProxy.name); // 先调用proxy中的handler的get方法
Promise
let pro = new Promise((resolve, reject) => {
// ajax 异步调用
setTimeout(function(){
if("请求正确"){
resolve()
} else {
reject()
}
}(1000))
})
// 调用promise 的then方法
// 第一个参数 异步请求执行了resolve方法后的回调函数
//第二 个参数 异步请求执行了reject方法后的回调函数
pro.then(
() => {
console.log('请求顺利完成')
},
() => {
console.log('请求未能顺利完成')
}
)