ES6基础 ** just for you **---
---ES6简介---
ECMScript 6 的简称,是JavaScript语言的新标准,自2015年6月正式发布后,得到迅速推广。对于ECMAScript和Javascript的关系,这里只说一句话:前者是后者的规格,后者是前者的一种实现。有关ES6的一些特性,现介绍一二:
个人学习小结
let 与 const
在js中有三种定义变量的方式:var let const(常量)
var,作为js中的一个老人,可谓鞠躬尽瘁;使用var 定义的变量没有块的概念,可以跨块访问,但是不能跨函数访问,举个小栗子:
var a = 2;
function test() {
console.log(a);//2
function test1() {
var b = 3;
console.log(a);//2
console.log(b);//3
}
test1();
console.log(b);//error
}
test();
复制代码
let和const js的新宠,这两种新的变量声明的到来为js提供了块级作用域与变量不再提升的两个重要特性;它们最直观的好处:
·用块替换立即执行函数
·定义变量循环不会外漏(for循环)
·可以放心的定义函数
let在ES6中,let 代替了var,它有以下特性
1.let定义的值不会被变量提升,eg:
function test1() {
console.log(a);//err
let a = 1
}
test1();
复制代码
2.let 定义的变量会形成块级作用域,外部不能访问,eg:
function test1() {
let a = 1
}
console.log(a);//err
test1();
复制代码
3.let 不能重复定义 eg:
function test1() {
let a = 1;
let a = 2;
}
console.log(a);//err
test1();
复制代码
const定义的常量也能形成块级作用域,并且不能被提升,它和let的区别是:let定义的变量可以修改,而const在定义的时候就要赋上初始值,并且不能修改。
Notice:const和let声明的变量不在window的属性中。如下:
var a = 1;
let b = 2;
const c = 3;
console.log(window.a);//1
console.log(window.c);//undefined
console.log(window.b);//undefined
复制代码
js模版字符串 ${}
ES6中新增的模版字符串的写法,愉快的解决了ES5在字符串功能上的痛点。
它主要的作用是连接字符串,eg:
在ES5中输出一串字符串-->javascript var a = "world";console.log("hello"+a);
在ES6中输出一串字符串-->javascript console.log(`hello${a}`)
函数相关之 箭头函数 --js的给力军
之前函数的写法:
function f(x){
return x;
}
let res = f(2);
console.log(res);
复制代码
箭头函数的写法
var f = x =>x;
console.log(f(1))
复制代码
重点: 省略了小括号,省略了大括号,省略了return ,没有比这更省的啦~
函数相关之 函数默认参数
在ES6中js的形参可以有默认值 eg:
function add(x = 2,y = 1){
return x + y;
}
let res = add();
console.log(res);//3
复制代码
*But:*默认值一般都是指后面的参数,再来举个小栗子吧
下面这种写法是OK的
function add(x,y = 1){
return x + y;
}
let res = add(2);
console.log(res);//3
复制代码
这种写法Not OK
function add(x = 1,y){
return x + y;
}
let res = add(2);
console.log(res);//NaN
复制代码
严格模式
听起来好紧张的样子,其实也就是为js'做后盾'的。使用严格模式的目的:规则,提高编译效率,是对js非严格模式的一种优化。
那么怎么去启动严格模式呢?
使用"use strict",如果是加在函数里,则需要加在函数体所有语句之前;
严格模式与非严格模式的区别有啥呢?
1,在严格模式下不能使用没有var的变量
eg:
<script>
"use strict"
a = 1;
console.log(a);//err : a is not defined
</script>
复制代码
2,在严格模式下不能使用八进制的数字 why?因为大神说,八进制语法很少有用并且可能胡错误使用,所以严格模式下八进制就会引起语法错误:(my god,神的阐述...)
"use strict"
let a = 010;
console.log(a);
//Uncaught SyntaxError: Octal literals are not allowed in strict mode.
复制代码
3,严格模式下function中的this不再指向window
<script>
function f(){
"use strict"
console.log(this);//undefined;
}
f();
</script>
复制代码
4,严格模式下的arguments不再跟踪参数的变化
function f1(a, b) {
b = 2;
console.log(arguments);//[1,2]
}
f1(1, 34);
function f2(a, b) {
"use strict"
b = 2;
console.log(arguments);//[1,34]
}
f2(1, 34);
复制代码
5,严格模式下函数不能有重名的形参; 首先,非严格模式下
function f(a, a) {
console.log(arguments);//[1,34]
}
f(1, 34);
复制代码
而启动严格模式之后,
function f(a, a) {
"use strict"
console.log(arguments);//语法错误,重命名
}
f(1, 34);
复制代码
6,严格模式下if语句中不能嵌套函数
"use strict"
if (1 > 0) {
function f(a, b) {
console.log(arguments);//引用错误,f is not defined
}
}
f(1, 34);
复制代码
set 和 map 两种新的数据结构(集合)
set 和数组差不多,只是set中的值是唯一的,没有重复的
创建set如下:
var s = new Set([1,2,3,4,"hello world"]);
复制代码
注意点:new set();小括号里面不能直接放元素,不能放对象;
添加元素如下
var s = new Set();
s.add(1);
s.add(2);
console.log(s);//{1,2}
复制代码
删除元素如下
var s = new Set([1,3,5,2,0,9]);
s.delete(1);
console.log(s);//{3,5,2,0,9}
复制代码
遍历--set()方法的遍历可以使用forEach(),for..of,但不能使用for..in; 下面使用for..of举个栗子:
var s = new Set([1,3,5,2,0,9]);
for(item of s){
consol.log(item);//1,3,5,2,0,9
}
复制代码
Notice:利用set()方法元素的唯一性可实现数组的去重 eg:
let arr = [1,1,2,2,3,3,"isLove"];
console.log(...new Set(arr));//1 2 3 "isLove"
复制代码
map 类似于对象,里面存放的也是键值对,区别在于:对象中的键名只能是字符串,而使用map可以是任意值
创建map
var m = new Map({name:"feichai"});
console.log(m);//恭喜错了
复制代码
其构造函数接受一个数组,集合或类数组 错的就不写了,写一个正确的
var m = new Map([[name:"feichai"]]);
console.log(m);//{"name" =>"feichai"}
复制代码
添加元素
var m = new Map([[name:"feichai"]]);
m.set(2018,"hello");
m.set(["salary"],{main:"20k"})
console.log(m);//添加倒是要求不多,就是加属性要加引号
复制代码
删除元素
var m = new Map([[name:"feichai"],[2018,"hello"]]);
m.delete(2018)
console.log(m);//成功
复制代码
获取元素
var m = new Map([[name:"feichai"],[2018,"hello"]]);
console.log(m.get(2018));//hello
复制代码
字符串拓展之 trim(清除空格)
使用方法,举个栗子(在chrome控制台,效果更清晰哦)
var str = " hello world!!! "
str.trimLeft();
//str.trimRight()
//str.trim()
console.log(str.trimLeft());
复制代码
字符串拓展之 repeat()
var str = " hello world!!! ";
console.log(str.repeat(12));//并不改变原字符串
复制代码
字符串拓展之 includes()
判断字符串中是否含有某个元素如果有返回true; 代码如下:
var str = " hello world!!! ";
console.log(str.includes("h"));//true
复制代码
字符串拓展之 startsWith()和endsWith()
判断是否以**字符开始或结束,返回值为布尔;
var str = " hello world!!! ";
console.log(str.startsWith("h"));//false
console.log(str.startsWith(" "));//true,怪厉害的!
复制代码
字符串拓展之 padStart(12,"*")
表示一共12位数,不足的用*号在前面补齐;
字符串拓展之 padEnd(4,"*")
表示一共4位数,不够的用*在后面补齐;
数组之 Array.from()
这个方法的作用是将伪数组转为真数组 eg:
function f() {
console.log(Array.isArray(arguments));//false
console.log(Array.from(arguments));[1,2]
}
f(1, 2);
复制代码
对getElementsByTagName()得到的伪数组,还有字符串都起作用;
数组之 Array.of()
用来创建一个数组
var arr = Array.of(3);
var arr1 = Array.of('3');
var arr2 = new Array(3);
console.log(arr, arr1,arr2);//[3]['3'](3) [empty × 3]
复制代码
数组之 find()和findIndex()
find()用来查找一个元素找到一个就返回
var arr = [1, 2, 3, 5]
var rs = arr.find(item => {
return item =2
}
)
console.log(rs);//1错的。
var arr = [1, 2, 3, 5]
var rs = arr.find(item => {
return item == 2
}
)
console.log(rs);//2 对的
复制代码
findIndex()方法返回的是一个索引
var arr = [1, 2, 3, 5];
console.log(arr.findIndex(item => item == 3));//2
复制代码
数组之 includes()
一丝丝熟悉的感觉扑面而来,原来是字符串中也有这个方法,返回值为Boolean值,充满新鲜感的是indexOf()也有此作用,返回值为0或-1,但是indexOf()对NaN的判断是错误的,好吧,NaN你牛!!!
var arr = [1, 2, 3, NaN]
var rs = arr.indexOf( NaN)
console.log(rs)//-1
复制代码
数组之 fill(值,起点,终点)
var arr = [1, 2, 3, NaN];
console.log(arr.fill(0,0,2));//[0,0,1,2,3,NaN]?错了[0,0,3,NaN]
复制代码
已有数据会被覆盖
数组之 数组的扩展运算符 ...
作用是1,浅拷贝;2,合并数组,3,转数组
var arr = [1, 2, 3];
console.log(...arr);//1,2,3
var arr1 = [1, 2, 3];
var arr2 = [4,5,6];
var arr = [...arr1,...arr2];
console.log(arr)//[1,2,3,4,5,6]
复制代码
数组之 数组的解构赋值
既是左右结构一致
var [a,b,c] = [1, 2, 3];
console.log(a,b,c);//1,2,3
var [e=2,f,g] = [, 2, 3];
console.log(e,f,g);//2,2,3
复制代码
对象的扩展之 对象的简写
1,属性的简写 前提条件:属性的值是一个变量,变量名和键名是一致的;
var name = "happy";
var obj = {
name:name
};
console.log(obj.name);//happy
复制代码
2.方法的简写
var name = "happy";
var obj = {
//以前的写法
// say:function(){
// console.log("I am your sunshine...");
// }
// };
//ES6简写
say() {
console.log("I am your sunshine...");
}
}
console.log(obj.say());//I am your sunshine...
复制代码
对象的扩展之 属性相关的方法
开始这部分之前先普及一下"常识":configurable:默认可删除; writable:默认可写; enumerable:默认可枚举; value:属性值
1.Object.getOwnPropertyDescriptor(); 获取一个对象中某个属性的详细信息
var obj = {
name: "九尾纽扣",
age:  18
}
console.log(Object.getOwnPropertyDescriptor(obj, "name"));
//{value: "九尾纽扣", writable: true, enumerable: true, configurable: true}
复制代码
2.Object.defineProperty(); 精细化设置对象的属性 举个栗子吧(此段设置,不可删,不可改,不可枚举,小姐姐永远18~)
var obj = { name: "九尾纽扣" }
Object.defineProperty(obj, "age", {
configurable: false,
writable : false,
enumerable : false,
value : 18
})
console.log(obj.name, obj.age);//九尾纽扣 18
复制代码
3.Object.getOwnPropertyNames(对象名) 获取对象的属性,以数组的格式返回
//在上段代码的基础上
console.log(Object.getOwnPropertyNames(obj));//["name", "age"]
复制代码
4.Object.keys(); 用法同上
区别: Object.keys()用来获取对象自身可枚举的属性键; Object.getOwnPropertyNames()用来获取对象自身的全部属性名
5.Object.values(); 获取对象的值,以数组的格式返回
//在上段代码的基础上
console.log(Object.values(obj));//["九尾纽扣"]
复制代码
划重点为啥没有age呢?因为在上段代码的设置中enumerable:false!!不可枚举~
到此我们可以总结遍历对象的三种方法:
-
for in :循环遍历对象自身的和继承的可枚举属性(不含Symbol属性);
-
Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)的键名;
-
Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)的键名
-
Ojbect.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有Symbols属性的键名
-
Reflect.ownKeys(obj):同样以数组的格式返回,包括对象自身的所有属性,所有!!
对象的扩展之 继承相关的方法
Object.create() 适用于字面量的继承,可以继承方法的原型属性,比如创建一个构造器,new一个方法n1, 那么Object.create() 就可以这样使用,var n2 = Object.create(n1); n2就继承了n1的原型属性。
Object.getPrototypeOf() 获取创建这个对象的那个构造器的prototype属性
var obj = {
name: "九尾纽扣",
age:  18
}
console.log(Object.getPrototypeOf(obj) == Object.prototype)//true
复制代码
防篡改的方法 分为三个级别
1.Object.preventExtensions(obj);此方法不允许想你增,但可以修改,也可以删除;
2.Object.seal(obj);不允许新增,不允许删除,但还可以修改
3.Object.freeze(obj);不允许新增,不允许删除,不允许修改
与之对应的三个方法来判断处理是否在某个状态
1.isExtensible(obj);
2.isSealed(obj);
3.isFrozen(obj);
对象的扩展之 Object.assign();
用于对象的合并,将对象的所有可枚举的属性复制到目标对象,实现的是浅拷贝,格式为Object.assign(target,source1,source2,source3)可以有多个参数
var obj1 = {
name: "九尾纽扣",
}
var obj2 = {
age: 18
}
var obj = {}
console.log(Object.assign(obj, obj1, obj2))
//{name: "九尾纽扣", age: 18}
复制代码
对象的扩展之 对象的扩展运算符 ···
作用:遍历当前对象的所有可遍历的属性,拷贝到当前对象之中。
let obj1 = {x :1,y : 2,z : 3};
let obj2 = {...obj1};
console.log(obj2);//{x: 1, y: 2, z: 3}
复制代码
class
ES6的class可以看作是一个语法糖。
1,class采用大驼峰命名法则,即类名的首字母都大写,类名后面紧跟{};
2,在{}中,不能直接写语句,只能写方法,方法不需要使用关键字;
3,方法和方法之间没有逗号,不是键值对。
ES6的类,完全可以看作构造函数的另一种写法,this指向实例化对象
格式如下:
class 类名{
constructor(参数){
this.属性 = 属性值
}
方法名(){
}
}
new 类名(实参);
调用
复制代码
举个栗子:
class MyNews {
constructor(title, count) {
this.title = title;
this.count = count;
}
show() {
console.log("I am Class 类...")
console.log(`${this.title}\t,${this.count}`)
}
}
var n1 = new MyNews("《Prision Break》", "7 seasons");//I am Class 类... 《Prision Break》,7 seasons
console.log(n1.show())
复制代码
extends 继承类
Notice:
1.使用extends关键字来实现继承;
2.在子类中的构造器函数constructor中,必须要显示调用父类的super()方法,如果不调用,则this不可用;
来个格式:
class子类extends 父类{
constructor(参数){
super(参数)//very important!
this.属性 = 值
}
}
复制代码
来个上面方法的继承吧 eg:
class Movie extends MyNews {
constructor(title, count, ticket) {
super(title, count);
this.ticket = ticket;
}
showT() {
console.log("I am a child of MyNews.... ");
console.log(`This movie is ${this.title},it's${this.count},my book office are ${this.ticket}`)
}
}
var m = new Movie("《 Men in Black 》", "4 seasons", "2000000");
m.showT();
//I am a child of MyNews.... This movie is 《Men in Black》,it's4 seasons,my book office are 2000000
复制代码
此次小结到这儿就告一段落,欢迎各位大神批评指正!
个人寄语:
学习不易,总结不易,且学且珍惜!
纽扣在这里特别感谢阮大大的参阅资料,也对我的老师波哥提出特别 ‘感谢’!
继续努力,追大神~