跟紧时代的步伐(虽然我已经落后好多了)~再不学习es6我就老了,而且学习react同样需要es6作为基础,所以抽空好好看看es6的一些语法,同样是先借鉴网上的一些资料,然后自己实践,一步步来学习。
我这边参考的是这一篇文章:https://segmentfault.com/a/1190000005742091
下面是我学习的笔记:(主要是记录我学习中遇到的“坑”)
"首当其冲"的是let,这个完全可以解决我们以前遇到的循环闭包中的问题。
下面这个代码就是有问题的。为什么,我以前分析过哦:http://blog.csdn.net/liuzijiang1123/article/details/53859682
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
首先我们用ES5的方法来解决这个问题,再添加一层闭包.
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function (x) {
return function(){
console.log(x);
}
}(i);
}
a[6](); // 6
当出现let后,特别简单-。-,使得let之后的代码块具有了作用域。不过这里测试的情况是IE11还是不行,chrome是可以的。由此可见各种浏览器对于ES6的支持还是没完全一样。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
当然,let还有一些需要注意的地方:
{
let a=1;
}
console.log(a) ;//报错
let只会在它所在的代码块中有效,这里用{ } 构成了一个代码块,类似的还有我们的if for等;
let也不存在变量提升;
console.log(a); //undefined
var a=1;
我们经常在面试的时候遇到上面这种问题,变量声明会提前,所以哪怕var a=1;这条语句在console.log后面,我们的a也是先声明了,所以打印是undefined,没有报错
但是如果我们用let 则会报错
console.log(a); //报错
let a=1;
因为let中不存在变量声明提前;
let也不允许在同一个代码块中重复声明:
let a=1;
let a=2;//报错
const就不多说了,和C语言中的是一样的用法
箭头函数是ES6一个新知识点,也是很重要的一块
形如:
function(i){ return i + 1; } //ES5
(i) => i + 1 //ES6
个人感觉其实箭头函数就是代替了以前的匿名函数。
关于括号里面的参数:
( ) => { … } // 零个参数用 ( ) 表示;
x => { … } // 一个参数可以省略 ( );
(x, y) => { … } // 多参数不能省略 ( );
上面是箭头函数的声明,然后就是关于它的调用,刚一开始还不知道怎么用-。-(丢脸)
我是这么用的,应该就是匿名函数定义之一,附着到一个变量上,貌似箭头函数没有自执行
var a=2;
var sum;
sum=(a,b)=>{
return a+b
}
var totl=sum(a,2);
console.log(totl)
然后就是当做函数参数使用:(这个是我们用得最多的一种形式)
$("#btn").click(()=>{
console.log("按下");
})
还需要注意的是:
如果箭头函数中的语句不只一句我们需要用{ }将代码括起来;
fn=()=>{var a=1;console.log(a)}
fn();
如果你的返回值是一个对象的话,需要用( ) 将对象括起来
fn=()=>{console.log({id:"lzj"})}
fn();
关于箭头函数中的this:
先看下面两个例子:
我想按下按钮一秒后打印id;
$("#btn").click(function(){
this.id=42;
setTimeout(function(){
console.log(this.id);
},1000)
})
这个输出是undefined;
因为settimeout里面的this是全局变量,在浏览器中就是window,而window没有id这个属性,所以显示undefined
如果用ES5的方法去改变的话,使用bind即可:
$("#btn").click(function(){
this.id=42;
setTimeout(function(){
console.log(this.id);
}.bind(this),1000)
})
这样就能输出42;
如果用箭头函数呢?
$("#btn").click(()=>{
this.id="42";
setTimeout(()=>{
console.log(this.id);
},1000)
})
输出仍然还是42;
是因为:
当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。
tips:如果这里要用事件对象event的话,当做参数传进去,这样使用 ( e )=>{ handleClick ( e ) } //因为react中很多地方用到了event这个对象
class也是非常重要的一个知识点,react里面非常多这个用法
个人觉得开头推荐的那篇文章说得很清楚了,大家可以好好看看.
这里需要注意一下,class是没声明提前的。
比如我们ES5实例一个类对象可以这样:
var p = new People( );
function People(){
}
但是class是不行的
var p = new People("Tom"); //错误,People 未定义
class People {
//...
};
必须要在前面先定义才行。
ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
上面这个等同于es5中的:
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
如果在一个方法前加上static关键字, 就表示该方法不会被实例继承, 而是直接通过类来调用, 这就称为“ 静态方法”。
例如:
class Animal {
constructor(name){
this.type = name;
}
static says(say){
console.log(this.type + ' says ' + say)
}
}
这样的话我只能通过Animal.says( );这个类本身去调用这个方法,它的实例不能使用,但是它的继承类可以使用,继承类的实例不能使用。
相反,如果这个方法没有用static声明,那么只能类的实例,及继承类的实例使用。
继承类是用extends表示,它能继承父类的方法,不过继承类中如果用到 constructor,在这个函数里面就必须用到super,否则报错,而且要在你使用this前面使用。因为super调用会生成一个空对象,作为context来调用父类的constructor,返回this对象,作为子类constructor的context继续调用构造函数。
template string
模板字符串这个东西简直拯救了我的眼睛,以前在字符串和变量混合使用的时候那个 " " 和‘ ’(双,单引号)简直要把我眼睛看瞎了!!react中在render返回的时候在html中插入数据的时候用到了这个。
整个字符串用 ` `包围起来,其中的常量,例如常量字符串和html标签直接写就好,其中的变量用${ }包围起来,里面是正常的js代码。
下面是我的代码:
$("#btn").click(function(){
var name="lzj";
$("body").append(`My name is <b>${name}</b>`);
})
tips: react中对CSS样式修改的时候,样式的名字要用驼峰式:形如fontSize这样。
ES6中的模块
ES6模块主要有两个功能:export和import
export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口
import用于在一个模块中加载另一个含有export接口的模块。
也就是说使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)
这里除了推荐的开头推荐的那个文章外,这里再推荐另一篇文章:http://blog.csdn.net/lihongxun945/article/details/49031383
1.如何导出一个组件,如何使用导出的组件
export default class HelloWorld extends Component{
render(){
return( <div>
"Hello World"
</div>)
}
import HelloWorld form " xxxx"
2.如何导出一个变量或者常量,如何使用导出的变量和常量
var name="lzj"
const age=22;
export { name, age}
import { name,age} form "xxxx"
3.如何导出一个方法,如何使用导出的方法
export function fn() {
}
import { fn } form "xxxx"
这3种情况可以结合在一起使用
import HelloWorld , { name ,age ,fn } form "xxxx"
函数的扩展
我们可以给函数添加默认值:
function fn(word="lzj")
{
console.log(word)
}
fn();//lzj
fn("liuzj")//liuzj
我们这里不能再去word用let或者const变量声明了,因为word已经存在了;
我们可以对于多个参数使用...arg来将其保存在一个arg这个数组中
function fn(...word)
{
for(let i=0;i<word.length;i++)
console.log(word[i])
}
fn("lzj","nzj"); //lzj nzj
解构赋值
这个方法我们主要是用来从数组和对象中提取值,对变量进行赋值;(解构)
以前我们赋值:
var a=1;
var b=2;
var c=3;
从数组中提取:
var [a,b,c]=[1,2,3];
var {a, b, c}={ a:1, b:2, c:3 };
对于数组解构的话我们必须要”一一对应“,例如:
var [a,,c]=[1,2,3]; //c:3
var [a,c]=[1,2,3]; //c:2
上面两种结果是不一样的;
我们还可以把解构和默认参数赋值结合起来:
var [a,b=1,c]=[1,,3]; //b:1
var {a, b=2, c}={ a:1, c:3 }; //b:2
Promise
https://segmentfault.com/a/1190000002395343
function helloWorld (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello World!");
} else {
reject("Good bye!");
}
});
}
helloWorld(true).then(function (message) {
console.log(message);
}, function (error) {
console.log(error);
});