ES6语法

简介

ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。Mozilla公司将在这个标准的基础上,推出JavaScript 2.0。ECMA Script,JavaScript的语言标准。

作用

优点:提升JS编写大型的复杂应用程序的能力,升级加入了模块化的概念、细化和优化语法、封装了一些方法。
缺点:对浏览器存在兼容性问题

知识点

一:新增的声明变量

1、let

特点:声明的变量不会造成的全局的污染,因此新增一种块级作用域,存到临时性的死区

		 {
	     	let num = 100;
			console.log(num)
		 }

例如:

let a = 10;
		{
		 	console.log(a);   //
		 	let a = 20;  //这时得a存到临时性的死区中
		}

常见得面试题:

<body>
	<button>0</button>
	<button>1</button>
	<button>2</button>
	<button>3</button>
	<button>4</button>
	<button>5</button>
	<script>
		// i值的问题

		var buttons = document.getElementsByTagName("button");
		for(var i = 0;i < buttons.length;i++){
			buttons[i].onclick = function(){
				console.log(i);
			}
		}
		解决办法一:ES6方法
			for(let i = 0;i < buttons.length;i++){
			buttons[i].onclick = function(){
				console.log(i);
			}
		}
		解决办法二:
		(function(i){
		 		for(var i = 0;i < buttons.length;i++){
			    buttons[i].onclick = function(){
				console.log(i);
			}
				}
		 	})(i)
	</script>
</body>

2、const 常量
const定义的变量不可以修改,而且必须初始化,存到临时性的死区。

 const b = 2;//正确
// const b;//错误,必须初始化 
console.log('函数外const定义b:' + b);//有输出值
// b = 5;
// console.log('函数外修改const定义b:' + b);//无法输出 

ES6新增了API:
1.is() ===
2.assign() 用于混合对象,带浅克隆
3…getOwnPropertyNames()
4.setPrototypeOf()

二:新增的字符串模板 ``

<script>
		var day = "Hello";
		var str = "world";
		console.log(`${day}${str}`)
		// `${表达式}字符串`
		// 可以添加串
		// 可以使用转义字符
		// 可以嵌套
		console.log(`${true?`Helloworld`:`My Gad`}`)
</script>

三:ES6解构

<script>
         //1:对于对象
		 let obj = {
		 	name : "wxw",
			age : 21
		 }
		 let name,age;
		 ({name,age} = obj);
		 console.log(name,age)
		 
         //2:
         
		 let {name , age} = obj;
		 console.log(name,age);
		 
         //3:
         
		 let {name : OName,age : OAge} = obj;
		 console.log(OName,OAge)

         //对于数组
         //1:
		 let arr = [1,3,5,7];
		 let [a,b,c,d] = arr;
		 console.log(a,b,c,d)
         //2:
		 let {length} = arr;
		 console.log(length)
         //3:
		 let {1:a,5:b,7:c,3:d} = arr;
		 var a = arr[1];
		 var b = arr[5]		
		 var c = arr[7]
		 var d = arr[3]
		 console.log(a,b,c,d)
		 //4:
		let arr = [1,2,3,{name:'wxw'}];
		 a : 1 b : 2 c : 3 name:wxw
		 let {0:a,1:b,2:c,3:{name:OName}} = arr;
		 console.log(a,b,c,oName)
        //5
	    var OName = arr[3].name;
		let [,,,{name : OName}] = arr;
		console.log(OName)
	</script>

四:…运算符
1、拓展运算符。

function myFunction(x, y, z) { 
  console.log(x + "" + y + "" + z); 
} 
var args = [0, 1, 2]; 
myFunction(...args);//...arr返回的并不是一个数组,而是各个数组的值

2、数组和对象的拷贝
数组:

var arr1 = [1,2,3];
var arr2 = [...arr1];
arr2.push(4);
console.log(arr1 === arr2);  // false
console.log(arr1); // [1,2,3]
console.log(arr2);// [1,2,3,4]

对象:

var obj1 = {
  a:1,
  b:2
};
var obj2 = {...obj1};
console.log(obj2); //{ a:1, b:2}
console.log(obj1 === obj2);// false

提示:这是一个深拷贝,实际上, 展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)。

3、构造字面量数组。
ES6之前只能组合使用 push, splice, concat 等方法,现在。。。

//代替Array.concat 函数
var arr1 = [1,2,3];
var arr2 = [4,5,...arr1];
console.log(arr2);
// [4,5,1,2,3]
代替Array.unshift 方法
var arr1 = [1,2,3];
var arr2 = [4,5,6];
var newarr = [...arr1,...arr2];
console.log(newarr );
//  [1, 2, 3, 4, 5, 6]
newarr1= [...arr2,...arr1];
console.log(newarr1);
//  [4, 5, 6, 1, 2, 3]

4、字符串转数组

var demo = "Hello"
var str = [...demo];
console.log(str);
// ["h", "e", "l", "l", "o"]

五:ES6 提供新内容,参数可以加默认值

function fun(a,b=1,c=2){
			return a+b+c;
		}
		 console.log( fun(undefined,undefined,30) );
		 console.log( fun(1,2,3) )

面试题:

