安装 Babel cnpm install --save-dev @babel/core
安装转码规则 cnpm install --save-dev @babel/preset-env
安装命令行转码工具 cnpm install --save-dev @babel/cli
转码结果输出到标准输出npx babel 待转码文件.js
将转码结果写入到一个文件(--out-file
或-o
参数指定输出文件)
npx babel 待转码文件.js --out-file 输出文件.js
或 npx babel 待转码文件.js -o 输出文件.js
整个目录转码(--out-dir
或-d
参数指定输出目录)
npx babel src --out-dir lib
或npx babel src --d lib
Babel 是 ES6 的一部分,是 ES6 新特性;
Babel 是 ES6 的转码器,可以将 ES6 代码转为 ES5 代码;
Babel 是配置文件,配置 ES6 环境;
Babel 是 ES5 的基础知识。
var
关键字:函数集的作用域;
let
关键字:块级作用域({}
级的作用域,只在一层{}
内生效);
const
关键字:声明一个只读的常量,一旦声明就不能改变。
for循环内很适合使用let
: 每次循环都创建一个新的i
for(let i=0; i<10; ++i){console.log(i); // 0 1 2 3 4 5 6 7 8 9
};
console.log(i); // ReferenceError: i is not defined
var a = [];
for(let i=0; i<10; ++i){a[i] = function(){console.log(i);};
}
a[6](); // 6
for(var i=0; i<10; ++i){a[i] = function(){console.log(i);};
}
a[6](); // 10
let
不存在变量提升: let
声明的变量必须在声明之后使用
console.log(a); // undefined
var a;console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b;
let
不允许重复声明: 不可以在相同作用域内重复声明同一个变量
var i = 10;
var i = 20;
console.log(i); // 20
let i = 1;
console.log(i); // SyntaxError: Identifier 'a' has already been declared
const
声明的常量不能改变值: 因此在声明的时候必须赋值
const PI = 3.14;
console.log(PI); // 3.14
PI = 2; // TypeError: Assignment to constant variable.
console.log(PI);
const a; // SyntaxError: Missing initializer in const declaration
const
在块级作用域内生效
const
不存在变量提升: const
声明的变量必须在声明之后使用
const
不允许重复声明: 不可以在相同作用域内重复声明同一个变量
var user = {name: "yyt",age: 16
};
console.log(user.name, user.age); // yyt 16
// 解构赋值
const {name, age} = user; // 用一组常量将 user 内的属性提取出来,便于以后多次使用
console.log(name, age); // yyt 16
对象的属性没有顺序,变量必须与属性同名才能取到正确的值。
对象的解构赋值可以很方便地将现有对象的方法赋值给某个变量。
如果要将一个已经声明的变量用于解构赋值,必须非常小心(建议不要这样做,何苦呢):
let name = "yyt";
var user = {name: "lyl"
};
// let{name} = user; // SyntaxError: Identifier 'name' has already been declared
({name} = user);
console.log(name); // lyl
uxxxx
形式表示一个字符,其中xxxx
表示字符的 Unicode 码点。for(let i of "nakahara chuya"){console.log(i);
}
// 动态创建一个a标签,其 href属性也是动态的
let href = "";
let name = "nakahara chuya";
// 当我们向页面动态写入标签时,标签的数据一般来源于服务器
var atab = "<a href='"+ href +"'>"+ name +"</a>";
console.log(atab);
// 模板语法
var btab = `<a href="${href}">${name}</a>`;
console.log(btab);
includes()
:返回布尔值,表示是否找到了参数字符串startsWith()
:返回布尔值,表示参数字符串是否在原字符串的头部endsWith()
:返回布尔值,表示参数字符串是否在原字符串的尾部let s = "Hello World!";
console.log(s.startsWith("llo")); // false
console.log(s.startsWith("llo", 2)); // true
console.dsWith("!")); // true
console.log(s.includes("Wor")); // true
repeat()
n
次。n = 0
时返回一个空字符串。let s = "Hello World! ";
console.peat(3)); // Hello World! Hello World! Hello World!
s.padStart(n, str)
:如果s
的长度小于n
,那么用str
在头部进行补全;s.padEnd(n, str)
:如果s
的长度小于n
,那么用str
在尾部进行补全;let s = "yyt";
console.log(s.padStart(10, "sikoyi ")); // sikoyi yyt
console.log(s.padStart(5, "sikoyi ")); // siyyt
console.log(s.padStart(15, "sikoyi ")); // sikoyi sikoyyyt
console.log(s.padEnd(10, "sikoyi ")); // yytsikoyi
console.log(s.padEnd(5, "sikoyi ")); // yytsi
console.log(s.padEnd(15, "sikoyi ")); // yytsikoyi sikoy
trimStart()
:消除字符串头部的空格;trimEnd()
:消除尾部的空格;const s = " yyt ";
console.imEnd()); // " yyt"
console.imStart()); // "yyt "
at()
undefined
。const s = "nakahara chuya";
console.log(s.at(6)); // "r"
console.log(s.at(-6)); // " "
console.log(s.at(-16)); // undefined
...
:将一个数组转为用逗号分隔的参数序列apply
方法;var arr = [10, 20, 30, 40];
console.log(...arr); // 10 20 30 40
// 替代 apply
var es5 = Math.max.apply(null, [14, 3,77]);
var es6 = Math.max(...[14, 3, 77]);
console.log(es5, es6); // 77 77
// 合并数组
var arr1 = [1,2,3,4];
var arr2 = [5,6,7,8];
console.at(arr2)); // [ 1, 2, 3, 4, 5, 6, 7, 8]
console.log([...arr1, ...arr2]); // [ 1, 2, 3, 4, 5, 6, 7, 8]
Array.from()
:将类数组(arguments、元素集合、类似数组的对象)转换为真正的数组// arguments:函数中的可选参数
function add(){console.log(arguments); // [Arguments] { '0': 1, '1': 2, '2': 3 }var result = Array.from(arguments);result.push(4);console.log(result); // [ 1, 2, 3, 4 ]
}
add(1,2,3);
//元素集合
let links = document.querySelectorAll("a");
console.log(Array.from(links)); // (3) [a, a, a]
// 类似数组的对象
var user = {"0":"yyt","1":16,"2":"female",length:3
};
console.log(Array.from(user)); // (3) ['yyt', 16, 'female']
Array.of()
:将一组值转换为数组console.log(Array.of(1,2,3,4)); // [ 1, 2, 3, 4 ]
let name = "yyt";
let age = 16;
var user = {name,age,sex:"female",getName(){ console.log(this.name);}
};
console.log(user); // { name: 'yyt', age: 16, sex: 'female' }
Name(); // yyt
var iName = "yyt";
var user = {[iName]: "yyt",age:16
};
console.log(user); // { yyt: 'yyt', age: 16 }
var z = {a:1, b:2};
var n = {z};
console.log(n); // { z: { a: 1, b: 2 } }
var n = {...z};
console.log(n); // { a: 1, b: 2 }
ES6允许使用箭头=>
来声明函数。
var fn1 = function(x, y){return x+y;
}
var fn2 = (x,y) => x+y;
如果箭头函数不需要参数或者需要多个参数,那么要用一个空括号代替参数;
var fn3 = () => 1;
如果箭头函数的代码块多于一条语句,那么要用花括号把它括起来,并用return
返回;
var fn4 = (x, y) => {var z = 10;return x+y+z;
};
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外加一层括号,否则会报错;
var fn5 = (x, y) => ({x:1, y:2});
箭头函数的一个用法是简化回调函数(匿名函数)。
注: 箭头函数没有自己的this
对象,内部的this
就是定义它时上层作用域的this
。
类似于数组,成员值唯一,没有重复值。
var s = new Set();
var arr = [1, 1, 2, 3, 4, 5];
arr.forEach(x => s.add(x));
console.log(s); // Set(5) { 1, 2, 3, 4, 5 }
s.delete(2);
console.log(s); // Set(4) { 1, 3, 4, 5 }
console.log(s.has(3)); // true
console.log(s.size); // 4
s.clear();
console.log(s); // Set(0) {}
Set
函数可以接收一个数组作为参数Set
可以使用扩展运算符来读取数据var s = new Set([1, 2, 3, 4, 5]);
s = [...s];
console.log(s); // [ 1, 2, 3, 4, 5 ]
var s = new Set([1, 1, 2, 3, 4, 5]);
s = [...s];
console.log(s); // [ 1, 2, 3, 4, 5 ]
var s = new Set("yyt is the greatest");
s = [...s].join('');
console.log(s); // "yt ishegra"
Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。
Promise
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的API,各种异步操作都可以用同样的方法进行处理。有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外, Promise 对象提供统一的接口,使得控制异步操作更加容易。
Promise
对象是一个构造函数,用来生成Promise
实例Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署;Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。Promise
对象用来封装一个异步操作并可以获取其成功/失败的结果值状态指的是Promise实例对象中的一个属性PromiseState
,有三个可能的值:pending
未决定的;resolved / fullfilled
成功;rejected
失败。
状态改变只有两种情况:pending → rightarrow → resolved 或 pending → rightarrow → rejected,一个 promise 对象只能改变一次,无论成功 (value) 还是失败 (reason) 都会返回一个结果数据。
实例对象中的属性 PromiseResult
,保存着对象成功/失败的结果。只有回调函数 resolve 和 reject 可以对属性值进行修改,在then方法的回调当中可以把属性值取出来进行后续修改。
excutor
:一个函数,是执行器,(resolve, reject)=>{}
,它会在程序运行到 new Promise()
这里时立即同步调用,在它里面进行异步操作;resolve
:excutor
里的异步操作成功时调用的回调函数,(value)=>{}
reject
:excutor
里的异步操作失败时调用的回调函数,(reason)=>{}
Promise.prototype.then(onResolve, onReject)
,返回一个新的 Promise 对象onResolveed
:excutor
里的异步操作成功时resolve()
修改了状态后调用的回调函数,(value)=>{}
onRejected
:excutor
里的异步操作失败时reject()
修改了状态后调用的回调函数,(reason)=>{}
Promise.prototype.catch(onReject)
onRejected
:excutor
里的异步操作失败时reject()
修改了状态后调用的回调函数,(reason)=>{}
const promise = new Promise(function(resolve, reject) {// ... some codeif (/* 异步操作成功 */){resolve(value);} else {reject(error);}
});
promise.then(function(value) {// success
}, function(error) {// failure
});
promise实例对象调用then方法后返回一个promise
对象,then()接收的参数是两个回调函数,执行回调时
then()
返回的promise
状态为rejected
,值 PromiseResult
是错误的值;then()
返回的promise
状态为resolved
,值 PromiseResult
就是返回值;then()
返回的promise
状态和值与改对象相同;then()
返回的promise
状态为pending
,值 PromiseResult
为undefined
;resolve(value)
:如果当前是pending
状态,会修改为resolved
;reject(reason)
:如果当前是pending
状态,会修改为rejected
;pending
状态,会修改为rejected
;then()
给一个 promise 指定多个成功/失败的回调函数,当状态改变时都会调用const promise = new Promise(function(resolve, reject) { ... };
promise.then(value=>{}, reason=>{});
promise.then(value=>{}, reason=>{});
resolve()/reject()
;当状态发生改变时调用回调函数,得到数据;resolve()/reject()
;或者延迟更长的时间才调用then()
(比如在then的回调中加个定时器);指定回调时调用回调函数,得到数据。.catch(reason=>{})
,前面任何一步中出现了异常,都会调用最后的这个失败回调。pending
状态的 promise 对象,就可以在使用 promise 的 then 进行链式调用时在中间中断,不再调用后面的回调函数。加载图片
<div id="img"></div>
// url:图片路径
function loadImage(url){// resolve 和 reject 这两个名字是固定的,不能修改const promise = new Promise(function(resolve, reject){// 异步处理:消耗时间的代码const img = new Image(); // 创建新的图片对象img.src = url; // 加载图片load = function(){ // 加载成功resolve(img);};r = function(){ // 加载失败reject(new Error('Could not load image at ' + url));};});return promise; // 返回的 promise 中保存了加载图片这个操作的结果
}
// 我自己的QQ空间里的图片的路径
const promise = loadImage('?/V12IERdR1cPfzX/ruAMsa53pVQWN7FLK88i5vkRidgmc*LxvhToGvTwO*qaF0WOEtHMYujvzyWnw7uV17PyS7hQfls84YKHq5CTHBDTWtNegFXR.XSHZHR3sSU!/r');
var div = ElementById("img");
promise.then(function(data){ // 异步的操作成功div.appendChild(data); // data是返回的img的标签,在const img = new Image();时创建
}, function(error){ // 异步的操作失败div.innerHTML = "image load faild.";console.log(error);
});
const getJSON = function (url){const promise = new Promise(function(resolve, reject){// 异步操作:网络请求代码const handler = function(){adyState !== 4){ // 状态码为 0 1 2 3 时都代表操作没有完成return;};if(this.status === 200){sponse);}else{reject(new Error(this.statusText));}};const client = new XMLHttpRequest();client.open("GET", url); // 默认请求方式 GET,发送 url 网址adystatechange = handler; // 接收前后端交互的状态sponseType = "json";client.setRequestHeader("Accept", "application/json");client.send();});return promise;
}
getJSON(".php").then(function(data){console.log(data);
}, function(error){console.log(error);
});
ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async函数可以将异步操作变为同步操作。async
函数中可以没有 await
,但await
必须写在async
函数中。
async
函数的返回值是一个promise对象,该对象的结果由 async 函数执行的返回值决定:await
语句右侧是一个表达式:// 定时器是异步的
function print(){setTimeout(()=>{console.log("delay 1000 ms");}, 1000);console.log("中也!");
}
print();// async将定时器变为同步效果
function timeout(ms){const promise = new Promise(function(resolve, reject){setTimeout(function(){console.log("yi?"); resolve()}, ms);});return promise;
};
// 将 "async" 放在函数定义前,再将 "await" 放在具有异步操作的代码前面。
async function asyncPrint(ms, value){console.log( ...");await timeout(ms);console.log(value);
};
asyncPrint(1000, "quya!");
网络请求之间有依赖关系,很多接口可能要依赖于上一个接口的数据才能执行。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法。
class Person{constructor(name, age){this.name = name;this.age = age;}getName(){console.log(this.name);}
}
var p = new Person("yyt", 16);
p.getName();
constructor()
方法是类的默认方法,通过new
命令生成对象实例时,自动调用该方法。一个类必须有constructor()
方法,如果没有显式定义,那么会默认添加一个空的constructor()
。类不存在变量提升。
p.name
、p.age
。Class
本身的属性,即 Class.propName
,要通过类名添加属性。class Person{
}
pe = "People";
var p = new Person();
console.pe); // People
static
关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。如果静态方法包含this
关键字,这个this
指的是类,而不是实例。class Person{constructor(name, age){this.name = name;this.age = age;}getName(){console.log(this.name);}static classMethod(){console.log("static method Oh~");console.log(this.name); // `this`指向当前类,而不是实例对象}
}
var p = new Person("yyt", 16);
p.classMethod(); // Uncaught TypeError: p.classMethod is not a function
p.getName(); // yyt
Person.classMethod(); // static method Oh~; Person
Class
可以通过extends
关键字实现继承,让子类继承父类的属性和方法。extends 的写法比 ES5 的原型链继承,要清晰和方便很多。constructor()
方法中调用super()
,否则就会报错,这是因为子类自己的this
对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()
方法,子类就得不到自己的this对象。class Person{constructor(name, age){this.name = name;this.age = age;}getName(){console.log(this.name);}static getSpecies(){console.log("Person");}
}
class Student extends Person{constructor(name, age, sex){super(name, age);this.sex = sex;}getSex(){console.log(this.sex);}
}
var s = new Student("yyt", 16, "female");
s.getName(); // yyt
s.getSex(); // female
Species(); // Person
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的 require 、Python 的 import ,甚至就连CSS 都有 @import ,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。ES6 模块是通过 export 命令显式指定输出的代码,再通过 import 命令输入。
我们采用Nodejs方式测试Module语法。但是nodejs采用的是CommonJS的模块化规范,使用require引入
模块;而import是ES6的模块化规范关键字。想要使用import,必须引入babel转义支持,通过babel进行编译,使其变成node的模块化代码。
本文发布于:2024-02-01 01:17:46,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170672146632787.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |