前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,如今前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提高技术水平,打牢基础知识的中心思想,咱们开课啦(每周四)。javascript
放开我,我又要吐槽了。看到这个题目的时候,我十分的头秃。
那么我为何头秃呢?html
其实还有一个误区不是ES5的都归ES6。
其实想一想挺逗的。为何会有这样一个误区?ES2015出来的时候浏览器厂商支持就不同,ES2016出来以后支持仍是不同,ES201七、ES201八、ES2019 都是这样。这就出现了一个问题,发布是发布了,可是啥时候支持就不必定了。
这里放出来我前两天才看的文章,他们的更新速度是真的恐怖。前端
从提案到正式标准,须要经历五个阶段。每一个阶段的变更都须要由 TC39 委员会批准。vue
当前的全部提案,能够在 TC39 的官方网站查看。java
Babel 是一个 JavaScript 编译器。将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便可以运行在当前和旧版本的浏览器或其余环境中。下面列出的是 Babel 能作的事情:node
.babelrc
{ // presets字段设定转码规则 "presets": ["es2015", "react", "stage-2"], // 插件 "plugins": ["transform-decorators-legacy", "transform-class-properties"] }
官方已经针对经常使用环境编写了一些 preset:react
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,好比 Iterator
、Generator
、Set
、Map
、Proxy
、Reflect
、Symbol
、Promise
等全局对象,以及一些定义在全局对象上的方法(好比Object.assign
、Array.includes
)都不会转码。ios
因此咱们还须要使用 babel-polyfill
。git
后面的东西其实看不看无所谓,想要学习呢,仍是看阮一峰大佬的好了。
我这里说一下我认为ES6更新了一些什么东西。es6
在以前没有块级做用域的概念(try{}catch(e){}
能够模拟,性能呵呵呵呵)。此次加入了块级做用域的概念,let 变量,const 常量。
// 输出什么? for(var i = 0; i<4;i++){}; i // 4 // 输出什么? for(let i1 = 0; i1<4;i1++){}; i1 //Uncaught ReferenceError: i1 is not defined
你们都知道面试的时候,喜欢搞一些花里胡哨的鬼东西。
提高是说,var 会被提高到最前面执行,因此不会出现i is not defined
死区是说,let 定义的变量,不能在声明前使用。
(function(){ console.log(1, i) //1 4 //4来源于上面的测试例子,否则会是下面这个鬼样子 //Uncaught ReferenceError: i is not defined })(); (function(){ console.log(2, i) var i = 'lilnong.top' //2 undefined })(); (function(){ console.log(3, i) let i = 'lilnong.top' // Uncaught ReferenceError: Cannot access 'i' before initialization })();
window
,但 Node 和 Web Worker 没有window
。self
也指向顶层对象,可是 Node 没有self
。global
,但其余环境都不支持。因此提供了一个访问顶层对象的属性。
let [a, b, c] = [1, 2, 3];
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }
const [a, b, c, d, e] = 'hello'
函数参数的解构赋值(这个比较经常使用)
axios('https://www.lilnong.top/cors/axios-destructuring') .then(({data})=>console.log(data))
// y取默认值,而后入参第一个的默认值是{} function move({x = 0, y = 0} = {}) { return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, 0] move({}); // [0, 0] move(); // [0, 0]
// y没有默认值,第一个入参的默认值是{ x: 0, y: 0 } function move({x, y} = { x: 0, y: 0 }) { return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, undefined] move({}); // [undefined, undefined] move(); // [0, 0]
只能说写起来更爽了。而后就是以前的写法其实不是很好。会浪费空间,效率不高。${Math.random()}-${Date.now()}-lilnong.top
面向国际化,以及 emoji
。JavaScript 内部,字符以 UTF-16 的格式储存,每一个字符固定为2
个字节。对于那些须要4
个字节储存的字符(Unicode 码点大于0xFFFF
的字符),JavaScript 会认为它们是两个字符。
这里有个小插曲,weex 中 Text 组件没法包含 Image 组件,实现流式排列。(富文本组件好像是能够解决)
在实现这个功能的时候,我想到能够把字变成块,而后flex 容许换行。
测试地址,里面用了两种方案来获取大于Oxffff
的字符。
0xFFFF
,须要跳字节。charCodeAt
是ES5就支持的,只能拿到小于OxFFFF
。includes、startsWith、endsWith、repeat、padStart、padEnd、trimStart、trimEnd、matchAll
随着原生提供的 API 愈来愈多,咱们慢慢的不须要使用 Loadsh 等工具库。
JavaScript 语言的正则表达式,只支持先行断言(lookahead)和先行否认断言(negative lookahead),不支持后行断言(lookbehind)和后行否认断言(negative lookbehind)。ES2018 引入 后行断言,V8 引擎 4.9 版(Chrome 62)已经支持。
“先行断言”指的是,x
只有在y
前面才匹配,必须写成/x(?=y)/
。好比,只匹配百分号以前的数字,要写成/\d+(?=%)/
。“先行否认断言”指的是,x
只有不在y
前面才匹配,必须写成/x(?!y)/
。好比,只匹配不在百分号以前的数字,要写成/\d+(?!%)/
。
ECMAScript 6 入门 - 后行断言 - 阮一峰
更多的API Number.isFinite()、Number.isNaN()、Number.parseInt()、Number.parseFloat()、Number.isInteger()、Number.isSafeInteger()、Number.EPSILON、Number.isSafeInteger()
咱们知道,函数调用会在内存造成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。若是在函数A
的内部调用函数B
,那么在A
的调用帧上方,还会造成一个B
的调用帧。等到B
运行结束,将结果返回到A
,B
的调用帧才会消失。若是函数B
内部还调用函数C
,那就还有一个C
的调用帧,以此类推。全部的调用帧,就造成一个“调用栈”(call stack)。
递归很是耗费内存,由于须要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来讲,因为只存在一个调用帧,因此永远不会发生“栈溢出”错误。
(()=>arguments)(1,2,3) // 输出什么?Uncaught ReferenceError: arguments is not defined
在兼容函数中arguments没法使用
((...args)=>args)(1,2,3) //有输出什么?[1, 2, 3]
咱们可使用...
来把入参收集起来
((a,...args)=>args)(1,2,3) //[2, 3]
甚至咱们前面用变量接收,后面总体用...
接收
this
指向定义时所在的对象arguments
对象举一个例子你就知道了。去重,虽然这个方法有局限性吧。[...new Set([12, 2, 3, 12, 31, 2, 11, 2, 1, 2, 1, 21, 1, 2, 3, 1, 23, 12, 3, 12, 31, 11, 1, 2, 2, 31, 2, 3])]
Array.from()、Array.of()、Array.prototype.copyWithin()、Array.prototype.find()、Array.prototype.findIndex()、Array.prototype.fill()、Array.prototype.entries()、Array.prototype.keys()、Array.prototype.values()、Array.prototype.includes()、Array.prototype.flat()、Array.prototype.flatMap()、
nodeList = document.querySelectorAll('div'); // ES5的写法 [].slice.call(nodeList); // ES6的写法 Array.from(nodeList);
当我看到下面的写法的时候,心里是卧槽的。
GET_USER_INFO = 'getBaseUserInfo' obj = { [GET_USER_INFO](){// 第一次看到是vuex里面分开定义获取数据 console.log(arguments) }, 'abc.sdf'(){// vue watch监听改变的时候 console.log(arguments) } }
Object.is()、Object.assign()、Object.getOwnPropertyDescriptors()、Object.setPrototypeOf()、Object.getPrototypeOf()、Object.keys()、Object.values()、Object.entries()、Object.fromEntries()
Symbol、Set、Map、Proxy、Reflect、Promise、Iterator、Generator、async、Class、Module
简直了。太多了