babel是react团队选择的在使用react过程中转换es*和jsx为es5语句的工具。
babel可将es6和es7语句转换为es5语句。
编译转换:(1)在线转换(2)提前编译
<script src='browser.js' charset='utf-8'></script>
jsxtransformer.js |
|
babel.js |
|
browser.js |
|
将es6语法在线转换为es5语法:
<script src="browser.js" charset="UTF-8"></script>
<script type="text/babel">
let a = 1;
let b = 2;
console.log(a + b)
</script>
var | 可以重复声明定义,无法限制修改,没有块级作用域 |
let | 不可重复声明,变量->可以修改,块级作用域 |
const | 不可重复声明,常量->不能修改,块级作用域 |
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
window.onload = () => {
var btns = document.getElementsByTagName('input');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = () => {
console.log(i) // var定义的变量,会导致全部打印3
}
}
}
</script>
</head>
<body>
<input type="button" value="btn1" />
<input type="button" value="btn2" />
<input type="button" value="btn3" />
</body>
</html>
<script type="text/javascript">
window.onload = () => {
var btns = document.getElementsByTagName('input');
for (var i = 0; i < btns.length; i++) {
((i) => { //这个i是一个形参,其实可以不叫i,任何一个变量均可
btns[i].onclick = () => {
console.log(i) // 函数分别打印0,1,2
}
})(i) //这个i是一个实参
}
}
</script>
<script type="text/javascript">
window.onload = () => {
var btns = document.getElementsByTagName('input');
for (let i = 0; i < btns.length; i++) {
btns[i].onclick = () => {
console.log(i) // let定义的变量,分别打印0,1,2
}
}
}
</script>
(1)如果函数只有一个参数,()可省略;
(2)如果函数只有一条语句,{}可省略;
<script type="text/javascript">
// window.onload = () => {
// console.log('测试')
// }
window.onload = () => console.log('测试'); //第二步:打印 测试
let plusFun = params => params * 2;
console.log(plusFun(2)) //第一步:打印 4
</script>
函数参数:
(1)收集剩余的参数 …xxx
let printlog = (p1 = 9, p2, ...args, p3) => { }
Uncaught SyntaxError: Rest parameter must be last formal parameter
(2)默认参数
let printlog = (p1 = 9, p2, ...args) => {}
<script type="text/javascript">
let printlog = (p1, p2, ...args) => {
console.log(p1)
console.log(p2)
console.log(args)
}
printlog(1)
// 1
// undefined
// []
printlog(1, 2, 3, 4, 5, 6)
// 1
// 2
// [3, 4, 5, 6]
</script>
(3)展开数组 …xxx
<script type="text/javascript">
let inner = (p1, p2) => {
console.log(p1 + p2) // 4
}
((inner, ...args) => {
inner(...args)
})(inner, 1, 3)//将inner函数传入
</script>
<script type="text/javascript">
let arr = [2, 19, 1, 13, 4];
console.log(arr); //[2, 19, 1, 13, 4]
arr.sort();
console.log(arr); //[1, 13, 19, 2, 4]
arr.sort((p1, p2) => {
return p1 - p2;
})
console.log(arr); //[1, 2, 4, 13, 19]
</script>
<script type="text/javascript">
let arr = [1, 4, 3, 2];
console.log(arr.map(item => item >= 3 ? '优' : '良')) //["良", "优", "优", "良"]
let rslt1 = arr.map((item, idx, arr) => {
return item * 2;
})
let rslt2 = arr.map(item => item * 3)
console.log(arr); //[1, 4, 3, 2]
console.log(rslt1); //[2, 8, 6, 4]
console.log(rslt2) //[3, 12, 9, 6]
</script>
<script type="text/javascript">
let arr = [1, 4, 3, 2];
/* 求和 */
let rslt = arr.reduce((temp,item,idx)=>{
console.log(temp,item,idx)
// 1 4 1
// 5 3 2
// 8 2 3
return temp + item;
})
console.log(rslt); // 10
/* 求平均数 */
rslt = arr.reduce((temp, item, idx) => {
return arr.length - 1 == idx ? (temp + item) / arr.length : temp + item;;
})
console.log(rslt); // 2.5
</script>
<script type="text/javascript">
let arr = [{name:'李白',score:66},{name:'李清照',score:88},{name:'李贺',score:99}];
let rslt = arr.filter((item,idx)=>{
return item.score > 80;
});
console.log(rslt);//[{name: "李清照", score: 88},{name: "李贺", score: 99}]
</script>
<script type="text/javascript">
let arr = [{name:'李白',score:66},{name:'李清照',score:88},{name:'李贺',score:99}];
arr.forEach((item,idx)=>{
console.log(this)//this是window对象,不是arr对象
console.log(item,idx)
})
</script>
concat连接两个或多个数组。该方法不改变原有数组,仅仅返回被连接数组的一个副本。
let rslt = arr.concat(arr1, arr2, arr3, …, arrX)
<script type="text/javascript">
let arr = [1,2,3]
const [x,y,z] = arr;// x,y,z将与arr中的每个位置对应来取值
console.log(x,y,z); // 1 2 3
const [a] = arr; //只匹配1个参数
console.log(a); // 1
--------------------------------
const person = {
name:"jack",
age:21,
language: ['java','js','css']
}
// 解构表达式获取值
const {name,age,language} = person;
console.log(name);
console.log(age);
console.log(language);
--------------------------------
let arr1 = [1, 2]
let arr2 = [3, 4]
console.log([...arr1, ...arr2]) // [1, 2, 3, 4]
let [p1, p2] = [1, 2]
let [json1, arr1, str1, {p3, p4}] =
[{name: 'Michael'},
[1, 2],
'HelloWorld',
{id: '101', age: 99}
]
//大括号括起来和不用大括号有什么区别?
let aaa = ({ p1, p2, p3 = null }) => {
console.log(p1, p2, p3)
};
aaa({ p1: '1111', p2: '2222', p3: '33333' }) //1111 2222 33333
aaa(1111, 2222, 33333) //undefined undefined null
let bbb = (p1, p2, p3 = null) => {
console.log(p1, p2, p3)
};
bbb({ p1: '1111', p2: '2222', p3: '33333' }) //{p1: "1111", p2: "2222", p3: "33333"} undefined null
bbb(1111, 2222, 33333) //1111 2222 33333
</script>
<script>
// 常规的JS给函数传递一个对象参数
let sayName = (person) => {
if (Object.prototype.toString.call(person) == '[object Object]') {
console.log(`${person.firstName}----${person.lastName}`);
}
}
sayName({ firstName: 'Michael', lastName: 'Li' });//Michael----Li
// ES6的对象可以实现简写
let firstName = 'Michael';
let lastName = 'Li';
let person = { firstName, lastName }//等价于 let person = {firstName: firstName, lastName: lastName}
console.log(`${person.firstName}----${person.lastName}`); //Michael----Li
// 使用解构给变量赋值
// 解构会在右侧对象中找到和左侧对象相同的属性名,以该属性值为对应变量赋值;若没找到,则该变量值为undefined
// 解构赋值可以有默认值
let personTmp = {firstNameTmp:"Michelle", lastNameTmp:"Li"}
let {firstNameTmp, lastNameTmp, p1, p2='你好世界'} = personTmp;
console.log(`${firstNameTmp}---${lastNameTmp}---${p1}---${p2}`);//Michelle---Li---undefined---你好世界
// 注意这里变量虽然有默认值,但是函数参数是没有默认值的
function sayNameNew({ firstName = 'Bob', lastName = 'Li'}) {
console.log( firstName, lastName );
}
sayNameNew({})//Bob Li
</script>
使用 反单引号 ` ;1)可占位 2)可折行
<script type="text/javascript">
let name = '萧红';
let borthAndDeath = '1911年6月1日-1942年1月22日';
let rslt = `${name}(${borthAndDeath}),
中国近现代女作家,“民国四大才女”之一,被誉为“20世纪30年代的文学洛神”。
乳名荣华,本名张秀环,后由外祖父改名为张廼莹。
笔名${name}、悄吟、玲玲、田娣等。`
console.log(rslt)
// 萧红(1911年6月1日-1942年1月22日),
// 中国近现代女作家,“民国四大才女”之一,被誉为“20世纪30年代的文学洛神”。
// 乳名荣华,本名张秀环,后由外祖父改名为张廼莹。
// 笔名萧红、悄吟、玲玲、田娣等。
</script>
关键字:class,extends
ES6以前的写法:
<script type="text/javascript">
/* ES6以前 类的写法 */
function Student(id, name, age) {
this.id = id;
this.name = name;
this.age = age;
}
Student.prototype.showName = function() {
console.log(this.name)
}
Student.prototype.showAge = function() {
console.log(this.age)
}
var student1 = new Student(101, '萧红', 18);
student1.showName(); //萧红
student1.showAge(); //18
/* ES6以前 继承的写法 */
function VipStudent(id, name, age, level) {
Student.call(this, id, name, age)
this.level = level
}
VipStudent.prototype = new Student();
VipStudent.prototype.constructor = VipStudent;
VipStudent.prototype.showLevel = function() {
console.log(this.level)
}
let student2 = new VipStudent(102, '李清照', 16, 5);
student2.showName(); //李清照
student2.showAge(); //16
student2.showLevel() //5
</script>
ES6的写法:
<script type="text/javascript">
/* ES6定义类写法 */
class Student {
constructor(id, name, age) {
this.id = id;
this.name = name;
this.age = age;
}
showName() {
console.log(this.name)
}
showAge() {
console.log(this.age)
}
static helloWorld() {
console.log("你好世界!你好中国!")
}
}
Student.helloWorld();
let student1 = new Student(101, '萧红', 18);
student1.showName(); //萧红
student1.showAge(); //18
/* ES6 继承写法 */
class VipStudent extends Student {
constructor(id, name, age, level) {
super(id, name, age);
this.level = level;
}
showLevel() {
console.log(this.level)
}
}
let student2 = new VipStudent(102, '李清照', 16, 5);
student2.showName(); //李清照
student2.showAge(); //16
student2.showLevel() //5
</script>
babel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
let demo = document.getElementById('demo')
ReactDOM.render(<h2>你好世界</h2>,demo);
</script>
</head>
<body>
<div id="demo"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Item extends React.Component{
constructor(...args) {
super(...args);
}
render(){
return <li>{this.props.initVal}</li>;
}
}
class List extends React.Component{
constructor(...args) {
super(...args);
}
render(){
let items = this.props.arr.map((item)=><Item initVal={item}></Item>)
return <ul>{items}</ul>;
}
}
window.onload = function(){
let demo = document.getElementById('demo')
ReactDOM.render(
<List arr={['你好中国','你好世界','你好银河','你好宇宙']}></List>,
demo);
}
</script>
</head>
<body>
<div id="demo"></div>
</body>
</html>
json相关:
<script type="text/javascript">
// json字符串标准写法:
// 1)只能用双引号
// 2)所有key都必须用引号包起来
let json = {name:'Michael',age:18}
console.log(typeof JSON.stringify(json), JSON.stringify(json))
// string {"name":"Michael","age":18}
let str = '{"name":"Michael","age":18}';
json = JSON.parse(str);
// json简写
let name = "萧红";
json = {
name, // key和value相同简写
key1:'value1',
show(){ // 方法简写
console.log("show method run...")
}
}
</script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
// Promise--承诺 同步 异步
let p = new Promise((resolve, reject) => {
$.ajax({
url: 'http://127.0.0.1:8848/test2/data.json',
dataType: 'json',
success(res) {
resolve(res);
},
error(err) {
reject(err)
}
});
});
p.then((res) => {
console.log('resolve'+JSON.stringify( res))
}, (err) => {
console.log('reject'+JSON.stringify( err))
})
</script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
// Promise--承诺 同步 异步
let p1 = new Promise((resolve, reject) => {
$.ajax({
url: 'http://127.0.0.1:8848/test2/data.json',
dataType: 'json',
success(res) {
resolve(res);
},
error(err) {
reject(err)
}
});
});
let p2 = new Promise((resolve, reject) => {
$.ajax({
url: 'http://127.0.0.1:8848/test2/data2.json',
dataType: 'json',
success(res) {
resolve(res);
},
error(err) {
reject(err)
}
});
});
// p1.then((res) => {
// console.log('resolve'+JSON.stringify( res))
// p2.then((res) => {
// console.log('resolve'+JSON.stringify( res))
// }, (err) => {
// console.log('reject'+JSON.stringify( err))
// });
// }, (err) => {
// console.log('reject'+JSON.stringify( err))
// });
Promise.all([p1,p2]).then((res)=>{
let [rslt1,rslt2] = res; //解构赋值
console.log("success rslt1:",JSON.stringify(rslt1));
console.log("success rslt2:",JSON.stringify(rslt2));
},(err)=>{
console.log("fail:",JSON.stringify(err));
})
</script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
// Promise--承诺 同步 异步
function createPromise(url){
return new Promise((resolve, reject) => {
$.ajax({
url, // url: url,
dataType: 'json',
success(res) {
resolve(res);
},
error(err) {
reject(err)
}
});
});
}
let p1 = createPromise('http://127.0.0.1:8848/test2/data.json');
let p2 = createPromise('http://127.0.0.1:8848/test2/data2.json');
Promise.all([p1,p2]).then((res)=>{
let [rslt1,rslt2] = res; //解构赋值
console.log("success rslt1:",JSON.stringify(rslt1));
console.log("success rslt2:",JSON.stringify(rslt2));
},(err)=>{
console.log("fail:",JSON.stringify(err));
})
</script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
// Promise--承诺 同步 异步
let p1 = $.ajax({url: 'http://127.0.0.1:8848/test2/data.json', dataType: 'json'});
let p2 = $.ajax({url: 'http://127.0.0.1:8848/test2/data2.json', dataType: 'json'});
Promise.all([p1,p2]).then((res)=>{
let [rslt1,rslt2] = res; //解构赋值
console.log("success rslt1:",JSON.stringify(rslt1));
console.log("success rslt2:",JSON.stringify(rslt2));
},(err)=>{
console.log("fail:",JSON.stringify(err));
});
// Promise.race([p1,p2]).then((res)=>{
// let [rslt1,rslt2] = res; //解构赋值
// console.log("success rslt1:",JSON.stringify(rslt1));
// console.log("success rslt2:",JSON.stringify(rslt2));
// },(err)=>{
// console.log("fail:",JSON.stringify(err));
// });
</script>
// 普通函数 --执行期间不能中止
// generator --执行期间 可中止
// yield --放弃执行代码; 功能:(1)传参 (2)返回值
<script type="text/javascript">
function * printLog(){//*可以贴着function,也可以贴着函数名,也可以单独放置
console.log("aaa");
yield;
console.log("bbb");
}
let genObj = printLog();//此时不会执行函数
genObj.next(); // aaa //执行到第一个yield处,暂停等待next()调用
genObj.next(); // bbb
//generator 相当于将一个函数 生产 多个小函数,一个一个的单独执行
</script>
<script type="text/javascript">
function* helloMethod () {
yield "hello";
yield "world";
return "done";
}
let h = helloMethod();
console.log(h);//helloMethod {}
console.log(h.next()); //{value: "hello", done: false}
console.log(h.next()); //{value: "world", done: false}
console.log(h.next()); //{value: "done", done: true}
console.log(h.next()); //{value: undefined, done: true}
let h2 = helloMethod();
for(let obj of h2){
console.log(obj)
}
// hello
// world
</script>
<script type="text/javascript">
function* printLog() {
console.log("aaa");
let params = yield;
console.log(params);
console.log("bbb");
}
let genObj = printLog();
genObj.next(12); // aaa //第一个next中的实参无法传递给yield;若要在第一步传参可通过函数传值
genObj.next(13); // 13 //传参打印
// bbb
</script>
<script type="text/javascript">
function* printLog() {
console.log("aaa");
let params = yield 100;
console.log(params);
console.log("bbb");;
// return "结束了";
}
let genObj = printLog();
let rslt1 = genObj.next(12); // aaa //第一个next中的实参无法传递给yield;若要在第一步传参可通过函数传值
console.log(rslt1 ); // { value: 100, done: false } // rslt1 由yield返回(100返回给了rslt1)
let rslt2 = genObj.next(13); // 13 //传参打印 //(13传递给了params)
console.log(rslt2); // bbb
// { value: undefined, done: true } // 若函数有return语句则:{ value: "结束了", done: true }
</script>
<script type="text/javascript">
</script>
<script type="text/javascript">
</script>
模块化就是把代码进行拆分,方便重复利用。类似java中的导包:要使用一个包,必须先导包。
而JS中没有包的概念,换来的是 模块。
模块功能主要由两个命令构成: export 和 import 。
// Util.js
class Util {
static sum = (a, b) => a + b;
}
//导出该类
export default Util;
//Index.js
//导入Util类
import Util from './Util'
//使用Util中的sum方法
console.log(Util.sum(1, 2));
//Promise函数
function Promise(executor) {
let self = this; //保留this。防止后面方法出现this只想不明的问题
self.status = 'pending'; //promise的默认状态是pending
self.success = undefined; //保存成功回调传递的值
self.error = undefined; //保存失败回调传递的值
self.onSuccessCallbacks = []; //存放成功的回调
self.onErrorCallbacks = []; //存放失败的回调
function resolve(success) {
if (self.status === 'pending') {
self.status = 'resolved'; //成功函数将其状态修改为resolved
self.success = success; //将成功的值保存起来
self.onSuccessCallbacks.forEach(element => {
element();
});
}
}
function reject(error) {
if (self.status === 'pending') {
self.status = 'rejected'; //失败函数将其函数修改为rejected
self.error = error; //将失败的值保存起来
self.onErrorCallbacks.forEach(element => {
element();
})
}
}
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
//then函数
Promise.prototype.then = function (onResolved, onRejected) {
let self = this;
let promiseAgain = new Promise((resolve, reject) => {
if (self.status === 'pending') {
self.onSuccessCallbacks.push(() => {
let x = onResolved(self.success); //将resolve函数保留的成功值传递作为参数
resolvePromise(promiseAgain, x, resolve, reject);
})
self.onErrorCallbacks.push(() => {
let x = onRejected(self.error); //将reject函数保留的失败值传递作为参数
resolvePromise(promiseAgain, x, resolve, reject);
})
}
if (self.status === 'resolved') {
let x = onResolved(self.success); //将resolve函数保留的成功值传递作为参数
resolvePromise(promiseAgain, x, resolve, reject);
}
if (self.status === 'rejected') {
let x = onRejected(self.error); //将reject函数保留的失败值传递作为参数
resolvePromise(promiseAgain, x, resolve, reject);
}
})
return promiseAgain;
}
//resolvePromise函数
function resolvePromise(promiseAgain, x, resolve, reject) {
if (promiseAgain === x) {
return reject(new TypeError("循环调用"));
}
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, (y) => {
resolvePromise(promiseAgain, y, resolve, reject);
}, (e) => {
reject(e);
})
} else {
resolve(x);
}
} catch (error) {
reject(error);
}
} else {
resolve(x);
}
}
module.exports = Promise;
ES8中把async和await变得更加方便,它其实就是Generator的语法糖。
在代码中使用 async / await 有两个部分。
/**
*将 async 关键字加到函数申明中,可以告诉它们返回的是 promise,而不是直接返回值。
*此外,它避免了同步函数为支持使用 await 带来的任何潜在开销。
*在函数声明为 async 时,JavaScript引擎会添加必要的处理,以优化你的程序。爽!
*/
function hello1() { return "Hello 1" };
console.log(hello1()); // 返回值:Hello 1
async function hello2() { return "Hello 2" };
console.log(hello2()); // 返回值:Promise {: 'Hello 2'}
let hello3 = async function() { return "Hello 3" };
console.log(hello3()); // 返回值:Promise {: 'Hello 3'}
let hello4 = async () => { return "Hello 4" };
console.log(hello4()); // 返回值:Promise {: 'Hello 4'}
hello4().then((value) => console.log(value)) // Hello 4
hello4().then(console.log) // 返回值:Hello 4
// 当 await 关键字与异步函数一起使用时,它的真正优势就变得明显了 —— 事实上, await 只在异步函数里面才起作用。它可以放在任何异步的,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了。
// 您可以在调用任何返回Promise的函数时使用 await,包括Web API函数。
let hello5 = async () => await hello4(); // 和下面的写法效果是相同的
// let hello5 = async () => {
// let greeting = await hello4();
// return greeting;
// };
hello5().then(alert); // Hello 4