阮一峰es6研習(xí)

精通javascript

參考文獻(xiàn)(兩個文檔混合看,非常有用)
  1. 阮一峰 es6 :http://es6.ruanyifeng.com/#docs/object
  2. MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects
  3. webpack打包:https://segmentfault.com/a/1190000006178770#articleHeader3
  4. 廖雪峰的js教程:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434499763408e24c210985d34edcabbca944b4239e20000
  5. over
node.js

javascript : BOM DOM ECMASCRIPT

DOM:節(jié)點和屬性、增刪改查、事件

HTML

CSS

框架:JQuery、Vue、Wepy、Angular

快速學(xué)習(xí)能力

參考文獻(xiàn):http://www.w3school.com.cn/htmldom/dom_intro.asp

DOM
  1. getElementById(id)
  2. appendChild(node)
  3. removeChild(node)
  4. innerHTML
  5. parentNode
  6. childNodes
  7. attributes
JQuery
  1. jquery 安裝

  2. jquery語法

    $(document).ready(function(){
    
    --- jQuery functions go here ----
    
    });
    
  3. jquery 選擇器

  4. jquery事件

  5. jquery 效果

  6. jquery HTML處理

  7. over

nodejs支持es6
'use strict'//加上這句聲明
$ node test.js
let和const
{
    let b = 100;
    var c = 1;
}
console.log(b);//b is not defined
let命令所在的代碼塊內(nèi)有效。
for循環(huán)的計數(shù)器,就很合適使用let命令。

var array = ['gaolong', 'xiaoming', 'xiaoli'];
for (let i = 0; i < array.length; i++) {}
console.log(i); //i is not defined, i只在for循環(huán)體內(nèi)有效

var array = ['gaolong', 'xiaoming', 'xiaoli'];
var a = [];
for (let i = 0; i < array.length; i++) {
    a[i] = function () {
        console.log(i);
    }
}
a[2](); //此處數(shù)組中存放的是函數(shù),所以可以直接執(zhí)行a[i]();重點比較let i與 var i的不同

let不存在變量提升,var存在。即腳本未執(zhí)行前var變量已經(jīng)存在,只是值為undefined.

let暫時性死區(qū),temporal dead zone
var tmp = 123;
if (true) {
    tmp = 'abc'; //referenceError。該區(qū)域已經(jīng)被let 覆蓋。
    let tmp; 
}
let不允許在相同作用域內(nèi),重復(fù)聲明同一個變量。
因此,不能在函數(shù)內(nèi)部重新聲明參數(shù)。
ES5只有全局作用域和函數(shù)作用域,沒有塊級作用域.

因此會出現(xiàn)這兩種情況:
第一:內(nèi)層變量可能會覆蓋外層變量。
var tmp = new Date();
function f() {
    console.log(tmp);
    if (false) {
        var tmp = 'hello wolrd';
    }
}
f(); //undefined ,該使用let
'use strict';
if (true) {
  function f() {}
}
f(); // ReferenceError: f is not defined,es6函數(shù)在塊級作用域內(nèi),外部不能使用。
第二:用來計數(shù)的循環(huán)變量泄露為全局變量。

const
只讀常量,不能改變。
'use strict';
const pi = 3.14159;
pi // 3.14159
pi = 3; typeerror: pi is read-only
//如果是常規(guī)模式,不會報錯,但是賦值無效
//const 一旦聲明就必須賦值,const foo,報錯
const的作用域與let命令相同:只在聲明所在的塊級作用域內(nèi)有效。
const命令聲明的常量也是不提升,同樣存在暫時性死區(qū),只能在聲明的位置后使用
const聲明的常量,也與let一樣不可重復(fù)聲明。

對于復(fù)合類型的變量,變量名不指向數(shù)據(jù),而是指向數(shù)據(jù)所在的地址。const命令只是保證變量名指向的地址不變,并不保證該地址的數(shù)據(jù)不變,所以將一個對象聲明為常量必須非常小心。
const foo = {}
foo.prop = 123;
foo.prop ;// 123
foo = {} //type error ;foo is readonly
const a = [];
a.push('Hello');//ok
a.length = 0; //ok
a = ["schiller"]; //error
如果真的想將對象凍結(jié),應(yīng)該使用Object.freeze方法。

 全局對象屬性
 全局對象是最頂層的對象,在瀏覽器環(huán)境指的是window對象,在Node.js指的是global對象。ES5之中,全局對象的屬性與全局變量是等價的。
 var a = 1;
// 如果在Node的REPL環(huán)境,可以寫成global.a
// 或者采用通用方法,寫成this.a
window.a // 1

let b = 1;
window.b // undefined
上面代碼中,全局變量a由var命令聲明,所以它是全局對象的屬性;全局變量b由let命令聲明,所以它不是全局對象的屬性,返回undefined。

解構(gòu)賦值
//注意,解構(gòu)賦值在node環(huán)境中暫且無法運行,具體原因待探究,可以使用新建rn項目 //跑來測試
ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)。
var [a, b, c] = [1, 2, 3];
let [x, y, ...z] = ['a'];
// x = 'a', y = undefined, z = []
如果解構(gòu)不成功,變量的值就等于undefined。
如果等號右邊不是數(shù)組,嚴(yán)格的說不是可遍歷結(jié)構(gòu),那將會報錯。
//報錯
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
上面的表達(dá)式都會報錯,因為等號右邊的值,要么轉(zhuǎn)為對象以后不具備Iterator接口(前五個表達(dá)式),要么本身就不具備Iterator接口(最后一個表達(dá)式)
事實上,只要某種數(shù)據(jù)結(jié)構(gòu)具有Iterator接口,都可以采用數(shù)組形式的解構(gòu)賦值。
function* fibs() {
  var a = 0;
  var b = 1;
  while (true) {
   yield a;
    [a, b] = [b, a+b]; 
  }
}
var [first ,second, third, fourth, fifth, sixth] = fibs();
sixth //5
默認(rèn)值
var [foo = true] = [];
foo //true
ES6內(nèi)部使用嚴(yán)格相等運算符(===),判斷一個位置是否有值。所以,如果一個數(shù)組成員不嚴(yán)格等于undefined,默認(rèn)值是不會生效的。
如:
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'
var [x = 1] = [null] //x = null

對象的解構(gòu)賦值
解構(gòu)賦值還可以用于對象
var {foo, bar} = {foo: 'aaa', bar: 'bbb'};
// foo = 'aaa', bar = 'bbb'
對象的解構(gòu)與數(shù)組有一個重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值,如:
var {foo, bar} = {bar:'aaa', foo: 'bbb'};
//foo = "bbb", bar='aaa'
對象的解構(gòu)賦值的內(nèi)部機(jī)制,是先找到同名屬性,然后再賦給對應(yīng)的變量。真正被賦值的是后者,而不是前者。
var {foo: baz} = {foo:'aaa', bar:'bbb'}
//baz = 'aaa' //foo  error, foo is not defined
//類似var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
變量的聲明和賦值是一體的
對于let和const來說,變量不能重新聲明,所以一旦賦值的變量以前聲明過,就會報錯。
let foo;
let {foo} = {foo:1} //erro, duplicate declaration of foo
上面代碼中,解構(gòu)賦值的變量都會重新聲明,所以報錯了。不過,因為var命令允許重新聲明,所以這個錯誤只會在使用let和const命令時出現(xiàn)。如果沒有第二個let命令,上面的代碼就不會報錯。
let foo;
({foo} = {foo:1}) //ok
//允許嵌套s
var obj = {
      p: [
        "Hello",
        {y: 'world'} 
      ]
    };
 var {p:[x, {y}]} = obj;
//對象的解構(gòu)也可以指定默認(rèn)值,默認(rèn)值生效的條件是,對象的屬性值嚴(yán)格等于undefined

字符串的解構(gòu)賦值
const [a, b,c,d, e] = 'hello';//a ='h', ...
類似數(shù)組對象都有一個length
let {length : len} = 'hello';
len // 5
數(shù)值和布爾值得解構(gòu)賦值
解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
 
函數(shù)參數(shù)的解構(gòu)賦值
function add([x,y]) {
  return x + y;
} 
var arr = [[1, 2], [3, 4]].map(([a, b]) => a + b);

函數(shù)的解構(gòu)也可以使用默認(rèn)值
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]

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]
上面代碼是為函數(shù)move的參數(shù)指定默認(rèn)值,而不是為變量x和y指定默認(rèn)值,所以會得到與前一種寫法不同的結(jié)果。
解構(gòu)賦值用途
1、交換變量的值
[x, y] = [y, x]; 
2、 從函數(shù)返回多個值
// 返回一個數(shù)組
 
function example() {
  return [1, 2, 3];
}
var [a, b, c] = example();
 
// 返回一個對象
 
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
var { foo, bar } = example();
3、 函數(shù)參數(shù)的定義
// 參數(shù)是一組有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3])
// 參數(shù)是一組無次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1})
4、 提取JSON數(shù)據(jù)
var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
}
let { id, status, data: number } = jsonData;
 
console.log(id, status, number)
// 42, OK, [867, 5309]
 
5、 函數(shù)參數(shù)的默認(rèn)值
jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
}; 
6、 遍歷Map結(jié)構(gòu)  
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
 
for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
 
如果只想獲取鍵名,或者只想獲取鍵值,可以寫成下面這樣。    
// 獲取鍵名
for (let [key] of map) {
  // ...
}
 
// 獲取鍵值
for (let [,value] of map) {
  // ...
}    
7、 輸入模塊的指定方法    
const { SourceMapConsumer, SourceNode } = require("source-map"); 
字符串的擴(kuò)展
字符的Unicde表示法
codePointAt() //如果確實要處理字符
String.fromCodePoint()
字符串的遍歷器接口
at();
'abc'.at(0) // "a"
'??'.at(0) // "??"
normalize()
includes(), startsWidth(),endsWith()
傳統(tǒng)上,JavaScript只有indexOf方法,可以用來確定一個字符串是否包含在另一個字符串中。ES6又提供了三種新方法:
includes():返回布爾值,表示是否找到了參數(shù)字符串。
startsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的頭部。
endsWith():返回布爾值,表示參數(shù)字符串是否在源字符串的尾部。
var s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
//第二個參數(shù)表示搜索位置
var s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
repeat()
repeat方法返回一個新字符串,表示將原字符串重復(fù)n次。

es7提供補齊padStart(), padEnd()
'x'.padStart(5, 'ab').// 'ababx'
'x'.padEnd(4, 'ab').// 'xabab'

模板字符串
標(biāo)簽?zāi)0濉嵗0澹簳翰挥懻?
String.raw();

參考文獻(xiàn):
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Text_formatting
trim
repeat
normalize
toLowerCase, toUpperCase
match,replace,search
substring,substr
slice
split
contact
fromCharCode,fromCodePoint
startsWith,endsWith,includes
indexOf,lastIndexOf
charAt,charCodeAt,codePointAt
正則擴(kuò)展
RegExp構(gòu)造函數(shù)
var regex = new RegExp('xyz', 'i');
//等價
var regex = /xyz/i
或者
var regex = new RegExp(/xyz/i);
=> var regex = /xyz/i
es6:
new RegExp(/abc/ig, 'i').flags //'i'

字符串的正則方式:
字符串對象共有4個方法,可以使用正則表達(dá)式:match()、replace()、search()和split()。

