最近半年开始接触前端的项目,虽然之前也多多少少接触过,但也都只是蜻蜓点水,没有完全在意里面的语法和使用的场景。尤其是ES6的出现,自己脑子里的概念还是停留在ES5阶段,所以这篇文章就是帮助自己migrate from ES5 to ES6。
Template literals(模板字面量)
模板字面量不同之处在于可以嵌入表达式和字符,以前我们拼接字符用'+'来拼接,如果字符串过长就会导致很混乱,不太好维护,现在ES6可以使用${}表达式,而且可以避免部分特殊字符(\n、"、'等)的转义
ES5
var name = "Renu";
var age = 9;
console.log ("My name is \" "+ name + " \" "+ " and I 'm " + age + " years old. ")
// My name is "Renu" and I 'm 9 years old.
ES6
var name = "Renu";
var age = 9;
console.log (`My name is'" ${name} "and I'm ${age} years old.`);
// My name is "Renu" and I 'm 9years old.
Function declaration
在ES5中定义function的方法有3种:
function str (arg1, arg2) {console.log ('Renu')}
var str = new Function ("arg1", "arg2", "console.log ('Renu')");
var str = function (arg1, arg2) {console.log ('Renu');}
在ES6中使用arrow function:
var str = (arg1, arg2) => {console.log ('Renu');}
Difference if this
this
关键字代表function的上下文,它决定了how you call the function, 而不是how you defined it.
ES5
在function中,this
指的是the object that function belong to。
var value = 'window-value';
var showValue = function( scope ){
console.log( 'this inside ' + scope + ' is : ', this );
console.log( this.value );
};
var object = {
value: 'object-value',
showValue: showValue
};
showValue( 'window' ); // 输出 window-value
object.showValue( 'object' ); //输出 object-value
匿名函数属于window作用域
var object = {
provider: 'gmail.com',
usernames: [ 'mike', 'john', 'nina' ],
getEmails: function() {
return this.usernames.map( function( username ){
return username + '@' + this.provider;
} );
}
};
var emails = object.getEmails();
console.log( emails ); //["mike@undefined", "john@undefined", "nina@undefined"]
所以,当在匿名函数中调用 this.porvider
的时候,this
指向的是window,window.provider没有被定义,所以输出的结果为["mike@undefined", "john@undefined", "nina@undefined"]。如果代码修改为如下,结果就会正确:
var provider = 'yahoo.com';
var object = {
provider: 'gmail.com',
usernames: [ 'mike', 'john', 'nina' ],
getEmails: function() {
return this.usernames.map( function( username ){
return username + '@' + this.provider;
} );
}
};
var emails = object.getEmails();
console.log( emails ); //["mike@yahoo.com", "john@yahoo.com", "nina@yahoo.com"]
如果想改变function的作用域,可以通过bind
方法进行绑定:
var provider = 'yahoo.com';
var object = {
provider: 'gmail.com',
usernames: [ 'mike', 'john', 'nina' ],
getEmails: function() {
return this.usernames.map( function( username ){
return username + '@' + this.provider;
}.bind( this ) );
}
};
var emails = object.getEmails();
console.log( emails ); //["mike@gmail.com", "john@gmail.com", "nina@gmail.com"]
因为在getEmails
方法中,this
指的是object
,bind(this)
实际是把object
绑定为匿名函数的作用域
ES6
在arrow function中,{}
中的this
指的是whatever the value of this
inside upper function is。
var provider = 'yahoo.com';
var object = {
provider: 'gmail.com',
usernames: [ 'mike', 'john', 'nina' ],
getEmails: function() {
return this.usernames.map( ( username ) => {
return username + '@' + this.provider;
} );
}
};
var emails = object.getEmails();
console.log( emails );
在getEmails
方法中,this.usernames
中的this
指的是object
,所以在arrow function中{}
中的this.provider
中的this
指的是object
。
声明变量
var
允许定义重复的变量名
let
变量名不能重复,且变量可以修改
const
变量名不能重复,且变量不能修改
以及作用域不同
if (true) {
var i = 0;
}
console.log (i); // 0
if (true) {
let j = 10;
}
console.log (j); // ReferenceError
if (true) {
const k = 100;
}
console.log (k); // ReferenceError
Module(模块化)
ES5
按照顺序Require依赖 var myModule = require('./myModule');
ES6
允许在文件中import相应的依赖,或者export依赖 import myModule from './myModule';
Class declaration(声明类)
ES5
var Add = function (arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
};
Add.prototype.calc = function () {
return this.arg1 + '+' + this.arg2 + '=' + (this.arg1 + this.arg2);
};
var num = new Add (5, 8);
console.log (num.calc ()); // 5 + 8 = 13
ES6
class Add {
constructor (arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
calc () {
return this.arg1 + '+' + this.arg2 + '=' + (this.arg1 + this.arg2);
}
}
var num = new Add (5, 8);
console.log (num.calc ()); // 5 + 8 = 13
Manipulating objects in ES6 vs ES5
Merge object
ES5
var obj1 = { a: 1, b: 2 }
var obj2 = { a: 2, c: 3, d: 4}
var obj3 = Object.assign(obj1, obj2)
ES6
const obj1 = { a: 1, b: 2 }
const obj2 = { a: 2, c: 3, d: 4}
const obj3 = {...obj1, ...obj2}
Destructuring object
ES5
var obj1 = { a: 1, b: 2, c: 3, d: 4 }
var a = obj1.a
var b = obj1.b
var c = obj1.c
var d = obj1.d
ES6
const obj1 = { a: 1, b: 2, c: 3, d: 4 }
const {
a,
b,
c,
d
} = obj1
Promises vs Callbacks
ES5
function isGreater (a, b, cb) {
var greater = false
if(a > b) {
greater = true
}
cb(greater)
}
isGreater(1, 2, function (result) {
if(result) {
console.log('greater');
} else {
console.log('smaller')
}
})
ES6
const isGreater = (a, b) => {
return new Promise ((resolve, reject) => {
if(a > b) {
resolve(true)
} else {
reject(false)
}
})
}
isGreater(1, 2)
.then(result => {
console.log('greater')
})
.catch(result => {
console.log('smaller')
})
The ES6 promises are better than callback because it allows us to distinguish easily between a success
and error
, so we don’t have to check it again in our callback function.
后续有新的知识点,会持续更新