这篇文章我会在持续学习中不断更新,并给出每个具体语法demo的验证结果
一、ES6++
什么是ECMA
中文名称是欧洲计算机制造商协会,这个组织的目的是评估,开发和认可电信和计算机标准。1994年后该组织改名为ECMA国际
什么是ECMAscript
ECMAscript是由ECMA 国际通过ECMA-262标准化的脚本程序设计语言
1、ES6
1.1 let变量声明以及声明特性
//变量不能重复声明
let star = 'zll';
let star = 'wxl';//此时会报错
//块级作用域有效 全局、函数、ecal
{
//if for else while
let str='zzl';
}
console.log(str);//此时会报错,因为拿不到
// 不存在变量提升
console.log(name);//会报错,不能使用name这个变量
let name='zzl';
//不影响作用域链
{
let name='zzl';//虽然是块级作用域,但是不影响作用域链的效果
function fn(){
console.log(name);
}
fn();//可以拿到
}
1.1.1 let const和var的区别?
// var 存在变量提升(在声明语句代码之前可以使用,不会报错) let const 存在暂时性死区(声明之后在声明语句后面代码才可以用)
console.log(a) console..log(a) 报错 console.log(a) 报错
var a = 10 let a = 10 const a = 10
// vat 声明的变量可以重复声明 let const声明的变量不能重复声明
var a = 10 let a = 10 const a = 10
var a = 20 let a = 20 报错 const a = 14 报错
// var 没有块级作用域 let const 有块级作用域(例如:在while for 循环中)
for(var i = 0;i<10;i++){
} for(let i = 0;i<10;i++){
}
i泄漏为全局变量,存在于全局变量中 i有块级作用域
// var let 是声明变量,变量值可以改变 cosnt 声明常量,值不能改(准确来说,内存地址不能变),而且声明时必须赋值
1.2 const 声明常量以及特点
1,const声明常量
2,一定要赋初始值
3,常量的值不能再修改
4,也是块级作用域,
5,声明常量
const CL='zzl';
// 对于数组和对象的元素修改,不算2中的常量修改,不会报错
const SZ=['zzl','wxl'];
SZ.push('ll');//此时不会报错,因为只是修改数据,并没有修改地址
1.3 变量的解构赋值
//数组解构赋值
const nameS=['zzl','wxl','ll'];
let [name1,name2,name3]=nameS;
console.log(name1);//输出zzl
//对象的结构赋值
const data={
name:'zzl',
age:'22',
active:function(){
console.log('我会飞');
}
}
let {name,age,active}=data;
console.log(name); // 输出zzl
active(); // 调用方法,输出我会飞
let {active} = data;
active();
1.4 模板字符串
let str=`字符串`
// 它可以支持换行
// 变量拼接
let name='zzl';
let data=`${
name}是个人` // 'zzl是个人'
1.5 对象简化写法
// es6允许在大括号里面直接写入变量名和函数名,作为对象的属性和方法
let name='zzl';
let fun=function(){
console.log('我是人');
}
const data={
name, //可以直接写变量名,不用再写值了
fun
}
console.log(data); // 结果输出 name:'zzl',fun()
const data={
// 旧的方法定义
// act:function(){
// console.log('我会动');
// }
//新的方法定义
act(){
console.log('我会动');
}
}
1.6 箭头函数以及声明特点
// 声明一个函数
let fn=function(a,b){
}
// 箭头函数声明一个函数
let fn=(a,b)=>{
}
fn(1,2);
1.6.1 特点
// 箭头函数的额this是静态的,this始终指向函数声明时所在作用域下的this的值
function getname(){
//name是zzl,直接调用的话this值指向window
}
console.log(this.name);//zzl
let getname2=()=>{
//而这个箭头函数是在全局作用域下声明的,所以this也是指向window
console.log(this.name);//zzl
}
window.name='zzl';
const data={
name:'wxl'
}
//直接调用
getname();//name是zzl,直接调用的话this值指向window
getname2();//而箭头函数是在全局作用域下声明的,所以this也是指向window
// call方法调用
getname.call(data);//此时普通函数this的值已经变为data了。
getname2.call(data);
//输出wxl,因为它的this依然指向函数getname2声明时所在作用域下的this的值window.name='zzl';
////////////////////////////////////////////////////////////////////////////////
// 不能作为构造实例化对象
let Person=(name,age)=>{
this.name=name;
this.age=age;
}
let me=new Person('zzl','22');//此时会报错,箭头函数不能作为实例化对象。
////////////////////////////////////////////////////////////////////////////////
//不能使用arguments变量
// arguments:用来保存实参的
let fn=()=>{
console.log(arguments);
}
fn(1,2,3);//会报错,不用用来保存实参
1.6.2 简写箭头函数
// 省略小括号
let add=(n)=>{
return n+n;
}
console.log(add(9));
//简写为下面----------
//当形参有且只有一个的时候,可以省略小括号
let add=n=>{
return n+n;
}
console.log(add(9));
////////////////////////////////////////////////////////////////////////////////
//省略花括号
//当代码体只有一条语句的时候
let sum=(n)=>{
return n*n;
};
console.log(sum(9));
//简写为下面----------
//当代码体只有一条语句的时候,此时return必须省略,而且语句的执行结果就是函数的返回值
let sum=(n)=>n*n;
console.log(sum(9));
//小括号和花括号同时省略----------
let sum=n=>n*n;
console.log(sum(9));
1.6.3 箭头函数注意事项
// 箭头函数适合与this无关的回调,比如定时器,数组的方法回调。
// 箭头函数不适合与this有关的回调,比如DOM元素的事件回调、对象的方法。
btn.addEventListener("click",function(){
//此时普通函数的this指向事件缘
//如果使用箭头函数,事件源将变成外部作用域的this值,即这个函数所在的作用域
})
1.6.4 箭头函数中的this
// 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
function Person() {
this.age = 0;
setInterval(function growUp() {
this.age++; // 定时器中使用普通函数,this永远指向window,因为是window调用定时器 所以this.age 值得是Nan
}, 1000);
}
var p = new Person();
// '------------------------------------'
function Person() {
this.age = 0
setInterval(()=> { // 箭头函数没有自己this,只能往上一层去找
console.log(this) // Person对象
this.age++;
console.log(this.age)
}, 1000);
}
var p = new Person();
1.6.5 笔试题
var myObject = {
foo: "bar",
func: function () {
var self = this; // self = myObject
console.log(this.foo); // 'bar'
console.log(self.foo); // 'bar'
(function () {
console.log(this.foo); // undefined // 立即执行函数里面this永远指向window
console.log(self.foo); // 'bar'
}());
}
};
myObject.func();
// ----------------------------------------------------------------------------
function plugin () {
this.a = 1
this.b = {
x: 1,
confirm: function(title, callback) {
this.title = title
console.log(this, '2')
callback()
}
}
console.log(this, '1')
}
var obj = new plugin()
obj.b.confirm('弹窗', () => {
console.log(this, '3')
})
1.6.6 箭头函数与普通函数的区别?
1,this 的指向问题
// 箭头函数没有自己的作用域,所以没有自己的this,箭头函数中的this指向箭头函数当前函数声明时的作用域链的上一层
// 普通函数有自己的作用域
2,call() 和apply()
// 箭头函数里this的指向不受call,apply的指向,只跟定义位置作用域链的上一层有关,而普通函数可以
3,箭头函数不能当构造函数,而且没有Prototype属性,而普通函数可以
4,箭头函数没有arguments对象,普通函数有arguments对象,箭头函数中的参数可以用...参数名称来获取剩余参数
5,箭头函数不能作为generator函数,普通函数可以
1.6.7 箭头函数的this的指向?
// 箭头函数里的this指向沿着其作用域链往上找
代码的执行结果是什么?
1.7 函数参数初始值
function add(a,b,c=10){
}
//函数参数初始值与结构赋值结合使用
function data({
name,age='22'}){
console.log(name);
console.log(age);
}
data({
name='zzl',
// age='23'
})
1.7.1 rest参数
// 用于获取函数的实参,可以代替arguments。
function data(){
console.log(arguments); // 输出的是一个对象
}
data('zzl','wxl');
// rest参数
function data(...args){
console.log(args); //输出的是一个数组,可以使用filter some...
}
data('zzl','wxl');
// --------------------------------------------------------------
// rest参数必须放在参数最后。
function data(a,b,...args){
console.log(a);//1
console.log(b);//2
console.log(args);// [3,4,5]
}
data(1,2,3,4,5)
// --------------------------------------------------------------------------------------
const obj1={
q:'zzl'
}
const obj2={
s:'wxl'
}
const data={
...obj1,...obj2}; //相当于合并了两个对象
console.log(data); // {q:'zzl',s:'wxl'}
1.8 扩展运算符
// 它能将数组转换为逗号分隔的参数序列
const names=['zzl','wxl','ll'];
function data(){
console.log(arguments);
}
//不用扩展运算符
data(names); // 只输出一个结果,是一个数组
// 用扩展运算符
data(...names); // 输出3个结果,等价于:data('zzl','wxl','ll'),即参数序列
// --------------------------------------------------------
// 如果数组里面有引用类型的话,扩展呢运算符也只是浅拷贝。
// 可以用来数组的合并
// 数组的克隆
// 伪数组转为真正的数组
// 数组的合并
const a=['zzl'];
const b=['wxl'];
const c=[...a,...b]; // c=['zzl','wxl']
//将伪数组转为真正的数组
const divs=document.querySelectorAll('div'); // 得到伪数组
const divdata=[...divs]; // 转为真正的数组
1.8 symbol
// 它一种新的数据类型,表示独一无二的值,类似于字符串的数据类型。
// 它的值是唯一的,用来解决命名冲突的问题。
// 它的值不能于其他数据进行运算。
// 它定义的对象属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。
// 创建symbol
let s = Symbol();
// 下面的两个symbol对象时不一样的
let s2 = Symbol('aini')
let s3 = Symbol('sini')
// symbol.for创建
let s4 = Symbol.for('aini')
let s5 = Symbol.for('aini')
let game={
//假如有很多代码很多变量名
}
//声明一个对象
let data={
//Symbol保证了up和down的属性名是独一无二的,
// 所以添加进去也不怕也不怕有属性名冲突
up:Symbol(),
//up属性的数据类型为Symbol
down:Symbol()
};
//第一种添加方式
//把这个Symbol添加到game方法中
game[data.up]=function(){
console.log('我会飞'); //安全的向这个对象中添加了两个方法
}
game[data.down]=function(){
console.log('我会爬');
}
console.log(game);
//////////////////////////////////////
//第二种添加方式
let play={
name='run',
[Symbol('say')]:function(){
console.log('我会说话');
},
[Symbol('sleep')]:function(){
console.log('我会睡觉');
}
}
console.log(paly);
//补充代码
const title1 = Symbol("title")
const title2 = Symbol("title")
const info={
[title1]:'zzl',
[title2]:'wxl'
}
Symbol有很多内置方法
1.8.1 Symbol的数据类型及特性?
// 数据类型的声明