这篇博客是我在b站进行学习es6课程时的笔记总结与补充。
此处贴出up主的教程视频地址:深入解读ES6系列(全18讲)
1. 变量
2. 函数
3. 数组
4. 字符串
5. 面向对象
6. Promise
7. generator //类似于Promise
8. 模块化
知识点:
1. ES6之前的JS只有函数作用域和全局作用域,ES6引入了let后新增了块级作用域,还引入const。
2. 所有window对象内置属性都拥有全局作用域。
var
1. 可以重复声明
2. 无法限制修改
3. 函数作用域(在函数体内可访问)
let
1. 不能重复声明
2. 变量(可以修改)
3. 块级作用域(在大括号{}内可访问)
const
1. 不能重复声明
2. 常量(不能修改)
3. 块级作用域
[块级作用域]
说明:因为var是全局变量,js是单线程运行,而for循环是同步执行,onclick()是异步执行,所以for循环执行完成后,全局变量i为3,再执行onclick()就得到了3
var btn=document.getElementsByTagName('input'); //有三个input组件
for(var i=0;i
此处引用自stpice的博客
知识点:
function foo(){} //这是定义(Declaration),让解释器知道其存在,并不会立即执行
foo(); //这是语句,(Statement),解释器遇到它会执行
IIFE调用方式:
(function foo(){}());
(function foo(){})();
!function foo() {}();
+function foo() {}();
-function foo() {}();
~function foo() {}();
在需要表达式的场景下,就不需要用括号了:
void function(){}();
var foo = function(){}();
true && function () {}();
0, function () {}();
$(function(){})的用法:
$(document).ready(function(){
console.log("ready");
});
等同于
$(function(){
console.log("ready");
});
知识点:
箭头函数 ()=>{} 等价于 function(){}
当只有一个参数的时候,可以省略(),如 (res)=>{} 等价 res=>{}
当只有一个返回值时,可以省略{},如 ()=>{return 0;} 等价 ()=>return 0;
此处引用自博主越努力越幸运_952c
知识点:
调用栈:调用栈主要是存放返回地址
调用位置:当前函数在代码中被调用的位置
function baz(){
//当前调用栈是baz
//当前调用位置是全局作用域
bar(); //<--bar的调用位置
}
function bar(){
//当前调用栈是baz->bar
//当前调用位置在baz中
foo(); //<--foo的调用位置
}
function foo(){
//当前调用栈是baz->bar->foo
//当前调用位置是在bar中
}
baz(); //<--baz的调用位置
此处引用自博主蔡香满屋
ES5:
函数的调用位置决定了this的绑定
全局环境下,this始终指向全局对象(window)
普通函数内部的this分为两种情况:严格模式和非严格模式
非严格模式:this默认指向全局对象window
function f2(){
return this;
}
f2()===window; //true
严格模式:this为undefined
function f2(){
"use strict"; //使用严格模式
return this;
}
f2()===undefined; //true
ES6:
箭头函数的定义位置决定了this的绑定
所以call()/apply()/bind()方法对于箭头函数来说只是传入参数,不会影响this值
var Animal=function(){
this.name="Animal"; //下面那一行的this指向的时这外面的this
this.speak=(name,words)=>{
console.log(this.name+'is saying'+words+'.');
}
}
var cat=new Animal();
cat.speak("cat","miao~"); //Animal is saying miao~
知识点:
...可以用于展开/收集参数
[收集参数]
function show(a,b,...args){ //...args必须是最后一个形参
alert(a);
alert(b);
alert(args); //输出3,4,5,6
}
show(1,2,3,4,5,6);
[展开参数]
let arr1=[1,2,3];
let arr2=[4,5,6];
let arr=[...arr1,...arr2]; //等价于arr=[1,2,3,4,5,6]
知识点:
1. 左右两边结构必须一样
2. 右边的格式必须是合法的
3. 声明和赋值不能分开
let [a,b,c]=[1,2,3]; //把1,2,3分别赋值给a,b,c
let [{a,b,c},[d,e,f],g,e]=[{a:1,b:2,c:3},[1,2,3],"string",1];
let [json,arr,s,i]=[{a:1,b:2,c:3},[1,2,3],"string",1]; //注意与上式的区别
知识点:
map映射可以实现两个数组间的对应映射,比如下面a[],b[]两个数组间的元素一一对应:
a=[10,60,88,50,30];
b=['不及格','及格','及格','不及格','及格']
let score=[19,85,99,25,90];
let result=score.map(item=>item>=60?'及格':'不及格');
alert(score); //分别输出19,85,99,25,90
alert(result); //分别输出'不及格','及格','及格','不及格','及格'
知识点:
reduce将数组[1,2,3]各个元素相加得到总数5
let arr=[12,69,180,8763];
let result=arr.reduce(function(tmp,item,index){ //tmp代表两数相加产生的中间数,item表示当前第二个加数,index为索引(第一次运算得到中间数后为2)
return tmp+item;
});
let arr=[12,69,180,8763];
let result=arr.reduce(function(tmp,item,index){
if(index!=arr.length-1){ //不是最后一次运算
return tmp+item;
}else{
return (tmp+item)/arr.length;
}
});
alert(result);
知识点:
filter将返回true或false来实现过滤
let arr=[12,5,8,99,27,36,75];
let result=arr.filter(item=>item%3==0);
alert(result);
知识点:
forEach迭代输出数组的元素
let arr=[12,5,8,9];
arr.forEach((item,index)=>{ //index可加可不加
alert(index,": ",item);
});
相同点:
都是遍历数组的每一项
执行匿名函数时都支持传入三个参数:item,index,arr //item为当前项,index为索引,arr为原数组
不同点:
map会分配内存空间存储新数组并返回,forEach不会返回
forEach对数据的操作会改变原数组,map不会改变原数组,而是会返回一个新数组
知识点:
startsWith和endsWith通过判断字符串开头或结尾是否含有特定字符串来返回true和false
知识点:
可以直接把东西塞到字符串里面 $(东西)
可以折行书写代码
let title='标题';
let content='内容';
旧的写法:
let str='\ //折行需要加'\'
'+title+'
\
'+content+'
\
';
新的写法:
let str=` //使用反引号包裹
$(title)
//不需要加'+'连接符
$(content)
`;
缺点:
面向对象概念模糊,类和函数的不分家
方法需要在外面用prototype定义
function User(name,pass){
this.name=name;
this.pass=pass;
}
User.prototype.showName=function(){
alert(this.name);
}
User.prototype.showPass=function(){
alert(this.pass);
}
var u1=new User('zhang','123');
u1.showName();
u1.showPass();
//---------------继承User----------------
function VipUser(name,pass,level){
User.call(this,name,pass); //call实现继承
this.level=level;
}
VipUser.prototype=new User();
VipUser.prototype.constructor=VipUser; //个人猜测这里是加入User后,重新构造VipUser
VipUser.prototype.showLevel=function(){
alert(this.level);
}
var v1=new VipUser('zhang','123',3);
v1.showName();
v1.showPass();
v1.showLevel();
优点:
强化面向对象概念,区分函数和类
class关键字、构造器和类分开了
class里面直接加方法
class User{
constructor(name,pass){ //构造器
this.name=name;
this.pass=pass;
}
showName(){ //方法
alert(this.name);
}
showPass(){
alert(this.pass);
}
}
var u1=new User('zhang','123');
u1.showName();
u1.showPass();
//---------------继承User----------------
class VipUser extends User{
constructor(name,pass,level){
super(name,pass); //super关键字继承父类
this.level=level;
}
showLevel(){ //直接在class里面加方法
alert(this.level);
}
}
var v1=new VipUser('zhang','123',3);
v1.showName();
v1.showPass();
v1.showLevel();
React特点:
1. 强调组件化,一个组件即一个class
2. 强依赖与JSX(JSX==babel==browser.js)
(这里先简单介绍一下react框架,后续将会详细学习)
知识点:
1. JSON转换成字符串:JSON.stringfy()
2. 字符串转换成JSON:JSON.parse()
3. 把字符串作为URI组件进行编码:encodeURIComponent()
4. JSON的标准写法:
· 所有key和字符串类型的value都要用双引号包裹
· 最外层用单引号包裹
eg:let str='{"a":12,"b":"hello"}';
知识点:
1. 名字一样可以简写(key和value一样)
2. 方法可以简写
eg:
let a=12;
let b=5;
let json={a:a,b:b}; //可简写为:let json={a,b};
let json={
a:12,
show:function(){ //可简写为:show(){alert(this.a);}
alert(this.a);
}
};
知识点:
Promise的出现解决了ajax异步加载时代码复杂的问题,在较新版本的ajax中有封装了Promise
let p = new Promise(function(resolve,reject){
$.ajax({
url:'hello.txt',
dataType:'json',
success(arr){
resolve(arr); //执行成功调用resolve()返回arr
},
error(err){
reject(err); //执行失败调用reject()返回err
}
})
});
p.then(function(arr){ //接受resolve()返回的参数
console.log('成功',arr);
},function(err){ //接受reject()返回的参数
console.log('失败',err);
});
知识点:
当有多个Promise一起异步执行时,使用Promise.all()来返回多个Promise调用结果
let p1 = new Promise(functioin(resolve,reject){...});
let p2 = new Promise(functioin(resolve,reject){...});
Promise.all([p1,p2]).then(arr=>{ //此处也可简写成箭头函数
let [res1,res2]=arr; //解构赋值
console.log(res1,res2);
},err=>{
let [err1,err2]=err;
console.log(err1,err2);
});
知识点:
与Promise.all()用法相似,原则是谁先来先返回谁,即哪个Promise返回的值快就返回谁,可以用于超时处理
Promise.race([p1,p2]).then(results=>{},err=>{});
知识点:
generator(生成器),执行过程中可以暂停去执行其他函数
generator跟promise相似,用于异步回调处理,异步的请求可以用类似同步的逻辑来写
普通函数异步请求:
function 函数(){
代码...
ajax(xxx,function(){
代码...
});
}
generator异步请求:
function *函数(){ //*不能省略
代码...
yield ajax(xxx);
代码...
}
知识点:
yield把函数分成了几部分,通过调用next()来分别执行
yield可以传参和返回
传参:
function *show(){
alert('a');
let a=yield; //执行第二个next的时候把5赋值给a
alert('b');
alert(a); //输出5
}
let gen=show();
gen.next(12); //执行yield的上半部分
gen.next(5); //执行yield的下半部分
返回:
function *show(){
alert('a');
yield 12; //返回12给第一个next
alert('b');
return 55; //返回55给第二个next
}
let gen=show();
let res1=gen.next();
console.log(res1); //输出{value:12,done:false}
let res2=gen.next();
console.log(res2); //输出{value:55,done:true}
知识点:
在使用前需要安装runner,并引入jquery.js(用于ajax)和runner.js
runner(function *(){
//使用同步的写法实现异步的请求
let data1=yield $.ajax({url:'data/1.txt',dataType:'json'});
let data2=yield $.ajax({url:'data/2.txt',dataType:'json'});
let data3=yield $.ajax({url:'data/3.txt',dataType:'json'});
console.log(data1.data2.data3);
});
知识点:
1. 在同时请求多条数据的时候,promise和generator方法效果差不多
//第一层
$.ajax({
url:xxx,
dataType:'json',
success(data1){
//第二层
$.ajax({
url:xxx,
dataType:'json',
success(data2){
//第三层
$.ajax({
url:xxx,
dataType:'json',
success(data3){
//OK
},error(){
alert('失败');
}
});
},error(){
alert('失败');
}
});
},error(){
alert('失败');
}
});
Promise.all([
$.ajax({url:xxx,dataType:'json'}),
$.ajax({url:xxx,dataType:'json'}),
$.ajax({url:xxx,dataType:'json'}),
]).then(res=>{
//OK
},err=>{
alert('失败');
});
runner(function *(){
let data1=yield $.ajax({url:xxx,dataType:'json'});
let data2=yield $.ajax({url:xxx,dataType:'json'});
let data3=yield $.ajax({url:xxx,dataType:'json'});
//OK
});
2. 在请求完数据后,通过数据的值来判断下一条请求时,generator>传统回调>promise
$.ajax({url:'getUserData',dataType:'json',success(userData){
if(userData.type=='vip'){
$.ajax({url:'getVipData',dataType:'json',success(items){
//OK
},error(err){
alert('失败');
}})
}
},error(err){
alert('失败');
}})
Promise.all([
$.ajax({url:'getUserData',dataType:'json'})
]).then(res=>{
let userData=res[0];
if(userData.type=='vip'){
Promise.all([
$.ajax({url:'getVipData',dataType:'json'})
]).then(res=>{
//OK
},err=>{
alert('失败');
});
}
},err=>{
alert('失败');
});
runner(function *(){
let userData=yield $.ajax({url:'getUserData',dataType:'json'});
if(userData.type=="vip"){
let items=yield $.ajax({url:'getVipData',dataType:'json'});
//OK
}
});