正則匹配難度比較大,暫時不討論
數(shù)值類型
二進(jìn)制和八進(jìn)制的表示
ES6提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴0b(或0B)和0o(或0O)表示。
0b111110111 === 503 // true
0o767 === 503 // true
Number.isFinite() , NumberisNaN()
ES6在Number對象上,新提供了Number.isFinite()和Number.isNaN()兩個方法,用來檢查Infinite和NaN這兩個特殊值。
Number.isFinite()用來檢查一個數(shù)值是否非無窮(infinity)。
Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
Number.isNaN()用來檢查一個值是否為NaN。
它們與傳統(tǒng)的全局方法isFinite()和isNaN()的區(qū)別在于,傳統(tǒng)方法先調(diào)用Number()將非數(shù)值的值轉(zhuǎn)為數(shù)值,再進(jìn)行判斷,而這兩個新方法只對數(shù)值有效,非數(shù)值一律返回false。

Number.parseInt(), Number.parseFloat()
// ES5的寫法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45

// ES6的寫法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

Number.isInteger()
Number.isInteger()用來判斷一個值是否為整數(shù)。
Number.isInteger(25) // true
Number.isInteger(25.0) // true //js中25和25.0采用同樣的存儲方式
Number.isInteger(25.1) // false 
Number.isInteger("15") // false
Number.isInteger(true) // false

//js中這樣部署 Number.isInteger();
(function (global) {
  var floor = Math.floor,
    isFinite = global.isFinite;

  Object.defineProperty(Number, 'isInteger', {
    value: function isInteger(value) {
      return typeof value === 'number' && isFinite(value) &&
        value > -9007199254740992 && value < 9007199254740992 &&
        floor(value) === value;
    },
    configurable: true,
    enumerable: false,
    writable: true
  });
})(this);

ES6在Number對象上面,新增一個極小的常量Number.EPSILON。
Number.EPSILON
// 2.220446049250313e-16
Number.EPSILON.toFixed(20)
// '0.00000000000000022204'

//JavaScript能夠準(zhǔn)確表示的整數(shù)范圍在-2^53到2^53之間(不含兩個端點),超過這個范圍,無法精確表示這個值。
Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER
Number.isSafeInteger()則是用來判斷一個整數(shù)是否落在這個范圍之內(nèi)

Math對象的擴(kuò)展
Math.trunc() 、 Math.sign() 、Math.cbrt() 、Math.clz32
Math.imul()、Math.fround()、Math.hypot()、
對數(shù)方法
Math.expm1()//Math.expm1(x)返回ex - 1,
Math.log1p()、Math.log10()、Math.log2()
三角方法
指數(shù)運算符
let a = 2;
a **= 2;
// 等同于 a = a * a;

let b = 3;
b **= 3;
// 等同于 b = b * b * b;

參考文獻(xiàn):
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Numbers_and_dates
數(shù)學(xué)對象Math
Math.PI Math.sin(1.34)
日期對象
處理日期時間的Date對象方法可分為以下幾類:

"set" 方法, 用于設(shè)置Date對象的日期和時間的值。
"get" 方法,用于獲取Date對象的日期和時間的值。
"to" 方法,用于返回Date對象的字符串格式的值。
parse 和UTC 方法, 用于解析Date字符串。

數(shù)字時鐘
function JSClock() {
  var time = new Date();
  var hour = time.getHours();
  var minute = time.getMinutes();
  var second = time.getSeconds();
  var temp = "" + ((hour > 12) ? hour - 12 : hour);
  if (hour == 0)
    temp = "12";
  temp += ((minute < 10) ? ":0" : ":") + minute;
  temp += ((second < 10) ? ":0" : ":") + second;
  temp += (hour >= 12) ? " P.M." : " A.M.";
  return temp;
}
數(shù)組的擴(kuò)展
擴(kuò)展運算符 rest 參數(shù)的逆運算,將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列。
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
復(fù)制數(shù)組
合并數(shù)組
與解構(gòu)賦值結(jié)合
字符串
實現(xiàn)了 Iterator 接口的對象
Map 和 Set 結(jié)構(gòu),Generator 函數(shù)

Array.from() //將類似數(shù)組的對象轉(zhuǎn)成真正的數(shù)組
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3,
};
// ES5的寫法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的寫法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.from('hello') ;// ['h', 'e'...];

Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

Array.of方法用于將一組值,轉(zhuǎn)換為數(shù)組。
Array.of(3,11,8) //[3, 11,8];

copyWithin()
數(shù)組實例的copyWithin方法,在當(dāng)前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置(會覆蓋原有成員),然后返回當(dāng)前數(shù)組。target、start、end三個參數(shù)
[1, 2, 3, 4, 5].copyWithin(0, 3)// [4, 5, 3, 4, 5]

