ES6 note
面試又被電爆,所以寫一下筆記。當然會是動態擴充。
雖然不知道該寫在哪裡……
Arrow function
()=>{}
←就這玩意兒。這玩意兩種功能,一是語法簡潔化、二是把 this
放到外面一層的物件上。
function Person(){
this.age = 0;
setTimeout(()=>{
this.age++;
}, 1000);
}
var p = new Person();
console.log(p);
// 用 Babel 還原語法看看?
"use strict";
function Person() {
var _this = this;
this.age = 0;
setTimeout(function () {
_this.age++;
}, 1000);
}
var p = new Person();
console.log(p);
感覺還蠻像是 Vue 的用法……
問題:_this
又是怎麼回事?
2018/04/30 增筆:在 JavaScript 裡面,變數的生效範圍,是以函式為單位。因此,為了讓 setTimeout(function () {})
函式,能收到外面函式的 this
,我們需要指派一個變數給 this
用。而這個變數,在這裡就是 _this
。
Ref: 重新認識 JavaScript: Day 10 函式 Functions 的基本概念
Class
語法糖。讓基於原型的 JavaScript 可以看起來像其他的物件導向一點。MDN 。
class Bar {
constructor(baz) {
this.baz = baz;
}
}
class Foo extends Bar {
constructor(ipt) {
super(ipt);
this.player = 2000;
}
}
console.log(new Foo("Java")); // { baz:"Java" , player:2000 }
// 用 Babel 把語法解壓縮以後,發現長成這樣子:
"use strict";
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Bar = function Bar(baz) {
_classCallCheck(this, Bar);
this.baz = baz;
};
var Foo = function(_Bar) {
_inherits(Foo, _Bar);
function Foo(ipt) {
_classCallCheck(this, Foo);
var _this = _possibleConstructorReturn(this, (Foo.__proto__ || Object.getPrototypeOf(Foo)).call(this, ipt));
_this.player = 2000;
return _this;
}
return Foo;
}(Bar);
看到 _inherits
函式裡面的 subClass.prototype
了嗎?所以儘管 ES6 用上了 Class
這物件導向的語法,它還是基於原型的程式語言。
Enhanced Object Literals
var obj =
{
__proto__: theProtoObj,
['__proto__']: somethingElse,
handler,
toString() {
return "d " + super.toString();
},
[ "prop_" + (() => 42)() ]: 42
};
"use strict";
var _obj, _obj2;
var _get = function get(object, property, receiver)
{
if (object === null) object = Function.prototype;
var desc = Object.getOwnPropertyDescriptor(object, property);
if (desc === undefined)
{
var parent = Object.getPrototypeOf(object);
if (parent === null)
{
return undefined;
}
else
{
return get(parent, property, receiver);
}
}
else if ("value" in desc)
{
return desc.value;
}
else
{
var getter = desc.get;
if (getter === undefined)
{
return undefined;
}
return getter.call(receiver);
}
};
function _defineProperty(obj, key, value)
{
if (key in obj)
{
Object.defineProperty(obj, key
, {
value: value
, enumerable: true
, configurable: true
, writable: true
});
}
else
{
obj[key] = value;
}
return obj;
}
var obj = _obj = (_obj2 = {
__proto__: theProtoObj
}, _obj2['__proto__'] = somethingElse, _defineProperty(_obj2, "handler", handler), _defineProperty(_obj2, "toString", function toString()
{
return "d " + _get(_obj.__proto__ || Object.getPrototypeOf(_obj), "toString", this)
.call(this);
}), _defineProperty(_obj2, "prop_" + function ()
{
return 42;
}(), 42), _obj2);
這什麼東西?我不知道……
Template Strings
var x = "foo";
var y = "2000";
console.log( x + "bar" + y );
console.log( "I use \" " + x + "bar" + y + " \"." );
// 但你可以在 ES6 這樣寫……
console.log( `${x}bar${y}` );
console.log( `I use "${x}bar${y}".` );
// 注意到 ` 符號了嗎?就是這個關鍵字。
Destructuring
用 []
這個看起來像是陣列的東西宣告多個變數。
var [ x , y , z ] = [ "x" , "y" ];
console.log( x , y , z ); // Shows: "x" , "y" , undefined
var [ a , b , ...c ] = [ 1 , 2 , 3 , 4 , 5 , 6 ];
console.log( a , b , c ); // Shows: 1 , 2 , [ 3 , 4 , 5 , 6 ]
// 反過來這樣會有語法錯誤:
var [ a , b , ...c , d ] = [ 1 , 2 , 3 , 4 , 5 , 6 ];
console.log( a , b , c , d ); // Error: rest element may not have a trailing comma
Let , Const
原本的 var 會全域生效,很容易被污染。但是在 ES6 裡面有兩種新的變數命名法:let
會只在被宣告的作用域內生效,而 const
在大多數情況下無法被變動。