ECMA前身今世
Ecma International —— 瑞士标准协会, 负责制定国际标准
JavaScript —— 经由Netscape 和 Sun Microsystems创建并提交国际标准,取名ECMAScript
name - ES6 === official name -ES2015
常量
const 常量标识
const LIMIT = 10;
const OBJ_MAP = {
a:'A',
A:'a'
};
const QUEUE = [1, 2, 3, 4, 5];
1.不允许重复声明赋值
// 变量重新赋值
var arg1 = '1';
arg1 = '2';
// 常量
// ES5
Object.defineProperty(window, 'arg2',{
value:'1',
writable: false //不允许修改
})
//arg2不能被改变
// ES6
const arg3 = '1';
//arg3不能被改变
//const 不允许重复声明
const arg4='1'
const arg4='1' // 再次声明会报错
2. 块级作用域
if(true){
var arg1 = '1';
}
console.log('arg1',arg1); //arg1 1
if(true){
const arg2 = '2';
}
console.log('arg2',arg2); //undefined
3. 无变量提升
console.log(arg1);
var arg1 = '1';
//相当于
var arg1;
console.log(arg1);
arg1 = '1';
//无变量提升 - 先声明再使用
console.log(arg2);
const arg2 = '2'; //not defined
var arg1 = '1'
console.log(window.arg1); // 1
//const 非全局作用域, 不在windiow中
const arg2 = '1';
console.log(window.arg2); // undefined
4. dead zone
//在声明之前,变量都是不可用的
if (true) {
arg1 = '2';
console.log(arg1); // ReferenceError
let arg1;
}
5. let or const
- 引用型 const
const obj = {
name: '张三',
age: 18
}
obj.name = '李四';
const arr = ['A','B']
arr[0] = 'C'
//引用类型的原理 - 指向地址
//如何把对象变成常量不可改变? - object.freeze()
object.freeze(obj);
const obj2 = {
name: '张三',
age:18,
class:['语文','数学']
}
object.freeze(obj2);
obj2.class['0'] = '英语';
//freeze只能冻结根层, 嵌套引用类型需要遍历(递归)
function deepFreeze(){
//2. 确定主执行步骤
Object.freeze(obj);
//3. 逐级深入
(Object.keys(obj) || [] ).forEach(key =>{
let innerObj = obj[key]
if(typeof innerObj === 'object'){
//1. 递归模式确定
deepFreeze(innderObj);
}
})
}
箭头函数
箭头函数的写法
//传统函数
function test(a, b) {
return a + b;
}
const test2 = function(a, b){
return a + b;
}
//ES6
const test3 = (a, b)=>{
return a + b;
}
const test4 = (a, b)=> a + b;
const test5 = x => {
//content
}
const test6 = ()=>{
// ...
}
上下文
const obj = {
name: '张三',
age:18,
class:['语文','数学'],
getName: function() {
console.log(this.name); //张三 - this指向的是obj
return this.name;
},
getAge: ()=>{
console.log(this.age); //undefined - this指向的是全局
return this.age;
}
}
箭头函数并不会行成独立上下文, 内部this指向了window。
- 场景1: dom操作callback时
const btn = document.querySelector('#btn');
btn.addEventListener('click',funtion(){
this.style.color = '#FFF';
})
- 场景2: 类操作
function Obj(teacher, leader){
this.teacher = teacher;
this.leader = leader;
}
const Obj=(teacher, leader){
this.teacher = teacher;
this.leader = leader;
}
const o1 = new Ojb('张三', '李四');
console.log(o1)
//箭头函数无法成为完整构造类
Obj.prototype.learn = function(){
console.log(this.teacher, this.leader);
}
Obj.prototype.learn = ()=>{
console.log(this.teacher, this.leader);
}
//箭头函数无法成为完整构造原型方法 - 本质原因:this指向的是window
箭头函数的参数特性 - 无法使用arguments
const test = function(name){
console.log(arguments);
}
const test = name =>{
console.log(arguments); //箭头函数没有arguments
}
class
class 助力js 更面向对象 - 类
// 传统对象 - function
function Course(name, age){
this.name = name;
this.age = age;
}
Course.prototyper.getCourse = function(){
return `name is:${this.name},age:${this.age}`;
}
const course = new Course('张三', 18);
course.getCourse()
//ES6
class Course {
// init 实例会默认执行
constructor(name, age){
this.name = name;
this.age = age;
}
//拓展方法
getCourse(){
return `name is:${this.name},age:${this.age}`;
}
}
const course = new Course('张三', 18);
course.getCourse()
- 问题1: class的类型
console.log(typeOf Course); // function
- 问题2: class的prototype
console.log(Course.prototype); // 有区别,但本质类型相同
- 问题3: class & 函数对象 的属性
console.log(course.hasOwnProperty('name')); // true
- 问题4: 属性定义 构造器 & 顶层定义 两种定义方式
class Course {
// init 实例会默认执行
constructor(name, age){
this.name = name;
this.age = age;
}
//拓展方法
getCourse(){
return `name is:${this.name},age:${this.age}`;
}
get teacher(){
return this.name;
}
set teacher(val){
this.name = val
}
}
// 1. 如何建立一个只读变量
class Course {
// init 实例会默认执行
constructor(name, age){
this._name = name;
this.age = age;
}
//拓展方法
getCourse(){
return `name is:${this.name},age:${this.age}`;
}
get teacher(){
return this.name;
}
}
// 2. js如何建立一个私有属性
class Course {
// init 实例会默认执行
constructor(name, age){
this._name = name;
// 在constructor 作用域内定义一个局部变量
let _age = '123';
// 内部通过闭包的形式暴露该变量
this.getCourse = ()=>{
return _age;
}
}
}
// 3. 封装核心 - 适配器模式
class utils{
constructor(core){
this._main = core;
this._name = 'my_utils';
this._id = '不让修改的id'
}
get name(){
return {
...this.main.name,
name: `name is: ${this._name}`
}
}
get id(){
return {
...this.main.id,
id: this._id
}
}
set name(val){
// valid saftey
this._name = val
}
}
- 问题5: 静态方法 - 直接挂载在类上的方法, 无需实例化获取
class Course{
constructor(){
// ...
}
static ring(){
// ...
}
}
Course.ring();
- 问题6: 继承
class Course{
constructor(){
// ...
}
static ring(){
// ...
}
send(){}
}
class Child extends Course{
constructor(){
super()
}
fun() {}
}
解构
const shool = {
teacher:{
name:'',
age:30
},
leader:'',
name:'E'
}
const {
teacher:{
namge,
age
},
leader,
name:className
} = shool
-
- 结构使用场景
// 形参结构
const sum = arr =>{
let res = 0;
arr.forEach(each =>{
res += each;
})
}
// 结合初始值
const course = ({ teacher, leader, course = 'E'})=>{
// ...
}
course({
teacher:'AA',
leader:'BB'
})
// 返回值
const getCourse = () => {
return {
teacher:'',
leader:''
}
}
const { teacher, leader } = getCourse();
// 变量交换
let a = 1;
let b = 2;
[b, a]= [a, b]
//json处理
const json = "{ 'teacher': 'AA', 'leader': 'BB' }";
const {
teacher,
leader
} = JSON.parse(json)
// ajax
const {
code,
data,
msg
} = response;