在学习javascript中感觉这个语言的变化太快了,发现系统学的效率很低,所以在学完传统三大件之后就自己整理了一个ES6到ES11常用的改变,内容比较杂可以看目录
观前提醒:
本文创作的目的是搭建一个传统三大件和框架之间的桥梁,少绕弯路,省去大部分的前端学习时间
本文默认读者会使用简单的html,css,javascript ,并且由于我自己的方向主要是后端java,所以有些内容都会用java比较,会一点java语法最好了
至于前后端交互的内容,如果学习过ajax等会观看得更加轻松,没学过也可以适当跳过文中我建议跳过的部分,可以在学过之后再来补充,相信你会有不一样的感受
let和const let 声明变量 1 2 3 4 let a;let b,c,d;let e = 100 ;let f = 521 , g = 'iloveyou' , h = [];
特点:
变量不能重复声明
块儿级作用域
不存在变量提升
1 2 console .log (singer);var singer = "日向文" ;
上面这种就叫做变量提升,即在输出后定义,var可行而let不可行
const
1 2 3 const TEAM = ['UZI' ,'MXLG' ,'Ming' ];TEAM .push ('Meiko' );
解构赋值 ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值
1 2 3 4 5 6 7 8 9 10 11 const F4 = ['小沈阳' ,'刘能' ,'赵四' ,'宋小宝' ];let [xiao, liu, zhao, song] = F4 ;console .log (xiao);console .log (liu);console .log (zhao);console .log (song);
1 2 3 4 5 6 7 8 9 const zhao = { name : '赵本山' , age : '不详' , xiaopin : function ( ){ console .log ("我可以演小品" ); } }; let {xiaopin} = zhao;xiaopin ();
注意上面对象的解构需要属性名一致
模板字符串 ES6 引入新的声明字符串的方式:反引号
声明 1 2 let str = `我也是一个字符串哦!` ;console .log (str, typeof str);
1 2 3 4 5 6 let str = `<ul> <li>沈腾</li> <li>玛丽</li> <li>魏翔</li> <li>艾伦</li> </ul>` ;
变量拼接 1 2 3 let lovest = '魏翔' ;let out = `${lovest} 是我心目中最搞笑的演员!!` ;
简化对象写法 ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的书写更加简洁
1 2 3 4 5 6 7 8 9 10 11 12 let name = '尚硅谷' ; let change = function ( ){ console .log ('我们可以改变你!!' ); } const school = { name, change, improve ( ){ console .log ("我们可以提高你的技能" ); } }
箭头函数
1 2 3 4 5 6 let fn = (a,b ) => { return a + b; } let result = fn (1 , 2 );console .log (result);
this 是静态的 ,this 始终指向函数声明时所在作用域下的 this 的值。
1 2 3 4 5 6 7 8 9 10 11 12 function getName ( ){ console .log (this .name ); } let getName2 = ( ) => { console .log (this .name ); } window .name = '哈哈哈' ; const kaixin = { name = "hahaha" } getName.call (kaixin); getName2.call (kaixin);
1 2 3 4 5 6 let Person = (name, age ) => {this .name = name;this .age = age;} let me = new Person ('xiao' ,30 );console .log (me);
箭头函数的简写 省略小括号, 当形参有且只有一个的时候 1 2 3 4 let add = n => { return n + n; } console .log (add (9 ));
省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略,而且语句的执行结果就是函数的返回值 1 2 let pow = n => n * n;console .log (pow (8 ));
参数默认值 ES6 允许给函数参数赋值初始值
1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则) 1 2 3 4 5 function add (a,b,c=10 ) { return a + b + c; } let result = add (1 ,2 );console .log (result);
2. 与解构赋值结合 1 2 3 4 5 6 7 8 9 10 11 12 function connect ({host="127.0.0.1" , username,password, port} ){ console .log (host) console .log (username) console .log (password) console .log (port) } connect ({ host : 'atguigu.com' , username : 'root' , password : 'root' , port : 3306 })
rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
1 2 3 4 function date ( ){ console .log (arguments ); } date ('白芷' ,'阿娇' ,'思慧' );
1 2 3 4 5 6 7 8 function date1 (...args ){ console .log (args); } function date2 (a,...args ){ console .log (args); } date1 ('阿娇' ,'柏芝' ,'思慧' );date2 ('阿娇' ,'柏芝' ,'思慧' );
spread扩展运算符 简介 『…』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
1 2 3 4 5 6 const three = ['死神' ,'火影' ,'海贼王' ];function jingdian ( ){ console .log (arguments ); } jingdian (...three);
应用
1 2 3 4 5 const kuaizi = ['王太利' ,'肖央' ];const fenghuang = ['曾毅' ,'玲花' ];const zuixuanxiaopingguo = kuaizi.concat (fenghuang);const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];console .log (zuixuanxiaopingguo);
1 2 3 const sanzhihua = ['E' ,'G' ,'M' ];const sanyecao = [...sanzhihua];console .log (sanyecao);
1 2 3 const divs = document .querySelectorAll ('div' );const divArr = [...divs];console .log (divArr);
Symbol 说实在的,讲的不好,这块不是很重点,推荐两个博客
在看之前明确几个概念
javascript里的对象本质就是键值对,左侧是键右侧是值,即左侧其实是一个字符串,如name: “张三”其实也可以写作”name”: “张三”,只是平常忽略了双引号
javascript中的对象调用内部属性和方法不仅可以用.还可以用[],如student.name和student[“name”]效果相同
以上知识不是ES6的内容,如果有疑问建议重学javascript高级
放推荐博客
https://www.cnblogs.com/sker/p/5474591.html
https://blog.csdn.net/qq_41694291/article/details/103322409?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167016723116782425175146%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167016723116782425175146&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-103322409-null-null.142
看完他们对Symbol有个大概了解即可
至此,java里的七大基本类型字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol 已经全部出现,其他的均为引用类型,论本质是对象(数组本质也是对象,这点也是javascript本篇的内容)
迭代器 和java很像但接口调用不一样,这里其实也讲得一般但是不重要
迭代器声明使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const xiyou = ['唐僧' ,'孙悟空' ,'猪八戒' ,'沙僧' ];for (let v of xiyou){ console .log (v); } let iterator = xiyou[Symbol .iterator ]();console .log (iterator.next ());console .log (iterator.next ());console .log (iterator.next ());console .log (iterator.next ());console .log (iterator.next ());
迭代器的自定义遍历
这里内容有点难,而且用处不大,可以以后再看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const banji = { name : "终极一班" , stus : [ 'xiaoming' , 'xiaoning' , 'xiaotian' , 'knight' ], [Symbol .iterator ]() { let index = 0 ; let _this = this ; return { next : function ( ) { if (index < _this.stus .length ) { const result = { value : _this.stus [index], done : false }; index++; return result; }else { return {value : undefined , done : true }; } } }; } } for (let v of banji) { console .log (v); }
生成器 生成器函数 这里需要一定的异步编程基础 ,如果没学可以先跳过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function * leimu ( ){ console .log ("leimu" ); } let iterator = leimu ();console .log (iterator.next ()); function * gen ( ){ console .log (111 ); yield '一只没有耳朵' ; console .log (222 ); yield '一只没有尾部' ; console .log (333 ); yield '真奇怪' ; console .log (444 ); } let iterator = gen (); console .log (iterator.next ()); console .log (iterator.next ());console .log (iterator.next ());console .log (iterator.next ());
生成器函数参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function * gen (arg ){ console .log (arg); let one = yield 111 ; console .log (one); let two = yield 222 ; console .log (two); let three = yield 333 ; console .log (three); } let iterator = gen ('AAA' ); console .log (iterator.next ()); console .log (iterator.next ('BBB' )); console .log (iterator.next ('CCC' )); console .log (iterator.next ('DDD' ));
案例就不写了,感觉这个用处真的不大
Promise 划重点!!! 这个对异步编程很重要,学没学过都可以看看
这里打算参考另一篇博客写下
Promise基本语法 定义 1 2 3 4 5 6 7 8 let p = new Promise ((resolve, reject ) => { setTimeout (() => { console .log ('执行完成' ); resolve ('我是成功!!' ); }, 2000 ); });复制代码
如上,我们已经发现了Promise其实就是一个对象,对象的构造函数参数是一个函数 用来实现异步操作,而作为参数的这个函数中又要有两个参数,分别是
resolve :异步操作执行成功后的回调函数
reject:异步操作执行失败后的回调函数
其实就是无限套娃,对象的参数是一个函数,函数的参数又是两个函数
该对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)
如果Promise的参数函数中调用了resolve,promise状态置为已成功
如果Promise参数函数中调用了reject,promise状态置为已失败
调用 promise 对象的 then 方法 Promise对象中有一个至关重要的方法叫then
Promise,顾名思义,是一个承诺,而之所以叫承诺就是因为在Promise确定状态后会调用then里面的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 let p = new Promise ((resolve, reject ) => { setTimeout (function ( ){ var num = Math .ceil (Math .random ()*10 ); if (num<=5 ){ resolve (num); } else { reject ('数字太大了' ); } }, 2000 ); }); p.then ((data ) => { console .log ('resolved' ,data); },(err ) => { console .log ('rejected' ,err); } ); p.then ((data1 ) => { console .log (data1); }) .then ((data2 ) => { console .log (data2); }) .then ((data3 ) => { console .log (data3); }); let promise = new Promise (function (resolve, reject ) { console .log ('Promise' ); resolve (); }); promise.then (function ( ) { console .log ('resolved.' ); }); console .log ('Hi!' );
这里如果还是没听懂,那建议还是先学完前后端交互再来看,了解了实际的应用场景后可能会对Promise有更深的理解
Promise的catch方法 Promise对象除了then方法,还有一个catch方法,它和then的第二个参数一样,用来指定reject的回调,用法如下
1 2 3 4 5 p.then ((data ) => { console .log ('resolved' ,data); }).catch ((err ) => { console .log ('rejected' ,err); });
Promise的all方法 Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
1 2 3 4 5 6 7 8 9 10 11 let Promise1 = new Promise (function (resolve, reject ){})let Promise2 = new Promise (function (resolve, reject ){})let Promise3 = new Promise (function (resolve, reject ){})let p = Promise .all ([Promise1 , Promise2 , Promise3 ])p.then (funciton ( ){ }, function ( ){ })
到这其实大致Promise对象用法就明确了,强烈建议在学完前后端交互之后再来看看,会有不一样的体会
Set集合 和java类似的机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let s = new Set ();let s2 = new Set (['大事儿' ,'小事儿' ,'好事儿' ,'坏事儿' ,'小事儿' ]);console .log (s2.size );s2.add ('喜事儿' ); s2.delete ('坏事儿' ); console .log (s2.has ('糟心事' ));s2.clear (); console .log (s2);for (let v of s2){ console .log (v); }
Map集合 类似于对象也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象都可以当做键,和java类似)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 let m = new Map (); m.set ('name' ,'尚硅谷' ); m.set ('change' , function ( ){ console .log ("我们可以改变你!!" ); }); let key = {school : 'ATGUIGU' }; m.set (key, ['北京' ,'上海' ,'深圳' ]); console .log (m.size ); m.delete ('name' ); console .log (m.get ('change' )); console .log (m.get (key)); m.clear (); for (let v of m){ console .log (v); } console .log (m);
class类 这下和java几乎一样的
学习之前如果没有搞清楚隐式原型对象和显式原型对象建议看这篇博客https://blog.csdn.net/cc18868876837/article/details/81211729?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167025642416800186588381%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167025642416800186588381&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-81211729-null-null.142
介绍和基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 function Phone (brand, price ){ this .brand = brand; this .price = price; } Phone .prototype .call = function ( ){ console .log ("我可以打电话!!" ); } let Huawei = new Phone ('华为' , 5999 ); Huawei .call (); console .log (Huawei ); class Shouji { constructor (brand, price ){ this .brand = brand; this .price = price; } call ( ){ console .log ("我可以打电话!!" ); } } let onePlus = new Shouji ("1+" , 1999 ); console .log (onePlus);
类的静态成员 和java一致,都是static,不多说了
类的继承 ES5构造函数的继承 复习一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function Phone (brand, price ){ this .brand = brand; this .price = price; } Phone .prototype .call = function ( ){ console .log ("我可以打电话" ); } function SmartPhone (brand, price, color, size ){ Phone .call (this , brand, price); this .color = color; this .size = size; } SmartPhone .prototype = new Phone ; SmartPhone .prototype .constructor = SmartPhone ; SmartPhone .prototype .photo = function ( ){ console .log ("我可以拍照" ) } SmartPhone .prototype .playGame = function ( ){ console .log ("我可以玩游戏" ); } const chuizi = new SmartPhone ('锤子' ,2499 ,'黑色' ,'5.5inch' ); console .log (chuizi);
ES6-Class类继承 这个也和java一模一样…
class里的get和set 这里和java有一点点不一样,java的class没这么智能,得自己调用get和set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Phone { get price (){ console .log ("价格属性被读取了" ); return 'iloveyou' ; } set price (newVal ){ console .log ('价格属性被修改了' ); } } let s = new Phone ();console .log (s.price );s.price = 'free' ;
模块化 重点又来了
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
ES6 模块化语法 模块功能主要由两个命令构成:export 和 import
export 命令用于规定模块的对外接口
import 命令用于输入其他模块提供的功能
导入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import * as m1 from "./src/js/m1.js" ;console .log (m1);import * as m2 from "./src/js/m2.js" ;console .log (m2);import * as m3 from "./src/js/m3.js" ;console .log (m3);m3.defalut .love (); ----------------------------------------------------分割线----------------------------------------------------------------- import {school,love} from "./src/js/m1.js" ;import {school as jiu,love as you} from "./src/js/m2.js" ;import {default as m3} from "./src/js/m3.js" ;console .log (school);console .log (jiu);console .log (m3);----------------------------------------------------分割线----------------------------------------------------------------- import m3 from "./src/js/m3.js" console .log (m3);
暴露 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 在m1文件下 export let school = "jiu" ;export function love ( ){ console .log ("you" ); } 在m2文件下 let school = "jiu" ;function love ( ){ console .log ("you" ); } export {school,findJob}在m3文件下 export default { school = "jiu" love:function ( ){ console .log ("you" ); } }
引入具体方式
1 2 3 <script type="module" > 在这里面写import 语句 </script>
1 2 <script src="./src/js/app.js" type="module" ></script> 然后在app.js 文件里面写import 语句
async和await 又是重点 ,不过到这里已经是ES8的内容了,并且涉及到一定的异步编程知识
async和await的出现是为了让异步代码像同步代码一样
async函数
async函数的返回值是Promise对象
Promise对象的结果有async函数执行的返回值决定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 async function fn1 ( ){ return "不想学习" ; } async function fn2 ( ){ throw new Error ("出错了!" ); } async function fn3 ( ){ return new Promise (() => { resolve ("成功的数据" ); }); } const result1 = fn1 ();const result2 = fn2 ();const result3 = fn3 ();console .log (result1);console .log (result2);console .log (result3);
如上,输出的Promise对象里只要async函数return后面不是Promise对象且不是抛出错误,返回的Promise对象就是成功的;抛出错误肯定是失败的;async函数return后面的是Promise对象就和这个Promise的状态一致
await表达式 awiat表达式只能放在async函数里面,但async函数中可以没有await
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const p1 = new Promise ((resolve,reject ) => { resolve ("我是成功的值!" ); }) const p2 = new Promise ((resolve,reject ) => { reject ("我是失败的值!" ); }) async function main ( ){ let result1 = await p1; console .log (result1) try { let result2 = await p2; }catch (e){ consolo.log (e); } } main ();
结合ajax对比Promise和async,await组合区别 这里如果没学过前后端交互可以跳过,只是为了更方便理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function sendAJAX (url ){ return new Promise (() => { const x = new XMLHttpRequest (); x.open ('GET' ,url); x.send (); x.onreadystatechange = function ( ){ if (x.readystate === 4 ){ if (x.status >= 200 && x.status < 300 ){ resolve (x.response ); }else { reject (x.status ); } } } }) } sendAJAX ("http://..." ).then (value => { console .log (value); }, reason => {}); async function main ( ){ let result = await sendAJAX ("http://..." ); console .log (result); }
私有属性 这是ES11新增的
1 2 3 4 5 6 7 function Person (name,age,weight ){ this .name = name; this .#age = age; this .#weight = weight; } const girl = new Person ("小红" , 18 , "45kg" );console .log (girl.#age);
ES6的class也是同理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Person { name; #age; #weight; constructor ( ){ this .name = name; this .#age = age; this .#weight =weight; } } const girl = new Person ("小红" ,18 ,"45kg" ); console .log (girl.#age);
那么到这里本文就暂且告一段落了,如果没有学习前后端交互的可以去学习前后端交互,学过了建议直接跳去框架Vue等进行学习,在掌握了本文内容后框架的学习将变得格外轻松
欢迎大家评论区交流学习