ES6
(1) ES6
ECMAScript6.0简称ES6,是JavaScript语言的下一代标准,已经在2015年6月正式发布了,它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,并成为企业级开发语言.
(2) let命令和const命令
- let命令
- let的用法类似于var,用于变量的声明
- 使用let就会产生块级作用域,let命令只在块级作用域内(也就是大括号内)有效
- let在同一作用域内只能声明一次,不能重复声明
- let和const不存在变量提升
if (1) {
var a = 2;
}
console.log(a);//2
//js没有作用域,变量声明会提前
if (0) {
var b = 3;
}
console.log(b);//undefined,不满足条件,b未赋但值,提前声明了
//es6有块级作用域,let声明变量不会提前,且不能重复声明同一个变量(let声明的变量是唯一的)
if(1) {
let c = 10;//声明为let的变量c只作用于{}里面
}
console.log(c);//报错,相对于es6来说,let声明的c已经被声明过,不能重复声明;相对于全局作用域来说,c没有被声明过
- const命令
- const用来声明常量,不能改变(不能重新赋值)
- const声明变量,如果变量是对象,不能重新赋值,但是可以修改属性值
const cat = {
name: '小花',
age: 1
}
obj.name = '小白'; //const可以改变对象中的属性值
console.log(obj.name);
//const 是常量,不能重新赋值
cat = {
name: '小黑',
age: 2
}
console.log(obj.name);
- var,let,const区别
var(声明变量的关键字):
- 变量提升,可以在声明的前面使用
- 同一作用域内可以多次声明同一个变量
- 能让它形成作用域的只有函数
let(声明变量的关键字):
- 没有变量提升,只能在声明之后使用
- 同一作用域内只能声明一次
- 声明的变量的作用域仅限于最近的花括号{}
const(声明常量的关键字):
- 使用const声明常量,一旦声明就不能改变
- 没有变量提升,只能声明之后使用
- 同一作用域内只能声明一次
- 声明的变量的作用域仅限于最近的花括号{}内
- 用const声明常量:不允许重新赋值,引用数据类型可以添加或修改属性
(3) 变量的解构赋值
解构: 解构分解,从一个整体的变量里分解出一部分来使用
- 数组解构
// 将数组解构, 使用x,y,z存放前三种水果
var list = ['苹果','香蕉','雪梨','火龙果','香瓜'];
let [a,b,c,d,e] = list;
console.log(a);
console.log(b);
console.log(c);
- 对象解构
// 将对象解构,获取username的值并打印
let person = {
username: '张三',
age: 100,
addr: '广东'
}
let {username} = person;
console.log(username);
- 函数参数解构和默认值
// 封装了get请求, 在函数里的形参里解构各个参数, 然后发送请求
// 若没有传入data, 则默认为{}
function get({url='地址未知',data={},callback}) {
// url = url?url:"地址未知";
// date = data || {};
console.log(url);
console.log(data);
}
get({url:'http://xxx/xxx', data: {page:1}, callback: function() {}});
- 判断一个对象是否为数组
- typeof: 对于一个数组或正则(由一个字符序列形成的搜索式模式)来说,typeof检测无法满足,因为两种方法不可行)
- instanceof,constructor: 在iframe元素跨平台的时候,这两种方法不可行
- Arrag.isArray: (IE8之前的版本是不支持的)这是最好的一个方法
//instanceof:instanceof可以判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上,所以用来检测某对象是否是数组可能更好不过了,直接通过看返回值true与false直接可以判断是否是数组。
console.log([] instanceof Array); //true
console.log({a:1} instanceof Array); //false
//constructor:同样 由于js中每一个对象都有一个constructor属性,它引用了初始化该对象的构造函数,比如判断未知对象的类型。
function isArray(obj){
return typeof obj == 'object' && obj.constructor ==Array
}
console.log(isArray([])); //true
var a = {"a":1};
console.log(isArray(a)); //false
var b = [1,2,3];
console.log(isArray(b)); //true
console.log(isArray(/\d+/g)); //false
//Array.isArray
var arr = [1,2,3];
var arr2 = [{ name : 'jack', age : 22 }];
console.log(Array.isArray(arr)); //true
console.log(Array.isArray(arr2)); //true
-
对象的扩展
属性和方法的简洁表示方法
变量名做属性名
合并对象
let attr1 = 'filmName';
let attr2 = 'price';
//1. 声明一个对象obj1, 并且att1和att2这个两个变量作为obj的属性, 对应的值随意
var obj1 = {
attr1,
attr2,
};
console.log(obj1);
// 2. 声明obj2, 它的值obj1
var obj2 = obj1;
// 3. 克隆obj1, 并把克隆后的对象赋给obj3
var obj3 = Object.assign({},obj1);
console.log(obj3);
// 4. 判断obj1和obj2是否相等, obj3和obj1是否相等
console.log(obj1 === obj2);//true
console.log(obj1 === obj3);//false
(4) 箭头函数
- 函数的常见表达式
//普通函数写法
function add(a, b) {
return a + b;
}
const add = (a, b) => {
return a + b;
};
add();
// 可以写成下面这样
const add = (a, b) => {
return a + b;
};
const add = (a, b) => a + b;
// 普通函数的写法
list.filter(function (item) {
return item > 3;
});
// 可以写成
list.filter((item) => item > 3);
-
箭头函数this指向
箭头函数不绑定this,但会捕获其所在上下文的this值作为自己的this值
箭头函数不能做构造函数,箭头函数的argument对象不可用
const obj = {
say() {
console.log('say中的this', this); // 指向obj
// setTimeout中普通函数的this
setTimeout(function () {
console.log('setTimeout的this', this);
}, 1000);
// setTimeout中箭头函数的this
setTimeout(() => {
console.log('箭头的this', this);
}, 1000);
}
}
obj.say();
const Cat = (name, age) => {
this.name = "name";
this.age = age;
};
var cat = new Cat("小花", 2);
console.log(cat);
function add() {
console.log(arguments);
// arguments可以想数组一样访问成员, 但不是真正的数组, 是个伪数组
console.log(arguments[0]);
console.log(arguments.map);
}
add(1, 2, 3);
<script>
// 会报错, 箭头函数没有arguments对象
const add = () => {
console.log(arguments);
};
add(1, 2, 3);
(5) 数组的扩展
- Array.from() 将伪数组变成真数组
- find() 找到了就返回符合条件的成员,找不到就返回undefined
- findIndex() 找到了就返回符合条件的成员的下标,找不到就返回undefined
- includes() 判断数组是否包含某个成员,只能对数组成员是基本数据类型的数组使用
- some() 判断数组是否包含某个成员
- keys() 遍历键
- values() 遍历值
- entries() 遍历键值对
(6) 扩展运算符
- 在对象中使用
- 在数组中使用
- 在函数中使用
//合并对象
let obj1 = {a:2,b:3,c:4};
let obj2 = {a:10,b:20,x:4};
let obj = {
...obj1,
...obj2
};
console.log(obj); //{ a: 10, b: 20, c: 4, x: 4 }
//克隆对象,并给新对象添加新的属性
let obj4 = {
...obj1,
a:3, //可以覆盖a
x:11,
y:10
}
console.log(obj4); //{ a: 3, b: 3, c: 4, x: 11, y: 10 }
let list = [
{
name: 'zs'
},
{
name: 'lisi'
}
];
let newList = list.map(item=>{
return{
...item,
age:0
}
});
console.log(newList); //[ { name: 'zs', age: 0 }, { name: 'lisi', age: 0 } ]
//合并两个数组
let arr1 = [1,2,3];
let arr2 = [3,4,5];
let arr = [
...arr1,
arr2
];
console.log(arr); //[ 1, 2, 3, [ 3, 4, 5 ] ]
//在函数中使用
let say = (a,b,...c)=>{
console.log(a); //2
console.log(b); //1
console.log(c); //[ 3, 4, 8 ]
}
say(2,1,3,4,8);
(7) promise
- promise的三种状态:pending(正在进行中),resolved(成功),rejected(失败)
- 使用步骤:
- 创建promise对象
- 存储成功或失败的数据
- 获取promise对象的数据
- 用途:用于解决地狱回调的问题(方法:async await)
//创建一个promis对象的实例
var promise = new Promise(resolve,reject)=>{
//判断成功或失败的逻辑
let isLogin = false;
if(isLogin){
resolve('登录成功');
}else{
reject('登录失败');
}
}
//获取promise对象里存放的数据
promise.then(res=>{
console.log('res',res);
}).catch(err=>{
console.log('err',err);
})
//封装ajax请求
const utils = {
get(url,data = {}){
return new Promise((resolve,reject)={
var xhr = new XMLHttpRequest();
var paramStr = this.toParams(data);
xhr.open('get',`${url}?${paramStr}`);
xhr.send();
xhr.onresdystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200)
}
}
})
}
}