find的()和findIndex//數(shù)組實例的find方法,用于找出第一個符合條件的數(shù)組成員
[1, 4, -5, 10].find((n) => n < 0)// -5
[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2
fill方法使用給定值,填充一個數(shù)組。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
fill方法還可以接受第二個和第三個參數(shù),用于指定填充的起始位置和結(jié)束位置。
['a', 'b', 'c'].fill(7, 1, 2);// ['a', 7, 'c']
數(shù)組實例的entries(), keys(), values()

參考文獻(xiàn):
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Indexed_collections
var arr = new Array(element0, element1, ..., elementN);
var arr = Array(element0, element1, ..., elementN);
var arr = [element0, element1, ..., elementN];
//創(chuàng)建和填充數(shù)組
var emp = [];
emp[0] = "Casey Jones";
emp[1] = "Phil Lesh";
emp[2] = "August West";
引用數(shù)組元素
遍歷數(shù)組
數(shù)組方法
contact
var myArray = new Array("1", "2", "3");
myArray = myArray.concat("a", "b", "c"); 

joint 將數(shù)組的所有元素連接成一個字符串。
var myArray = new Array("Wind", "Rain", "Fire");
var list = myArray.join(" - "); // list is "Wind - Rain - Fire"

push 在數(shù)組末尾添加一個或多個元素,并返回數(shù)組操作后的長度。
var myArray = new Array("1", "2");
myArray.push("3"); // myArray is now ["1", "2", "3"]

pop()

shift() 移除數(shù)組第一個元素

unshift()

slice從數(shù)組提取一個片段,并作為一個新數(shù)組返回

reverse() 顛倒數(shù)組元素的順序:第一個變成最后一個,最后一個變成第一個。

sort() 給數(shù)組元素排序。

indexOf(searchElement[, fromIndex]) 在數(shù)組中搜索searchElement 并返回第一個匹配的索引。

lastIndexOf(searchElement[, fromIndex]) 和 indexOf 差不多,但這是從結(jié)尾開始,并且是反向搜索。

forEach(callback[, thisObject]) 在數(shù)組每個元素項上執(zhí)行callback

map(callback[, thisObject]) 在數(shù)組的每個單元項上執(zhí)行callback函數(shù),并把返回包含回調(diào)函數(shù)返回值的新數(shù)組(譯者注:也就是遍歷數(shù)組,并通過callback對數(shù)組元素進(jìn)行操作,并將所有操作結(jié)果放入數(shù)組中并返回該數(shù)組)

filter(callback[, thisObject]) 返回一個包含所有在回調(diào)函數(shù)上返回為true的元素的新數(shù)組(譯者注:callback在這里擔(dān)任的是過濾器的角色,當(dāng)元素符合條件,過濾
器就返回true,而filter則會返回所有符合過濾條件的元素)。

every(callback[, thisObject]) 當(dāng)數(shù)組中每一個元素在callback上被返回true時就返回true(譯者注:同上,every其實類似filter,只不過它的功能是判斷是不是數(shù)組中的所有元素都符合條件,并且返回的是布爾值)。

some(callback[, thisObject]) 只要數(shù)組中有一項在callback上被返回true,就返回true(譯者注:同上,類似every,不過前者要求都符合篩選條件才返回true,后者只要有符合條件的就返回true

reduce(callback[, initialValue]) 使用回調(diào)函數(shù) callback(firstValue, secondValue) 把數(shù)組列表計算成一個單一值(譯者注:他數(shù)組元素兩兩遞歸處理的方式把數(shù)組計算成一個值)
var a = [10, 20, 30];
var total = a.reduce(function(first, second) { return first + second; }, 0);
console.log(total) // Prints 60

多維數(shù)組
var a = new Array(4);
for (i = 0; i < 4; i++) {
  a[i] = new Array(4);
  for (j = 0; j < 4; j++) {
    a[i][j] = "[" + i + "," + j + "]";
  }
}
函數(shù)的擴(kuò)展
javascript中函數(shù)就是對象。對象是鍵值對的集合并擁有一個連接到原型對象的隱形連接,對象連接到Object.prototype,函數(shù)連接到Function.prototype.
函數(shù)是對象。
函數(shù)字面量:保留字function 、函數(shù)名(可省略,用于遞歸)、參數(shù)、執(zhí)行域
//ES6函數(shù)默認(rèn)值
var add = function(a, b = 0) {
  return a+b;
}
//與解構(gòu)賦值默認(rèn)值結(jié)合使用
function foo({x, y = 5}) {
  console.log(x, y);
}
foo({}) // undefined 5
//函數(shù)length屬性
指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個數(shù)
//作用域,指定函數(shù)參數(shù)
function throwIfMissing() {
  throw new Error('Missing parameter');
}

function foo(mustBeProvided = throwIfMissing()) {
  return mustBeProvided;
}
foo()
// Error: Missing parameter
//rest參數(shù)
function push(array, ...items) {
  items.forEach(function(item) {
    array.push(item);
    console.log(item);
  });
}
var a = [];
push(a, 1, 2, 3)
//name屬性
var f = function () {};
// ES5
f.name // ""
// ES6
f.name // "f"

//箭頭函數(shù)
var sum = (c, d) => {return c+d};
方法調(diào)用模式:當(dāng)一個函數(shù)是一個對象的屬性時
var myObject = {
  value: 0,
  increment: function (inc) {
    this.value += typeof inc === 'number' ? inc : 1;
  }
};
myObject.increment(); 
alert(myObject.value);// 1;
函數(shù)調(diào)用模式:當(dāng)一個函數(shù)并非一個對象的屬性時。
當(dāng)函數(shù)以此模式調(diào)用時,this被綁定到全局對象。這是語言設(shè)計上的一個錯誤。正確的設(shè)計應(yīng)該是當(dāng)內(nèi)部函數(shù)被調(diào)用時,this應(yīng)該仍然綁定到外部函數(shù)的this變量。
var sum = add(3,4);
//解決的辦法是:如果該方法定義一個變量并給它賦值this,那么內(nèi)部函數(shù)就可以通過這個變量訪問到外部函數(shù)的this.
//給myObject增加一個double方法。
myObject.double = function () {
  var that = this;//如果不這么賦值會發(fā)生意想不到的錯誤,內(nèi)部函數(shù)無法訪問到外部的this,內(nèi)部函數(shù)訪問的是全局的this,就有bug.
  var helper = function () {
  that.value = add(that.value, that.value);
 }
  helper();//以函數(shù)形式調(diào)用helper.
};
myOjbect.double(); //myOjbect.value = 2, 否則是1.

構(gòu)造器調(diào)用模式:
var Quo = function (string) {//創(chuàng)建一個Quo名的構(gòu)造器函數(shù)。并構(gòu)造一個帶有status屬性的對象。
    this.status = string;
 } 
Quo.prototype.get_status = function() {//給Quo的所有實例提供一個方法。
     return this.status;
};
var myQuo = new Quo("confused"); //new 構(gòu)造一個Quo實例
alert(myQuo.get_status());

Apply調(diào)用模式
javascript是函數(shù)式的面向?qū)ο蟮恼Z言,所以函數(shù)可以擁有方法。
apply方法讓我們構(gòu)建一個參數(shù)數(shù)組并用其去調(diào)用函數(shù),apply方法接收兩個參數(shù),一個是將被綁定給this的值,第二個是參數(shù)數(shù)組。
var array = [3, 5];
var sum = add.apply(null, array);//sum = 8
var statusObject = {
  status: 'A-OK',
};
var status = Quo.prototype.get_status.apply(statusObject); //status : 'A-OK'

函數(shù)參數(shù):arguments數(shù)組是默認(rèn)的。
返回值:
異常:

給函數(shù)添加方法:Function.prototype.method = function() {}

遞歸:


參考文獻(xiàn):https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Functions
值傳遞和引用傳遞 ---- 函數(shù)重要知識點
function map (f, a) {
    var result = [];
    for (let i = 0; i < a.length; i++) {
        result[i] = f(a[i]);
    }
    return result;
}

var f = function(x) {
    return x*x*x;
}

var numbers = [0,1,2,5,10];
var cube = map(f,numbers);
console.log(cube);
for(let value  in numbers) {
    console.log(numbers[value]);
}

函數(shù)作用域
遞歸
嵌套函數(shù)和閉包
閉包
函數(shù)參數(shù)
箭頭函數(shù)
this

ES6函數(shù)

箭頭函數(shù):
var f = v => v, 等同于: var f = function(v) {return v;};
var geetTmpItem = id => ({id:id, name: 'Tmp'});//返回對象時,用圓括號括起來
const full = ({first, last}) => first + '' + last;//變量解構(gòu)
var sum = (num1, num2) => { return num1 + num2; }
對象
//null表示沒有對象,即該處不應(yīng)該有值
(1) 作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對象。
(2) 作為對象原型鏈的終點。
Object.getPrototypeOf(Object.prototype)// null

//undefined表示"缺少值",就是此處應(yīng)該有一個值,但是還沒有定義
(1)變量被聲明了,但沒有賦值時,就等于undefined。
(2) 調(diào)用函數(shù)時,應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined。
(3)對象沒有賦值的屬性,該屬性的值為undefined。
(4)函數(shù)沒有返回值時,默認(rèn)返回undefined。
var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var  o = new Object();
o.p // undefined
var x = f();
x // undefined

對象有時也被叫作關(guān)聯(lián)數(shù)組
var myCar = new Object();
myCar.make = "Ford"
或者
myCar["model"] = "Mustang";

//枚舉屬性
function showProps(obj,objName) {
    var result = "";
    for(var i in obj) {
        if (obj.hasOwnProperty(i)) {
            result += objName + "." + i + "=" + obj[i] + "\n";
        }
    }
    return result;
}

var myCard = new Object();
myCard.make = "Ford";
myCard.model = "Mystang";
myCard.year = 1969;
console.log(showProps(myCard, "myCard"))

Object.keys(o)
Object.getOwnPropertyNames(o)
//使用對象初始化器初始化一個對象
var obj = { property_1:   value_1,   // property_# 可以是一個標(biāo)識符...
            2:            value_2,   // 或一個數(shù)字...
           ["property" +3]: value_3,  //  或一個可計算的key名... 
            // ...,
            "property n": value_n }; // 或一個字符串
//使用構(gòu)造函數(shù)初始化對象
function Car(make, model, year) {
    this.make = make ;
    this.model = model;
    this.year = year;
}
var mycard_1 = new Car("eagle", "talon",1993)

//使用Object.create方法
//為對象類型定義屬性,其中Car為構(gòu)造函數(shù)
Car.prototype.color = null;
car1.color = "black";

//定義方法
objectName.methodname = function_name;

var myObj = {
  myMethod: function(params) {
    // ...do something
  }
  // 或者 這樣寫也可以  
  myOtherMethod(params) {
    // ...do something else
  }
};

get 和 set方法
刪除屬性
比較對象

ES6對象方法簡寫
let birth = '2000/01/01';
const Person = {
  name: '張三',
  //等同于birth: birth
  birth,
  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};

Object.is()
Object.assign() 淺拷貝、同名屬性替換、數(shù)組處理、取值函數(shù)的處理
1)給對象添加屬性
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}
Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});
// 等同于下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};
3)克隆對象
4)合并多個對象

