1.靜態函數
1.什么是靜態函數
靜態函數最重要的就是不用創建一個實例變量就可以進行調用,在C++里面,無法訪問this對象,
而在JS里面由於js的this對象支持,是可以訪問this對象,只是this對象有所不同
2.ES6靜態函數代碼
classtestClass{ static staticFunc(){ console.log("instatic") } }
將會被babel轉換為:
"use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; //利用defineProperty來創建函數 Object.defineProperty(target, descriptor.key, descriptor); } } //創建函數,根據傳入的數組創建成員函數和靜態函數 return function (Constructor, protoProps, staticProps) { //注意這里,傳入的是Constructor.prototype和Constructor //所以可以區分是靜態函數還是成員函數 if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var testClass = function () { function testClass() { /* *這是是為了保證這個class只能new出來,在usestrict模式下,this是undefined, *正常模式下,this為window,也就是說我們這直接調用這個函數,_classCallCheck的時候將會拋出異常 **/ _classCallCheck(this, testClass); } _createClass(testClass, null, [{ key: "staticFunc", value: function staticFunc() { console.log("instatic"); } }]); return testClass; }(); testClass.staticFunc();
2.=>符號
=>符號的出現是為了解決this作用域改變的問題
function test(){ this.x = 5; this.f = function(){ console.log(this.x) } } let xx = new test(); xx.f.call(this);
在上面的代碼里面,本來是期望回調的時候log輸出5的,但是此時call的時候this被修改為全局,所以將會產生錯誤,因為全局里面並沒有x
function test(){ this.x = 5; this.f = ()=>{ console.log(this.x) } } let xx = new test(); xx.f.call(this);
將代碼修改為上面的代碼后,即可正常輸出5
"use strict"; function test() { var _this = this; //通過創建一個臨時的_this變量來規避this改變的問題 this.x = 5; this.f = function () { console.log(_this.x); }; } var xx = new test(); xx.f.call(undefined); //在babel默認的use strict模式下,是不會有默認的全局this的
3.解構參數
/*這里只是單純地翻譯 * var a=arr[0] * var b=arr[1] * var c=arr[2] * */ let arr = [1,2,3]; let [a, b, c] = arr; /* * 這里也只是由編譯器自動生成分割的語法,有點類似於erlang的語法 * var head = 1; * var second = 2; * var tail = [3, 4] * */ { let [head,second, ...tail] = [1, 2, 3, 4]; } { /** * 這里暫時不管yiled是怎么轉換的,轉換完的代碼后: * var first = _fibs[0] * var second = _fibs[1] * var three = _fibs[2] * 還是自動生成與語法糖 */ 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(); } { /* * 跟之前的大同小異, * var _foo$bar = { foo: “lorem", bar: "ipsum" }; * var bar = _foo$bar.bar; * var foo = _foo$bar.foo; * */ var { bar, foo } = { foo: "lorem", bar: "ipsum" }; function t(a){ if(a == 0 ){ return [1, 2, 3]; } else{ return []; } } let [a, b, c] = t(0); let [d=1, e=2, f] = t(1); console.log(d) }
4.默認參數,不定參數,擴展參數
/* * 主要是利用arguments取得所有的參數,然后從1開始,把參數都取出來,如果是a, b,...tail則會從2開始 * for (var _len = arguments.length, needles = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { * needles[_key - 1] = arguments[_key]; * } * */ function containsAll(haystack,...tail) { console.log(arguments.length) } containsAll(1, 2,3,4); //判斷arguments的[0]是否為undefined //var a = arguments.length <= 0 || arguments[0] === undefined ? '11' : arguments[0]; function containsAll2(a = '11'){ console.log(a) } containsAll2(2)
5.yield
/* //這個regeneratorRuntime估計是polyfill的東西 var _marked = [fu].map(regeneratorRuntime.mark); function fu() { var i; //這里講函數內部的變量聲明在這里,然后利用閉包一直保持住這些變量的改變的改變,再通過switch來選擇執行到那一段 //跟C++里面的無堆棧routine的實現比較相似 return regeneratorRuntime.wrap(function fu$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: i = 9; i++; _context.next = 4; return i; case 4: i++; _context.next = 7; return i; case 7: case "end": return _context.stop(); } } }, _marked[0], this); } */ function *fu(){ let i = 9; i++; yield i; i++; yield i; } fu(); fu();