<div id="container"></div>
<script>
        //面试题
		// 控制台输出几次test?
		createElement(undefined,undefined,"sdfsdfsd")
		createElement(undefined,undefined,"sdfsdfsd")
		createElement(undefined,document.getElementById("container"),"sdfsdfsd")  
		// 2次  传递以后不会去看默认值
		// 面试题
		function test(a=b,b){   //Uncaught ReferenceError: Cannot access 'b' before initialization
    at test
			console.log(a,b)
		}
		test(undefined,2)
	</script>

六:加判断instanceof,ES6之前没有办法完美解决

<script>
        //面试点:new调用和直接调用出现的结果
		function Person(firstName,lastName){

			// 加判断   ES6之前没有办法完美解决
			 if(!(this instanceof Person)){
			 	throw new Error("该函数必须使用new调用")
			 }

			// 如果没有使用new 关键字调用函数,则返回undefined
			// 如果使用了new调用,则返回的是函数的本身
			if(new.target === undefined){
				throw new Error("该函数必须使用new调用")
			}

			this.firstName = firstName;
			this.lastName = lastName;
			this.fullName = `${firstName} ${lastName}`
		}
		const p1 = new Person("张","三");
		console.log(p1);

		const p2 = Person("张","三");
		console.log(p2)

		// const p3 = Person.call(p1,"张","三")
		// console.log(p3)
	</script>

七:箭头函数
1、

x => x * x
//相当于
function (x) {
    return x * x;
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ … }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ … }和return:

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

如果参数不是一个,就需要用括号()括起来

// 两个参数:
(x, y) => x * x + y * y

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错

// SyntaxError:
x => { foo: x }

因为和函数体的{ … }有语法冲突,所以要改为

x => ({ foo: x })

2、箭头函数的this指向问题,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域
ES6之前写法
面试点:this的指向

var obj = {
    birthday: 1999,
    getAge: function () {
        var b = this.birthday; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birthday; // this指向window或undefined
        };
        return fn();
    }
};

ES6之后写法

var obj = {
    birthday: 1999,
    getAge: function () {
        var b = this.birthday; // 1990
        var fn = () => new Date().getFullYear() - this.birthday; // this指向obj对象
        return fn();
    }
};
obj.getAge(); // 25

由于this在箭头函数中已经按照词法作用域绑定了,因此,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略。

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25

八:构造函数的新写法

class Person{
			constructor(job,name,age,sex){
				this.job = job;
				this.name = name;
				this.age = age;
				this.sex = sex;
			}
			print(){
				console.log('工作:',this.job)
				console.log('姓名:',this.name)
				console.log('年龄:',this.age)
				console.log('性别:',this.sex)
			}
		}
		const a = new Person("Web","wxw",18,"nan");
		console.log(a)
		a.print()

注意点:
1.类的声明不会被提升,和let const 一样,有临时性死区
2.类的所有代码全都是在严格模式中执行
3.类的所有方法都是不可枚举的
4.类的所有方法都无法当成构造函数直接使用
5.类的构造器必须使用new 来调用

setPrototypeOf() 设置某个对象的隐式原型 __ proto __

<script>
		// 类的继承
		function Amimal(name,age,sex){
			this.name = name;
			this.age = age;
			this.sex = sex;
		}
		Amimal.prototype.print = function(){
			console.log(`名字 : ${this.name}`)
			console.log(`年龄 : ${this.age}`)
			console.log(`性别 : ${this.sex}`)
		}
		function Dog(name,age,sex){
			// 借助父类的构造函数
			Amimal.call(this,name,age,sex);
		}

		Object.setPrototypeOf(Dog.prototype,Amimal.prototype)
		const d = new Dog("来福",5,"公");
		console.log(d);
		d.print();
	</script>

getOwnPropertyNames() 枚举的顺序,返回一个数组,枚举出来对象的属性

	   const obj = {
		 	e : 1,
			a : 2,
		 	c : 3,
		 	0 : 6,
		 	5 : 7,
		 	2 : 3
		 }
		 console.log(obj)
		 const arr = Object.getOwnPropertyNames(obj);
		 console.log(arr); 

九:ES6新增对象的方法
1.属性简写
2.方法简写
3.计算属性名

		 const printName = "print";
		 const test = "job1"
		 class Person{
		 	constructor(job,name,age,sex){
		 		this[test] = job;
				this.name = name;
		 		this.age = age;
		 		this.sex = sex;
			}
		 	[printName](){
		 		console.log('工作:',this[test])
		 		console.log('姓名:',this.name)
				console.log('年龄:',this.age)
		 		console.log('性别:',this.sex)
			}
		 }
		 const a = new Person("程序猿","zhansan",30,"nan");
		 console.log(a)
		 a[printName]()

4;面向对象写法

function Elephant(){}
		function Frige(){}
		Frige.prototype.openDoor = function(){}
		Frige.prototype.closeDoor = function(){}
		Frige.prototype.join = function(){}

		var frig = new Frige();
		frig.openDoor()
		var ele = new Elephant()
		frig.join(ele)
		frig.closeFrige()

小结:

等号表达式是典型的赋值形式,函数传参和for循环的变量都是特殊形式的赋值。解构的原理是赋值的两边具有相同的结构,就可以正确取出数组或对象里面的元素或属性值,省略了使用下标逐个赋值的麻烦。对于三个点号,三点放在形参或者等号左边为rest运算符; 放在实参或者等号右边为spread运算符,或者说,放在被赋值一方为rest运算符,放在赋值一方为扩展运算符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值