//屬性的可枚舉性和遍歷
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
屬性的遍歷

//__proto__屬性,Object.setPrototypeOf(),Object.getPrototypeOf() 
// es6 的寫法
const obj = {
  method: function() { ... }
};
obj.__proto__ = someOtherObj;

// es5 的寫法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };

//super關(guān)鍵字

//Object.keys(),Object.values(),Object.entries()

//對象的擴(kuò)展運算符
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

Class類
1.ES5寫法
function Point(x, y) {
    this.x = x;
    this.y = y;
}
Point.prototype.toString = function() {
    return '(' + this.x + ',' + this.y + ')';
};
console.log(Point.prototype);[ 'toString' ]

2.ES6寫法
class Point {
    constructor(x, y) {//默認(rèn)方法
        this.x = x;
        this.y = y;
    }
    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
    get prop () {//定義getter和setter函數(shù)
        return 'shit-get';
    }
    set prop(value) {
        console.log('setter'+value);
    }
    static classMethod() {//靜態(tài)方法
        return 'Hello, world';
    }
}
var point = new Point(8,0);
console.log(point.toString());//(8.0)
console.log(typeof point);//object
console.log(typeof Point);//function
console.log(Point.classMethod());//調(diào)用靜態(tài)方法
類的所有方法都定義在類的prototype屬性上面,在類的實例上面調(diào)用方法,其實就是調(diào)用原型上的方法,如下
point.constructor = Ponit.prototype.constructor//true

