ES6常用语法
一 、ES6常用语法之var和let定义
1. ES5只有全局作用域和函数作用域, 没有块级作用域, 如下代码所示。所以下面代码中的var变量定义会被提示到函数作用域顶端,
var的测试
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>标题</title>
</head>
<body>
<script>
var username;
console.log('1',username);
var username = "我的名字";
console.log('2',username)
</script>
</body>
</html>
//前端页面输出结果是
1 undefined // 第一次打印
2 我的名字 // 第二次打印结果
2、let :ES6中新增了let语法,用来声明变量,用法类似var,但是使用let定义的变量,只在当前代码块内有效。
1.
<script>
console.log('1',username);
let username = '你的名字';
console.log('2',username);
</script>
// Uncaught ReferenceError: username is not defined
//直接报错
2.
<script>
// console.log('1',username);
let username = '你的名字';
console.log('2',username);
</script>
// 2 你的名字
3.
<script>
// console.log('1',username);
let username = '你的名字';
let username = '你的名字';
console.log('2',username);
</script>
// 结果:SyntaxError: Identifier 'username' has already been declared
3. 块级作用域测试
<script>
if (true) {
var username = "名字";
let age = 22;
}
console.log(username);
console.log(age);
</script>
// 结果
// 名字
//Uncaught ReferenceError: age is not defined
4.1 、const 定义变量
const关键字声明一个只读常量,常量一旦被声明,就不能被更改。
1. 不能重复定义 <script> const PI = 3.1415; const PI = 3.14; console.log(PI) </script> // SyntaxError: Identifier 'PI' has already been declared 2. 不存在变量提升 <script> console.log(PI); const PI = 3.1415; </script> // ReferenceError: PI is not defined 3.只在定义域有效 <script> { var a = 10; const b = 10; } console.log(a); console.log(b); </script> // 10 // Uncaught ReferenceError: PI is not defined
4.2、const定义数组和对象
使用const定义的常量,不可改变,这里的不可改变,指的是该数据类型本身不可改变,比如字符串,数字,假设使用const定义一个对象或者数组,因为对象和数组这两种数据类型本身是可以被新增或者删除元素的,所以,此时const定义的常量可以被改变。
const实际上保证的,并不是变量的值不可改变,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(比如对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
<script>
// 使用const定一个常量,该常量的类型为object
const obj = {
name: "my_名字",
age: 18
};
obj.age = 19;
// 此时obj中的age被修改为19
// 但是obj所指向的内存地址并没有被改变,也不能被改变
console.log(obj);
// Uncaught TypeError: Assignment to constant variable.
obj = "hello Es6";
// 但是obj所指向的内存地址不能被改变,
</script>
总结 :在es6 中添加的let 和var对比
// var定义的变量:只有全局作用域和函数作用域
// let定义的变量:有全局作用域和函数作用域,块级作用域 {}
// let定义的变量不能重复定义
// const 相当于常量 用法类似let 注意:只最好只使用简单的[字符串,数值,布尔值]
二 、 模板之字符串
1.反引号和${}的使用
<div id="d1"></div>
直接拼接
<script>
// ES5
var d1 = document.getElementById("d1");
d1.innerHTML = "<h1>hello word</h1>" + "<h2>hello Vue</h2>";
</script>
反引号和{}的使用
<script>
// ES6
let username = "名字1";
let username2 = "名字2";
let d1 = document.getElementById("d1");
d1.innerHTML = `
<h1>hello ${username}</h1>;
<h3>hello ${username2}</h3>;
`
</script>
三 、模板之数据解构
1.数组类型解构
<script>
let ary =[1,2,'hello'];
let [a,b,c] = ary;
console.log(a);
console.log(b);
console.log(c)
</script>
// 解构结果:
1
2
hello
2.对象类型解构
<script>
let obj = {
name:"名字",
password:"root1234",
};
let {name:a,password:b} = obj;
console.log(a,b)
</script>
// 结果 ==》 名字 root1234
3.数据的交换
<script>
let a = 1;
let b = 2;
[a, b] = [b, a]
console.log(a, b)
</script>
//结果 ==》 2 1
四 、ES6函数的扩展
1.默认值参数
在ES5中,由于函数不支持设置默认值,所以当遇到需要设置默认值的情况的时候,只能采用变通的方式,不过这种变通的方式会存在一些问题。ES6中引入了函数的默认值参数,解决了这些问题。
1.1. ES5没有默认值参数
<script>
//默认值参数
function foo(x,y) {
let num = y;
return num;
}
ret1 = foo();
ret2 = foo(1);
ret3 = foo(1,2);
console.log(ret1); // ==> undefined
console.log(ret2); // ==> undefined
console.log(ret3); // ==> 2
</script>
1.2ES5需要默认值参数的折中方法
<script>
//ES5
function foo(x,y) {
let num = y || 10;
return num;
}
ret1 = foo();
ret2 = foo(1,0);
ret3 = foo(1,2);
console.log(ret1); // ==> 10
console.log(ret2); // ==> 10
console.log(ret3); // ==> 2
</script>
2.1.ES6 中使用默认值参数
<script>
//默认值参数
function foo(x,y=10) {
let num = y;
return num;
}
ret1 = foo();
ret2 = foo(1,0);
ret3 = foo(1,2);
console.log(ret1); // ==> 10
console.log(ret2); // ==> 0
console.log(ret3); // ==> 2
</script>
2.1箭头函数
ES6中引入了箭头函数,其实就相当于Python当中的匿名函数lambda,接下来我们详细看看箭头函数的使用方式以及使用箭头函数时需要注意的地方。
1.带参数的箭头函数
<script>
//箭头函数 (类似python中的 lambda函数)
let foo = v => v;
ret1 = foo(10);
console.log(ret1); // ==》 10
//普通函数 等同于上边的箭头函数
let foo1 =function (v) {
return v;
};
ret2= foo1(10);
console.log(ret1); // ==》 10
</script>
2. 不但参数(0参数)或者多个参数的箭头函数:用() => {} 表示
2.1 零个参数或者多个参数的箭头函数定义方式如下
<script>
let bar = (a, b) => a + b;
console.log(bar(1, 2)) // ==> 结果 3
</script>
2.2 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return
语句返回:
<script>
let bar = (x, y) => {
return x + y;
};
ret2 = bar(1, 2);
console.log(ret2); // ==》结果为 3
</script>
2.2箭头函数的用途
那么,箭头函数有什么用呢?其一,箭头函数可以简化代码,是代码实现更加简洁,比如如下需求:
判断一个数是否是偶数
//1普通写法
// function isEven(num) {
// if (num%2 === 0){
// return true
// } else {
// return false
// }
// }
//2箭头函数的写法
let isEven = num => num % 2 === 0;
console.log(isEven(9));
console.log(isEven(8))
2.3 另外,箭头函数还可以简化回调函数的写法,比如,map和sort中的回调函数
<script>
// 箭头函数可以简化回调函数
let ary = [1, 2, 3];
// 普通函数写法
let ary1 = ary.map(function (x) {
return x * x
});
// 箭头函数写法
let ary2 = ary.map(x => x * x);
console.log(ary1);
console.log(ary2);
// 将序排列数组
values = [10, 8, 9, 1, 2, 5, 7, 4, 6, 3];
// 普通函数写法
values.sort(function (a, b) {
return b - a
});
// 箭头函数写法
values.sort((a, b) => {
return b - a;
});
console.log(values);
</script>
2.4 箭头函数this的指向问题
首先,箭头函数中的this不再随着调用它的对象的改变而改变,this对象变成固定的了,它稳定的指向该箭头函数被定义时的作用域,而不是像普通函数那样,指向函数调用时的作用域。
function foo() {
console.log(this);
}
let bar = () => console.log(this);
let obj = {
foo: foo,
bar: bar,
};
foo(); // windows 指向
obj.foo(); // obj 的指向
bar(); // windows 固定的不会变
obj.bar(); // windows 固定的不会变
五 、 ES6之类的定义
1. 简单用function实现一个类和实例化
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
// 定义打印name的的方法
Person.prototype.showInfo = function () {
console.log(this.name)
};
// 定义打印age的的方法
Person.prototype.showage = function () {
console.log(this.age)
}
let xiaoming = new Person('xiaoming', 17)
xiaoming.showInfo(); // ==> xiaoming
xiaoming.showage() // ==> 17
</script>
2.用class实现一个类以及实例化
<script>
class Person {
//__init__
constructor(name,age){
this.name = name;
this.age = age;
}
//方法
showname(){
console.log(this.name)
}
//方法
showage(){
console.log(this.age)
}
}
let xiaoming = new Person('小明',18);
xiaoming.showname(); //执行方法
console.log(xiaoming.age) //执行对象的属性
</script>
3.类的继承
<script>
/*
// ES5中使用构造函数的方式创建实例对象
function Foo(username, age, hobby) {
this.username = username;
this.age = age;
this.hobby = hobby;
}
Foo.prototype.showInfo = function () {
console.log(this.username, this.age, this.hobby);
};
let foo = new Foo("peiqi", 73, "girls");
foo.showInfo();
*/
// ES6中使用class创建类,并使用new方法创建实例对象
// 我们需要注意:
// 1. 必须要有constructor方法,如果没有,默认会给一个空的constructor方法
// constructor () {};
// 2. 必须要用new调用,不能直接调用,否则报错;
/*
class Foo {
constructor (username, age, hobby) {
this.username = username;
this.age = age;
this.hobby = hobby;
}
showInfo () {
console.log(this.username, this.age, this.hobby);
}
}
let foo = new Foo("wuchao", 18, "girls");
foo.showInfo();
*/
// ES6中类的继承
// 第一步,使用class关键字定义类
class Baoyuan {
// 第二步,使用constructor构造函数,初始化实例
constructor (username, age) {
this.username = username;
this.age = age;
this.money = 100000;
}
showInfo () {
console.log(this.username, this.age, this.money);
}
}
let baoyuan = new Baoyuan("baoyuan", 20);
baoyuan.showInfo();
class Alex extends Baoyuan {
constructor (username, age) {
super();
this.username = username;
this.age = age;
}
}
let alex = new Alex("alex", 2);
alex.showInfo();
</script>
六 、 单体模式
简单示范一个
<script>
let obj = {
name:"ming",
func(){
console.log(this.name);
console.log(this);
}
};
obj.func() // obj 指向
</script>