ES6知识点-上
文章目录
ES6是个啥?
ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言
变量的声明与表达式
let和const
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let
let 声明的变量只在 let 命令所在的代码块内有效。
基本用法
{
let a = 0;
a // 0
}
a // 报错 ReferenceError: a is not defined
//不同作用域无法访问
let 是在代码块内有效,var 是在全局范围内有效:
{
let a = 0;
var b = 1;
}
a // ReferenceError: a is not defined
b // 1
不能重复声明
let 只能声明一次 var 可以声明多次:
let a = 1;
let a = 2;
var b = 3;
var b = 4;
a // Identifier 'a' has already been declared
b // 4
不存在变量提升
let 不存在变量提升,var 会变量提升:
console.log(a); //ReferenceError: a is not defined
let a = "apple";
console.log(b); //undefined
var b = "banana";
const
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
const PI = "3.1415926";
PI = 123456 // 报错
暂时性死区:
var PI = "a";
if(true){
console.log(PI); // ReferenceError: PI is not defined
const PI = "3.1415926";
}
ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。
注意要点
const 如何做到变量在声明初始化之后不允许改变的?
其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。此时,简单类型和复合类型保存值的方式是不同的。对于简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的那个内存地址,因此 const 声明的简单类型变量等同于常量。而复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了,所以使用 const 声明复杂类型对象时要慎重。
解构赋值
什么是解构
在ES6中 按照一定的模式 从数组中提取数 对对应的变量进行赋值的操作 就叫做解构赋值
本质上讲 解构赋值 就是模式匹配
解构模型
在解构中,有下面两部分参与:
解构的源,解构赋值表达式的右边部分。解构的目标,解构赋值表达式的左边部分。
数组模型的解构
var [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3
可以嵌套
var [a, b, c] = [1, [2], 3];
// a = 1
// b = [2]
// c = 3
不完全解构
var [a,b,c] = [1,2]
// a = 1
// b = 2
// c = undefined
var [a,b,c] = [1,2,3]
// a = 1
// b = 2
//这个也属于不完全解构 多的值直接忽略
扩展运算符
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]
支持默认值
let[a,b = "abc"] = [1];
// a = 1
// b = "abc"
数组的拷贝
var arr = [1,2,3]
var arrsp = [...arr]
// arrsp = [1,2,3]
字符串等
在数组的解构中,解构的目标若为可遍历对象,皆可进行解构赋值。可遍历对象即实现 Iterator 接口的数据。
let [a, b, c, d, e] = 'hello';
// a = 'h'
// b = 'e'
// c = 'l'
// d = 'l'
// e = 'o'
对象的扩展
属性的简介表示方法
ES6在{} 允许直接写入变量名 解析的时候 变量名作为属性名 变量值作为属性值
const age = 12;
const name = "Amy";
const person = {age, name};
person //{age: 12, name: "Amy"}
//等同于
const person = {age: age, name: name}
方法名也可以简写
const person = {
sayHi(){
console.log("Hi");
}
}
person.sayHi(); //"Hi"
//等同于
const person = {
sayHi:function(){
console.log("Hi");
}
}
person.sayHi();//"Hi"
属性名表达式
ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内。
const obj = {
["he"+"llo"](){
return "Hi";
}
}
obj.hello(); //"Hi"
注意点:属性的简洁表示法和属性名表达式不能同时使用,否则会报错。
const hello = "Hello";
const obj = {
[hello]
};
obj //SyntaxError: Unexpected token }
const hello = "Hello";
const obj = {
[hello+"2"]:"world"
};
obj //{Hello2: "world"}
对象的新方法
Object.assign()
用于用来合并对象的
let target = {a: 1};
let object2 = {b: 2};
let object3 = {c: 3};
Object.assign(target,object2,object3);
// 第一个参数是目标对象,后面的参数是源对象
target; // {a: 1, b: 2, c: 3
-
返回值是传入的第一个目标对象 会把所有的对象合并上去时候
-
第一个参数必须是对象 如果不是对象 就会把它准换成对象
-
如果是undefined 或者 null 没办法转换成对象 name 就会报错
-
如果在需要合并的多个对象里面 有同名的属性 那么后面的属性就会啊对前面的进行覆盖
-
如果undefined和null不是第一个参数 那么就不会报错 第一个参数返回
-
assign方法是浅拷贝 不是深拷贝
Object.is()
这个方法和js的严格判断(===)用法基本一样 只是在对于 -0 和 +0 以及NaN 的判断的时候不同
console.log(-0 === +0);//true ====> 需要他是 false
console.log(NaN === NaN);//false ====> 需要他是 true
console.log(Object.is(-0, +0)); //false
console.log(Object.is(NaN, NaN)); //true
Object,setPrototypeOf
给一个对象设置原型对象
如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible()
查看),就会抛出 TypeError
异常。如果prototype
参数不是一个对象或者null
(例如,数字,字符串,boolean,或者 undefined
),则什么都不做。否则,该方法将obj
的[[Prototype]]
修改为新的值。
var dict = Object.setPrototypeOf({}, null);
class关键字
传统的构造函数的问题 :
-
构造函数和原型方法属性分离 不便于维护 降低了可读性
-
原型对象的成员可以遍历
-
默认情况下构造函数也是可以被当做普通函数来调用的 所以 功能性不明显
在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。
class 的本质是 function。
它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。
类定义
类表达式可以为匿名或命名。
// 匿名类
let Example = class {
constructor(let Example =a) {
this.a = a;
}
}
// 命名类
class Example {
constructor(a) {
this.a = a;
}
}
类声明
class Example {
constructor(a) {
this.a = a;
}
}
-
class就是一个语法糖 本质就是一个函数 就是使用ES5里面的函数封装的
-
在类里面去定义方法的时候 可以省略function
类使用的注意点 :
-
类是不可枚举的
-
类的用法很let和const一样 都有暂时性死区 必须先定义 再使用
-
类里面的方法不能做为构造函数来使用
-
类(Person)使用的时候 必须配合new关键字进行使用 否则就会报错
模板引擎
模板字符串
ES5 之前拼接的字符串
-
拼接太麻烦 需要用到多次分割 不便于维护
-
所有拼接的字符串只能一行显示 太长
模板字符串 所有的内容卸载反引号(``)里面 然后变量放在${}里面
var stu = {
name : "loser",
age : 15,
place : "湖北武汉",
grade : 6
}
document.querySelector("p").innerHTML=`我叫${stu.name},今年${stu.age}岁,我住在${stu.place},今年上${stu.grade}年级`
//我叫 loser,今年15岁 ,我住在湖北武汉,今年上6 年级
在${}里面可以放入任意格式的js表达式 可以进行计算
`今年上${stu.grade-1}年级`
//我今年上5年级
模板引擎
页面渲染使用字符串拼接 会存在问题 : 字符串的恒定性 字符串拼接的时候容易出错
模板引擎不会拼接字符串 直接使用 静态页面里面的html里面的结构生成模板需要渲染的时候直接调用
模板引擎的实现方式有很多 最简的就是 “置换型”模板引擎,这类结构模板引擎只是将指定模板内容(字符串)中的特定标记(子字符串)替换一下便生成了最终需要的业务数据(比如网页)
模板引擎的使用步骤
1.准备模板引擎
2.准备一个模板
-
准备模板必须要是用script 模板引擎规定的只能使用script
-
必须要给他一个id 在调用的时候使用
-
必须要有type属性 而且type属性绝对不能使用 type/jsvascript
3.调用方法 生成html结构
<script src="./template-web.js"></script>
<script type="text/html" id="tpl">
<h1>自我介绍</h1>
<p>大家好, 我叫<%= name %>, 我今年<%= age %> 岁</p>
</script>
</script>
<script>
var stu = {
name : "lisa",
age:18
}
var html = template("tpl",stu)
document.body.innerHTML = html;
//自我介绍
//大家好, 我叫lisa, 我今年18 岁
</script>
模板引擎的内部循环
直接在模板引擎中可以使用 js 的 语法 实现循环
<script src="./template-web.js"></script>
<script type="text/html" id="tpl">
<%for(var i = 0; i < list.length; i++) { %>
<h1>自我介绍</h1>
<p>大家好, 我叫<%= list[i].name %>, 我今年
//可以使用if 也可以使用下面的三元表达式
<!-- <% if(list[i].age>18) { %>
<u>成年了</u>
<% }else{ %>
<u>成年了</u>
<%}%></p> -->
<% list[i].age > 18?%><u>成年了</u><%:%><u>未成年</u>;
</p>
<%}%>
</script>
</script>
<script>
var arr = [
{
name: "loser",
age: 26
},
{
name: "kmfk
age: 15
},
{
name: "sads
age: 20
},
{
name: "bgvz
age: 16
},
];
var html = ""
html += template("tpl", { list: arr });
document.body.innerHTML = html;
</script>
上一篇: JavaScript基础视频教程总结(031-040章)
下一篇: jQuery做字符串分隔