3.類的內(nèi)部所有定義的方法,都是不可枚舉的(non-enumerable),這與ES5不一致。
console.log(Point.prototype);// Point{}
console.log(Object.getOwnPropertyNames(Point.prototype));//[ 'constructor', 'toString' ]
console.log(point.hasOwnProperty('x'));//true
console.log(point.hasOwnProperty('toString'));//false
console.log(point.__proto__.hasOwnProperty('toString'));//true
4.同ES5,類的所有實例共享一個原型對象
point1.__proto__ = point2.__proto__
可以通過__proto__為Class添加方法。
point.__proto__.printName = function(){};
//同
Point.prototype.printName = function(){};

以上更改類慎用

5.class繼承
class ColorPoint extends Point{}
子類必須在constructor方法中調(diào)用super方法,否則新建實例會報錯。

6.類的prototype和__proto__
(1)子類的__proto__屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。
(2)子類prototype屬性的__proto__屬性,表示方法的繼承,總是指向父類的prototype屬性。
class A{} class B extends A{}
B.__proto__ === A;//true
B.prototype.__proto__ === A.prototype;//true
Object.getPrototypeOf方法可以用來從子類上獲取父類:
Object.getPrototypeOf(B) == A//true

7.super關(guān)鍵字
super這個關(guān)鍵字,有兩種用法,含義不同。
(1)作為函數(shù)調(diào)用時(即super(...args)),super代表父類的構(gòu)造函數(shù)。
(2)作為對象調(diào)用時(即super.prop或super.method()),super代表父類。注意,此時super既可以引用父類實例的屬性和方法,也可以引用父類的靜態(tài)方法。

子類繼承父類,必須調(diào)用super,且需要在this前調(diào)用

8.實例的__proto__屬性
子類實例的__proto__屬性的__proto__屬性,指向父類實例的__proto__屬性。也就是說,子類的原型的原型,是父類的原型。
因此,通過子類實例的__proto__.__proto__屬性,可以修改父類實例的行為。

9.ES6允許原生構(gòu)造函數(shù)的繼承
class MyArray extends Array {
  constructor(...args) {
    super(...args);
  }
}
但是es5是不能夠直接繼承原生構(gòu)造函數(shù)的。
Boolean()/Number()/String()/Array()/Date()/Function()/RegExp()/Error/Object()

9.Class的getter、setter
寫法見上2。

10.class的generator函數(shù)
class Foo {
    constructor(...args) {
        this.args = args;
    }
    * [Symbol.iterator]() {
        for (let arg of this.args) {
            yield arg;
        }
    }
}
for (let x of new Foo('hello', 'world')) {
    console.log(x);
}
如果某個方法之前加上星號(*),就表示該方法是一個Generator函數(shù)。
Symbol.iterator方法返回一個Foo類的默認(rèn)遍歷器,for...of循環(huán)會自動調(diào)用這個遍歷器.

11.Class的靜態(tài)方法
類相當(dāng)于實例的原型,所有在類中定義的方法,都會被實例繼承。
如果在一個方法前,加上static關(guān)鍵字,就表示該方法不會被實例繼承,而是直接通過類來調(diào)用,這就稱為“靜態(tài)方法”。
代碼見上2。
父類靜態(tài)方法可以被子類繼承,且可以從super對象調(diào)用。

12.Class靜態(tài)屬性和實例屬性
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
只有之中方法定義可行。es6類內(nèi)部不能定義靜態(tài)屬性。
目前,es6的實例屬性也只能定義在方法或者constructor方法里。es7允許。

13.newTarget屬性
14.Mixin模式
Mixin模式指的是,將多個類的接口“混入”(mix in)另一個類。它在ES6的實現(xiàn)如下。
class DistributedEdit extends mix(Loggable, Serializable) {
  // ...
}

15.Object.getPrototypeOf方法可以用來從子類上獲取父類。
Iterator和 for…of循環(huán)
遍歷器(Iterator)就是這樣一種機(jī)制。它是一種接口,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制。任何數(shù)據(jù)結(jié)構(gòu)只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數(shù)據(jù)結(jié)構(gòu)的所有成員)。

Promise對象
1.Promise含義、基本用法
var promise = new Promise(function(resolve, reject) {
    console.log('fuck');
    var shit = 'g';
    if ('st') {
        resolve('shit');
    }else {
        reject('go');
    }
});
console.log(promise);
promise.then(function(value) {//使用、success、resolved
    console.log('we did it.');
}, function(error) {//failure、rejected
});
Promise對象三種狀態(tài):Pending、Resolved、Rejected
then方法可以接受兩個回調(diào)函數(shù)作為參數(shù)。第一個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽esolved時調(diào)用,第二個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽eject時調(diào)用。其中,第二個函數(shù)是可選的,不一定要提供。這兩個函數(shù)都接受Promise對象傳出的值作為參數(shù)。
console.log(Object.getOwnPropertyNames(promise.__proto__));
//[ 'constructor', 'chain', 'then', 'catch' ]

2.Promise對象實例
var getJSON = function(url) {
  var promise = new Promise(function(resolve, reject){
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出錯了', error);
});

3.Promise.prototype.then()
console.log(Object.getOwnPropertyNames(promise.__proto__));//[ 'constructor', 'chain', 'then', 'catch' ]
then方法的第一個參數(shù)是Resolved狀態(tài)的回調(diào)函數(shù),第二個參數(shù)(可選)是Rejected狀態(tài)的回調(diào)函數(shù)。
then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。因此可以采用鏈?zhǔn)綄懛?,即then方法后面再調(diào)用另一個then方法。
getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  //...
});
面的代碼使用then方法,依次指定了兩個回調(diào)函數(shù)。第一個回調(diào)函數(shù)完成以后,會將返回結(jié)果作為參數(shù),傳入第二個回調(diào)函數(shù)。

