es6中有哪些新特性:
新的變量聲明方式 let/const
// 沒有變量提升
console.log(a); //error
let a = 3;
// 增加了塊級作用域
{
let b = 10
console.log(b);
}
console.log(b); // error
我們常常使用let來聲明一個值會被改變的變量运杭,而使用const來聲明一個值不會被改變的變量,也可以稱之為常量专甩。
const a = 5;
a = 7; // Uncaught TypeError: Assignment to constant variable.
const b = {};
b.a = 5 ; //ok can change
b = []; // Uncaught TypeError: Assignment to constant variable.
如何實現(xiàn)const定義的引用類型也不能改變运沦?
https://mathiasbynens.be/notes/es6-const
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
// 結合freeze和const
const foo = Object.freeze({
'bar': 27
});
箭頭函數(shù)的使用
//其次還有一個至關重要的一點,那就是箭頭函數(shù)中配深,沒有this。如果你在箭頭函數(shù)中使用了this嫁盲,那么該this一定就是外層的this篓叶。
var a = ()=> {
// do something
}
模板字符串
var a = 'world';
var b = `hello ${a}`;
解析結構
const props = {
className: 'tiger-button',
loading: false,
clicked: true,
disabled: 'disabled'
}
const {loading, clicked} = props;
默認參數(shù)
function add(num1=10,num2=20){
return num1 + num2;
}
擴展運算符
在ES6中用...
來表示展開運算符,它可以將數(shù)組方法或者對象進行展開
var a = [1,2,3];
var b = [...a, 4,5,6];
function addAll(...num){
return num.reduce((num1,num2)=>{return num1 + num2})
}
對象字面量簡寫
// 如果變量名和屬性值相同時
var name = 'zhangzhuo';
var age = 18;
// es6
const person = {
name,
age
}
// es5
person1 = {
name: name,
age: age
}
// 在對象字面量中可以使用中括號作為屬性羞秤,表示屬性名也能是一個變量了缸托。
const person = {
[name]: true,
[age]: true
}
class
// es6
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
sayName(){
console.log(this.name)
}
}
//es5
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
console.log(this.name)
}
繼承extends
// es6
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
sayName(){
console.log(this.name)
}
}
class Student extends Person{
constructor(name, age, gender, classes) {
super(name, age);
this.gender = gender;
this.classes = classes;
}
getGender() {
return this.gender;
}
}
// es5
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
console.log(this.name)
}
function Student(name, age, gender, classes){
Person.call(this,name,age);
this.gender = gender;
this.classes = classes;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.getGender = function(){
return this.gender;
}
Promise
var getJson = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(1000);
console.log(1)
}, 1000)
})
}
var getJson2 = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(1000);
console.log(2)
}, 1000)
})
}
getJson().then(function(){
return getJson2()
}).then(function(){
console.log(33333)
});
then之后return是一個新的promise
es7 Async/await語法
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test();
模塊 modules
引入模塊
import test from './test'
-
import
表示引入一個模塊, - test 我們暫時理解為引入模塊的名字瘾蛋,
- from表示從哪里引入
-
./test
為./test.js
的簡寫俐镐,表示將要引入模塊的路徑
對外提供接口
// test.js
const num = 20;
const arr = [1, 2, 3, 4];
const obj = {
a: 0,
b: function() {}
}
const foo = () => {
const a = 0;
const b = 20;
return a + b;
}
export default {
num,
arr,
obj,
foo
}
在test.js
中,我們使用export default
對包暴露了一個對象哺哼。他的意思就是當我們使用import test from './test'
時佩抹,這個test對象就默認等于export default
暴露的對象。
我們還可以在test.js中取董,僅僅通過export
暴露幾個方法與屬性棍苹,我們來看看index.js中test會變成什么樣子。
// src/test.js
export const bar = () => {}
export const zcar = 12345;
保存運行后茵汰,我們發(fā)現(xiàn)枢里,index.js中的test對象并沒有變化,因為它僅僅等于export default
拋出的對象蹂午,因此栏豺,為了獲得模塊test.js
暴露的所有接口,我們得通過如下的方式豆胸。
// src/index.js
import * as test from './test';
其中的 *
表示所有奥洼,這是比較常用的通配符,as表示別名配乱,* as test
的意思是將test.js暴露的所有接口組成的對象溉卓,命名為test皮迟。那么我們在index.js中l(wèi)og出test,結果就如下桑寨。
如果大家還記得前面一篇文章里伏尼,我所講的ES6解析結構的語法,那么對于如下的用法相信就不難理解尉尾。
// src/index.js
import test, { bar, zcar } from './test';
console.log(test);
console.log('bar:', bar);
console.log('zcar:', zcar);
test爆阶,仍然表示為export default
暴露的對象,而 { bar, zcar }
則表示利用解析結構的語法沙咏,從整個返回對象中去取得對應的接口辨图。輸出結果也就很清晰了。
這種方式還是比較常見肢藐,比如我們在使用react時故河,常常這樣使用:
import React, { Component } from 'react'
它其實暗示了React的封裝方式,也暗示了我們應該如何去封裝我們的模塊吆豹。
webpack的優(yōu)化
引用自https://segmentfault.com/a/1190000007891318
方案一鱼的、合理配置 CommonsChunkPlugin
webpack的資源入口通常是以entry為單元進行編譯提取,那么當多entry共存的時候痘煤,CommonsChunkPlugin的作用就會發(fā)揮出來凑阶,對所有依賴的chunk進行公共部分的提取,但是在這里可能很多人會誤認為抽取公共部分指的是能抽取某個代碼片段衷快,其實并非如此宙橱,它是以module為單位進行提取。
假設我們的頁面中存在entry1蘸拔,entry2师郑,entry3三個入口,這些入口中可能都會引用如utils都伪,loadash呕乎,fetch等這些通用模塊,那么就可以考慮對這部分的共用部分機提取陨晶。通常提取方式有如下四種實現(xiàn):
1猬仁、傳入字符串參數(shù),由chunkplugin自動計算提取
new webpack.optimize.CommonsChunkPlugin('common.js')
這種做法默認會把所有入口節(jié)點的公共代碼提取出來, 生成一個common.js
2先誉、有選擇的提取公共代碼
new webpack.optimize.CommonsChunkPlugin('common.js',['entry1','entry2']);
只提取entry1節(jié)點和entry2中的共用部分模塊, 生成一個common.js
3湿刽、將entry下所有的模塊的公共部分(可指定引用次數(shù))提取到一個通用的chunk中
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
minChunks: function (module, count) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
});
提取所有node_modules中的模塊至vendors中,也可以指定minChunks中的最小引用數(shù)褐耳;
4诈闺、抽取enry中的一些lib抽取到vendors中
entry = {
vendors: ['fetch', 'loadash']
};
new webpack.optimize.CommonsChunkPlugin({
name: "vendors",
minChunks: Infinity
});
添加一個entry名叫為vendors,并把vendors設置為所需要的資源庫铃芦,CommonsChunk會自動提取指定庫至vendors中雅镊。
方案二襟雷、通過 externals 配置來提取常用庫
在實際項目開發(fā)過程中,我們并不需要實時調試各種庫的源碼仁烹,這時候就可以考慮使用external選項了耸弄。
簡單來說external就是把我們的依賴資源聲明為一個外部依賴,然后通過script外鏈腳本引入卓缰。這也是我們早期頁面開發(fā)中資源引入的一種翻版计呈,只是通過配置后可以告知webapck遇到此類變量名時就可以不用解析和編譯至模塊的內部文件中,而改用從外部變量中讀取征唬,這樣能極大的提升編譯速度捌显,同時也能更好的利用CDN來實現(xiàn)緩存。
external的配置相對比較簡單总寒,只需要完成如下三步:
1扶歪、在頁面中加入需要引入的lib地址,如下:
<head>
<script src="http://cdn.bootcss.com/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/underscore.min.js"></script>
<script src="/static/common/react.min.js"></script>
<script src="/static/common/react-dom.js"></script>
<script src="/static/common/react-router.js"></script>
<script src="/static/common/immutable.js"></script>
</head>
2摄闸、在webapck.config.js中加入external配置項:
module.export = {
externals: {
'react-router': {
amd: 'react-router',
root: 'ReactRouter',
commonjs: 'react-router',
commonjs2: 'react-router'
},
react: {
amd: 'react',
root: 'React',
commonjs: 'react',
commonjs2: 'react'
},
'react-dom': {
amd: 'react-dom',
root: 'ReactDOM',
commonjs: 'react-dom',
commonjs2: 'react-dom'
}
}
}
適用場景
在實際的開發(fā)過程中击罪,可靈活地選擇適合自身業(yè)務場景的優(yōu)化手段。
優(yōu)化手段 | 開發(fā)環(huán)境 | 生產(chǎn)環(huán)境 |
---|---|---|
CommonsChunk | √ | √ |
externals | √ | |
DllPlugin | √ | √ |
Happypack | √ | |
uglify-parallel | √ |
event中target和currentTarget的區(qū)別贪薪?
document.body.onclick = function(event){
}
this和currentTarget都等于document.body。 然而target指向真正觸發(fā)的元素眠副。
css讓元素垂直居中
有2個元素画切,讓子元素相對于父元素水平垂直居中。
<div class="box">
<div class="innerbox">css設置元素水平垂直居中顯示</div>
</div>
已知元素的寬度
1囱怕、利用定位及設置元素margin值為自身的一半
.box{
width: 400px;
height: 200px;
border: 5px solid #ddd;
margin: 50px auto;
position: relative;
}
.innerbox{
width: 300px;
height: 100px;
border: 5px solid #f00;
font-size: 16px;
position: absolute;
left: 50%;
top: 50%;
margin: -50px 0 0 -150px;
說明:此方法霍弹,在我們工作中經(jīng)常用到,兼容性好娃弓。demo
2典格、margin:auto
.box{
width: 400px;
height: 200px;
border: 5px solid #ddd;
margin: 50px auto;
position: relative;
}
.innerbox{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 300px;
height: 100px;
margin: auto;
border: 5px solid #f00;
}
說明: position: absolute; left: 0; right: 0; top: 0; bottom: 0;這是自動填充父元素的可用空間。然而給子元素設定了寬高台丛,那么多余的空間耍缴,會被margin:auto平均分配。
實現(xiàn)未知元素寬高
1挽霉、利用css3屬性transform實現(xiàn)
.box{
width: 400px;
height: 200px;
border: 5px solid #ddd;
margin: 50px auto;
position: relative;
}
.innerbox{
position: absolute;
left: 50%;
top: 50%;
border: 5px solid #f00;
transform: translate(-50%,-50%);
}
說明:這種方法在移動端被廣泛使用防嗡。但是,只支持高版本瀏覽器(IE9+以上的瀏覽器支持)侠坎。
2蚁趁、將父元素設置成display: table, 子元素設置為單元格 display: table-cell
這個方法跟上面介紹的方法不同,它不是讓元素居中实胸,而是讓元素包含的內容居中
.box{
width: 400px;
height: 200px;
border: 5px solid #ddd;
margin: 50px auto;
display: table;
}
.innerbox{
display: table-cell;
vertical-align: middle;
text-align: center;
border: 5px solid #f00;
}
說明:利用表格的特性他嫡,將子元素看成行內元素番官,實現(xiàn)元素中的文字(文字可以是單行的,也可以是多行的)或圖片水平垂直居中钢属。demo
3徘熔、css3新的布局方法,彈性布局 display: flex
.box{
width: 400px;
height: 200px;
border: 5px solid #ddd;
margin: 50px auto;
display: flex;
align-items: center;
justify-content: center;
}
.innerbox{
width: 300px; /*寬度可以省略*/
height: 100px; /*高度可以省略*/
border: 5px solid #f00;
font-size: 16px;
}
說明: 此方法只支持IE9+以上的瀏覽器署咽。display: flex代表彈性布局近顷,align-items: center 代表垂直方向上的居中,justify-content: center代表水平方向上的居中宁否。這些是css3中的新屬性窒升,感興趣的同學可以查找相關資料學習。這里不多介紹慕匠。demo
移動端300ms延遲的解決方案
原來的解決方案:fastclick
其實現(xiàn)在已經(jīng)不需要了饱须, 瀏覽器自己做了處理:
https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away?hl=en
lib-flexible的多分辨率解決方案
引用項目里面的話https://github.com/amfe/lib-flexible
由于
viewport
單位得到眾多瀏覽器的兼容,lib-flexible
這個過渡方案已經(jīng)可以放棄使用台谊,不管是現(xiàn)在的版本還是以前的版本蓉媳,都存有一定的問題。建議大家開始使用viewport
來替代此方案锅铅。vw
的兼容方案可以參閱《如何在Vue項目中使用vw實現(xiàn)移動端適配》一文酪呻。
在內在都用vw單位了, 關于rem中的問題可以參考:談談 rem 與 vw -- rem