4.Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)的別名,用于指定發(fā)生錯誤時的回調(diào)函數(shù)。
getJSON("/posts.json").then(function(posts) {
  //...
}).catch(function(error) {
    // 處理 getJSON 和 前一個回調(diào)函數(shù)運行時發(fā)生的錯誤
  console.log('發(fā)生錯誤!', error);
});//如果狀態(tài)變?yōu)镽ejected則會調(diào)用catch方法指定回調(diào)函數(shù)。處理錯誤。

5.Promise.all()
用于將多個Promise實例包裝成一個新的Promise實例。只要數(shù)組中其中一個狀態(tài)被reject,則返回一個reject實例。
var promises = [1,3,4,5,90,8].map(function(id) {
  return getJSON("/post/" + id + ".json");
});
Promise.all(promises).then(function(post){
//...
}).catch(function(reason){
  /...
});

6.Promise.race()
同上、方法
7.Promise.resolve()
該方法將現(xiàn)有對象轉(zhuǎn)化為Promise對象。
Promise.resolve('foo')
//等價于
new Promise(resolve => resolve('foo'));
8.Promise.reject()
Promise.reject(reason)方法也會返回一個新的Promise實例,該實例的狀態(tài)為rejected。用法與上面一致
var p = Promise.reject('出錯了');
=> var p = new  Promise((resolve, reject) => reject('出錯了'));
p.then(null, function(s) {
  console.log(s);
});//出錯了
9.done()和finally()

Promise對象的回調(diào)鏈,不管以then方法或catch方法結(jié)尾,要是最后一個方法拋出錯誤,都有可能無法捕捉到(因為Promise內(nèi)部的錯誤不會冒泡到全局)。因此,我們可以提供一個done方法,總是處于回調(diào)鏈的尾端,保證拋出任何可能出現(xiàn)的錯誤.
10.應(yīng)用
const preloadImage = function (path) {
  return new Promise(function (resolve, reject) {
    var image = new Image();
    image.onload  = resolve;
    image.onerror = reject;
    image.src = path;
  });
};
async函數(shù)與Promise、Generator函數(shù)一樣,是用來取代回調(diào)函數(shù)、解決異步操作的一種方法。它本質(zhì)上是Generator函數(shù)的語法糖。async函數(shù)并不屬于ES6,而是被列入了ES7,但是traceur、Babel.js、regenerator等轉(zhuǎn)碼器已經(jīng)支持這個功能,轉(zhuǎn)碼后立刻就能使用。
Set和Map結(jié)構(gòu)
1.Set,不會重復(fù)添加元素
var s = new Set();
[1,2,1,5,5,8,6,2,7].map(x=>s.add(x));
for(let i of s){log(i)}//1,2,5,6,7,8
2.常用操作
var set = new Set([1,2,3,4,4]);
[...set];//[1,2,3,4]
set.size; 4
[...new Set(array)];//去除數(shù)組重復(fù)成員
向Set加入值的時候,不會發(fā)生類型轉(zhuǎn)換,5和'5'不同,NaN等于自身
兩個對象總是不等:set.add({}); set.size =1,set.add({}),set.size=2;

2.屬性和方法
屬性:constructor、size
方法:操作方法和遍歷方法
get(key);
set(key,value);
add(value)
delete(value)
has(value)
clear()
Array.from(set)=>array
keys();
values();
entries();
forEach();set.forEach((value, key)=>console.log(value*2));
擴(kuò)展運算符內(nèi)部用for...of循環(huán),所以也可以用于Set結(jié)構(gòu),數(shù)組的map和filter方法也可以用于Set了。
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// [1, 2, 3, 4]
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// [2, 3]
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// [1]
3.WeakSet
4.Map
JavaScript的對象(Object),本質(zhì)上是鍵值對的集合(Hash結(jié)構(gòu)),但是只能用字符串當(dāng)作鍵。這給它的使用帶來了很大的限制.
Map也是鍵值對,但是鍵的范圍不限于字符串,各種類型的值都可以當(dāng)做對象。
var m = new Map();
var o = {p: 'Hello world'};
m.set(o, 'content');
m.get(o);//"content"
m.has(o)//true
m.delete(o)//true
m.has(o)//false
var map = new Map([['name', '張三'], ['title', 'Author']]);//接受數(shù)組做參數(shù)
3.與其他類型的互相轉(zhuǎn)化
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
[...myMap];// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
轉(zhuǎn)為對象:
function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

Module
1.前言
JavaScript語言一直沒有分模塊的東西,社區(qū)解決方案是CommonJS和AMD兩種。
靜態(tài)優(yōu)化、運行時加載。
es5、CommonJS模塊
let {stat, exits, readFile } = require('fs');
上述代碼中實質(zhì)上是整體加載fs模塊生成一個對象,然后從對象中讀取三個方法。為運行時加載。
es6、Module
import {stat, exits, readFile} from 'fs';
上述代碼的實質(zhì)是從fs中加載3個方法,其他方法不加載,為編譯時加載。

2.use strict
嚴(yán)格模式主要有以下限制。

變量必須聲明后再使用
函數(shù)的參數(shù)不能有同名屬性,否則報錯
不能使用with語句
不能對只讀屬性賦值,否則報錯
不能使用前綴0表示八進(jìn)制數(shù),否則報錯
不能刪除不可刪除的屬性,否則報錯
不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
eval不會在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會自動反映函數(shù)參數(shù)的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對象
不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
增加了保留字(比如protected、static和interface)

3.export命令
export 可輸出函數(shù)、類、變量
export var firstName = 'Mike';
export default Home;
export {firstName, lastName, year};
export function mutiply(x, y) {
  return x * y;
}
export {f};//f為function
通常情況下,export輸出的變量就是本來的名字,但是可以使用as關(guān)鍵字重命名。
function v1(){...}
export {v1 as streanV1};
另外,export語句輸出的接口,與其對應(yīng)的值是動態(tài)綁定關(guān)系,即通過該接口,可以取到模塊內(nèi)部實時的值。
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);上面代碼輸出變量foo,值為bar,500毫秒之后變成baz

4.import
import {firstName, lastName, year} from './profile';
import {lastName as surname} from './profile';//使用as關(guān)鍵字重命名

5.模塊的整體加載
//circel.js
export function area(){}
export function name(){}
//main.js
import {area, name} from './circle'
整體加載:使用 * as關(guān)鍵字
import * as circle from './circle'
console.log(circle.area);

6.export default命令
為了給用戶提供方便,讓他們不用閱讀文檔就能加載模塊,就要用到export default命令,為模塊指定默認(rèn)輸出。
export default function() {log('foo')}; //export_default.js
import  customname from './export_default'
 customName();//'foo'
 
7.模塊的繼承

Generator函數(shù)
1.屬性
Generator函數(shù)有多種理解角度。從語法上,首先可以把它理解成,Generator函數(shù)是一個狀態(tài)機(jī),封裝了多個內(nèi)部狀態(tài)。
執(zhí)行Generator函數(shù)會返回一個遍歷器對象,也就是說,Generator函數(shù)除了狀態(tài)機(jī),還是一個遍歷器對象生成函數(shù)。返回的遍歷器對象,可以依次遍歷Generator函數(shù)內(nèi)部的每一個狀態(tài)。
function* helloworldGenerator() {
    yield 'hello';
    yield 'world';
    return 'ending';
}
var hw = helloworldGenerator();
hw.next();//hello,done
hw.next();//world;
hw.next();//ending
hw.next();//undefined
2.for...of循環(huán)
for(let v of helloworldGenerator()) {
  console.log(v);//1 2 3 4 5
}

webpack入門
參考文獻(xiàn):https://segmentfault.com/a/1190000006178770#articleHeader3c
1、webpack作用
WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用

2、webpack安裝
//全局安裝
npm install -g webpack
//安裝到你的項目目錄
npm install --save-dev webpack

3、正式使用
在項目根目錄創(chuàng)建package.json 文件 或者 在終端通過npm init創(chuàng)建pakage.json

4、創(chuàng)建app和public文件夾

5、正式使用webpack
# {extry file}出填寫入口文件的路徑,本文中就是上述main.js的路徑,
# {destination for bundled file}處填寫打包文件的存放路徑
# 填寫路徑的時候不用添加{}
webpack {entry file} {destination for bundled file}
# webpack非全局安裝的情況
node_modules/.bin/webpack app/main.js public/bundle.js

6、通過配置文件使用webpack
在項目根目錄下創(chuàng)建webpack.config.js
module.exports = {
  entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
  output: {
    path: __dirname + "/public",//打包后的文件存放的地方
    filename: "bundle.js"http://打包后輸出文件的文件名
  }
}

7、更快捷打包方式
{
  "name": "lib",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack",
    "server": "webpack-dev-server --open"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.11.0"
  }
}

8、使用webpack構(gòu)建本地服務(wù)器
全局安裝
npm install -g webpack-dev-server
在終端輸入npm run server 即可打開瀏覽器查看結(jié)果

9、Loaders
10、Babel安裝和配置
# npm一次性安裝多個依賴模塊,模塊之間用空格隔開.非全局安裝
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react

#npm install --save react react-dom
npm install --save react react-dom

Babel其實可以完全在 webpack.config.js 中進(jìn)行配置,但是考慮到babel具有非常多的配置選項,在單一的webpack.config.js文件中進(jìn)行配置往往使得這個文件顯得太復(fù)雜,因此一些開發(fā)者支持把babel的配置選項放在一個單獨的名為 ".babelrc" 的配置文件中。我們現(xiàn)在的babel的配置并不算復(fù)雜,不過之后我們會再加一些東西,因此現(xiàn)在我們就提取出相關(guān)部分,分兩個配置文件進(jìn)行配置(webpack會自動調(diào)用.babelrc里的babel配置選項)

11、一切皆模塊
webpack提供兩個工具處理樣式表,css-loader 和 style-loader,二者處理的任務(wù)不同,css-loader使你能夠使用類似 @import 和 url(...)的方法實現(xiàn) require()的功能,style-loader將所有的計算后的樣式加入頁面中,二者組合在一起使你能夠把樣式表嵌入webpack打包后的JS文件中。

12、CSS module
被稱為CSS modules的技術(shù)意在把JS的模塊化思想帶入CSS中來,通過CSS模塊,所有的類名,動畫名默認(rèn)都只作用于當(dāng)前模塊。Webpack對CSS模塊化提供了非常好的支持,只需要在CSS loader中進(jìn)行簡單配置即可,然后就可以直接把CSS的類名傳遞到組件的代碼中,這樣做有效避免了全局污染

module.exports = {

    ...

    module: {
        rules: [
            {
                test: /(\.jsx|\.js)$/,
                use: {
                    loader: "babel-loader"
                },
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: "style-loader"
                    }, {
                        loader: "css-loader",
                        options: {
                            modules: true, // 指定啟用css modules
                            localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的類名格式
                        }
                    }
                ]
            }
        ]
    }
};

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一、webpack介紹 1、由來 ...
    it筱竹閱讀 11,463評論 0 21
  • GitChat技術(shù)雜談 前言 本文較長,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,894評論 7 110
  • 目錄第1章 webpack簡介 11.1 webpack是什么? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,829評論 0 1
  • 最近在學(xué)習(xí) Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學(xué)習(xí) Webpack 的...
    My_Oh_My閱讀 8,334評論 40 247
  • 讀完文心一書,只感嘆兩位先生對中學(xué)生在學(xué)習(xí)作文上的困難分析的透徹。此書先從字、詞,到句,再到段,最后成文,逐個展開...
    鷓鴣少閱讀 696評論 0 0

友情鏈接更多精彩內(nèi)容