Ⅰ.ES6~POP

代码示例:https://github.com/lotapp/BaseCode/tree/master/javascript/1.ES6

在线演示:https://github.lesschina.com/js/1.base/ES6与PY3.html

ES6现在浏览器基本上都支持了,可以收一波韭菜了~(关键移动端都支持了)

1.变量

验证

  1. var:可以重复定义,不能限制修改,没有块级作用域(和Python差不多)
  2. let:不可以重复定义,相当于C#的变量,块级作用域(以后var全部换成let)
  3. const:不可以重复定义,相当于C#的常量,块级作用域

可以重复定义的验证

1.var可以重复定义

var a1 = 12; // 定义了一个a变量
// ...写了若干代码
var a1 = 5; // 然后又重新定义了一个a,这时候可能就有潜在bug了 console.log(a1); // 5

2.let不可以重复定义,相当于C#的变量(以后var全部换成let)

let a2 = 12;
let a2 = 5; // 标识符a已经被声明
console.log(a2); // Identifier 'a2' has already been declared

3.const:不可以重复定义,相当于C#的常量

const a3 = 12;
const a3 = 5; // 标识符a已经被声明
console.log(a3); // Identifier 'a3' has already been declared

可以被修改的验证

1.var可以修改

var a = 2;
a = 3; // var 可以修改
console.log(a); //3

2.let可以修改

let b = 2;
b = 3; // let可以修改
console.log(b);

3.const不可以修改

const c = 12;
c = 5; // 不能赋值给常量变量
console.log(c); // Assignment to constant variable.

验证作用域

1.var没有块级作用域

if(1<2){
var b1 = 1;
} // var没有块级作用域
console.log(b1); // 1

2.let复合正常变量特性

// 和我们平时使用差不多了
if(1<2){
let b2 = 1;
} // ReferenceError: b2 is not defined
console.log(b2); // b2 没有定义

3.更严格的const就更不说了

if(1<2){
const b3 = 1;
} // ReferenceError: b3 is not defined
console.log(b3); // b3 没有定义

Python3

变量没有修饰符的,直接定义,全局变量global引用即可

1.var变量和Python类似

if 1 < 2:
b = 1
print(b) # 1

2.全局变量建议global引用一下

age = 20

def test():
global age
print(age) # 20

结论:(以后var全部换成let)

  1. var:可以重复定义,不能限制修改,没有块级作用域(和Python差不多)
  2. let:不可以重复定义,相当于C#的变量,块级作用域(以后var全部换成let)
  3. const:不可以重复定义,相当于C#的常量,块级作用域
 

2.解构赋值

这个特性不管是C#还是ES6都是从Python那借鉴过来的,特点:

  1. 左右两边结构一样
  2. 定义和赋值同时完成

基础

简单版:

let [a,b,c] = [1,2,3];
console.log(a,b,c); // 1 2 3

变化版:

let {a,b,c} = {a:1,b:2,c:3}; // json格式对应也行
console.log(a,b,c); // 1 2 3

PS:把后面改成{a1:1,b1:2,c1:3}就变成undefined undefined undefined

复杂版:

let [x, { a, b, c }, y] = [4, { a: 1, b: 2, c: 3 }, 5];
console.log(a, b, c, x, y); // 1 2 3 4 5

验证

  1. 左右两边结构需要一样

    // 这种就不行,格式得对应(左边3,右边5个 ==> over)
    let [x, { a, b, c }, y] = { a: 1, b: 2, c: 3, x: 4, y: 5 };
    console.log(a, b, c, x, y); // 未捕获的TypeError:{...}不可迭代
  2. 定义和赋值同时完成

    let [a, b, c];
    [a, b, c] = [1, 2, 3];
    // 未捕获的SyntaxError:在解构声明中缺少初始化程序
    console.log(a, b, c);
 

3.函数系

3.1.箭头函数(匿名函数)

以前写法:

function (参数,参数){
函数体
}

简化写法:

(参数,参数) => {
函数体
} 参数 => {
函数体
} 参数 => 表达式

举个例子

function add(x, y) {
return x + y;
} let add1 = function (x, y) {
return x + y;
} let add2 = (x, y) => {
return x + y;
} let add3 = (x,y) => x+y;
console.log(add(1, 2)); // 3
console.log(add1(1, 2)); // 3
console.log(add2(1, 2)); // 3
console.log(add3(1, 2)); // 3

小验证(和Net用起来基本上一样

  1. 如果只有一个参数:()可以省略

    let get_age = age => {
    return age - 2;
    }
    console.log(get_age(18)); // 16
  2. 如果函数体只有一句话:{}可以省略
    • 如果只有一句return,那么return也可以省略

      let get_age = age => age - 2;
      console.log(get_age(18)); // 16
    • 没有return也可以简写
      let print_age = age => console.log(age - 2);
      print_age(18); // 16

PS:箭头函数会改变this(后面会说)


3.2.默认参数

// 原来:
function show(a, b, c) {
c = c || 7; // 默认参数
console.log(a, b, c);
}
// 现在:
function show(a, b, c = 7) {
console.log(a, b, c);
} show(1, 2); // 1 2 7
show(1, 2, 3); // 1 2 3

3.3.参数展开

基本用法

举个例子:

let show_args = (a, b, ...args) => console.log(a, b, args);
// `...args`是个数组(Python是元组)
show_args(1, 2, 3, 4, 5, 6);// 1 2 [3, 4, 5, 6]

小验证

  1. ...args必须是最后一个参数

    let show_args = (a, b, ...args, c) => console.log(a, b, args, c);
    // Uncaught SyntaxError: Rest parameter must be last formal parameter
    show_args(1, 2, 4, 5, 6, c = 3); // ...args必须是最后一个参数

PS:Python里面可以

def show(a, b, *args, c):
print(a, b, args, c) # 1 2 (4, 5, 6) 3
show(1, 2, 4, 5, 6, c=3)

扩展用法

案例1

let nums = [1, 2, 3, 4];
// 解包使用
let nums2 = [0, ...nums, 5, 6];
// [0,1,2,3,4,5,6]
console.log(nums2);

PS:Python用法类似

# 列表换成元组也一样用
num_list = [1,2,3,4]
# 不管是列表还是元组,这边需要加*才能解包
num_list2 = [0,*num_list,5,6]
# [0, 1, 2, 3, 4, 5, 6]
print(num_list2)

案例2

let nums = [1, 2, 3, 4];
let nums2 = [0, 5, 6];
nums.push(...nums2);
// [1, 2, 3, 4, 0, 5, 6]
console.log(nums);

PS:Python用法类似

num_list = [1,2,3,4]
num_list2 = [0,5,6]
# [1, 2, 3, 4, 0, 5, 6]
num_list.extend(num_list2)
print(num_list) # 如果使用append就是嵌套版列表了
# num_list.append(num_list2)
# [1, 2, 3, 4, [0, 5, 6]]

3.4.特殊的this(重要)

普通函数的this ==> 谁调用就是谁(经常变:谁调用是谁)

function show() {
alert(this); // 1,2,3,4
console.log(this); // [1, 2, 3, 4, show: ƒ]
} let arr = [1, 2, 3, 4];
arr.show = show;
arr.show();

箭头函数的this ==> 在谁的环境下this就是谁(不变:当前作用域)

let arr = [1, 2, 3, 4];
arr.show = () => {
alert(this); // [object Window]
console.log(this); // Window
}
arr.show();

再举个例子:在document内

document.onclick = function () {
let arr = [1, 2, 3, 4];
arr.show = () => {
console.log(this); // document
}
arr.show();
}
 

4.数组方法

下面几个方法都不会改变原数组

4.1.map

映射,传几个参数进去,出来几个参数。(不改变数组内容,生成新数组

基本用法

scor_arr = [100, 28, 38, 64]
let results = scor_arr.map(item => item >= 60); // [true, false, false, true]
console.log(results); // 不改变scor_arr内容,生成新数组 // old:
// let results = scor_arr.map(function (item) {
// return item >= 60;
// });

Python3

Python略有不同:(把函数依次作用在list的每个元素上)

scor_list = [100, 28, 38, 64]
result_list = map(lambda item: item >= 60, scor_list) # [True, False, False, True] 不改变旧list的值
print(list(result_list))

PS:result_list:PY2直接返回list,PY3返回Iterator


4.2.filter

代言词:过滤不改变数组内容,生成新数组

基本用法

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
nums2 = nums.filter(item => item % 2 == 0); // [2, 4, 6, 8, 10]
console.log(nums2) // 不改变旧数组的值

Python3

Python略有不同:(把函数依次作用在list的每个元素上)

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nums2 = filter(lambda item: item % 2 == 0, nums) # [2, 4, 6, 8, 10] 不改变旧list的值
print(list(nums2))

PS:nums2:PY2直接返回list,PY3返回Iterator


4.3.forEach

不做任何修改,纯粹的遍历,用法和net里面的ForEach差不多

forEach没有返回值的验证

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = 0;
let temp =nums.forEach(item => {
sum += item;
});
console.log(sum) // 55
console.log(temp) // 验证了:forEach 没有返回值

NetCore

var sum = 0;
var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
list.ForEach(item => sum += item);
Console.WriteLine(sum); // 55

不会改变原数组的验证

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
nums.forEach(item => {
item += 1;
}); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(nums); //不会改变nums,仅仅是遍历

NetCore

var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
list.ForEach(item => item += 1);
foreach (var item in list)
{
// 12345678910
Console.Write(item); //不会改变list里面的值
}

4.4.reduce

代言词:汇总,和map有点相反,进去一堆出来一个

基础用法

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// x是第一个元素,y是第二个元素
nums.reduce((x, y, index) => {
console.log(x, y, index);
});

输出:

1 2 1
undefined 3 2
undefined 4 3
undefined 5 4
undefined 6 5
undefined 7 6
undefined 8 7
undefined 9 8
undefined 10 9

逆推JS执行过程

逆推整个执行过程

  1. x只被赋值一次
  2. y从第二个值开始往下遍历
  3. 整个过程只遍历9遍就结束了
    • for循环需要10次遍历结束
    • y从第二个数开始的,少一次遍历也正常

简单说就是按顺序依次执行函数,eg:

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
result = nums.reduce((x, y) => x + y);
console.log(result / nums.length) // 5.5

reduce直接求平均值:(return是关键)

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let result = nums.reduce((temp, item, index) => {
temp += item;
if (index < nums.length - 1) {
return temp;
} else { // 最后一次,返回平均值即可
return temp / nums.length;
}
});
console.log(result) // 5.5

Python3

reduce就两个参数(有且仅有

PythonReducejs的强大,一般都是对列表做一个累积的‘汇总’操作

import functools
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = functools.reduce(lambda x, y: x + y, nums)
print(result / len(nums)) # 5.5

可以看看执行过程:

import functools

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = functools.reduce(lambda x, y: print(x, y), nums)
print(result)

输出:

1 2
None 3
None 4
None 5
None 6
None 7
None 8
None 9
None 10
None

4.5.Array.from

通俗讲:把类数组集合转化成数组

HTML代码:/BaseCode/javascript/1.ES6/1.array.from.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Array.from的应用</title>
</head>
<body>
<style type="text/css">
div {
width: 200px;
height: 200px;
margin-right: 1px;
float: left;
}
</style>
<div></div>
<div></div>
<div></div>
</body>
</html>

JS部分:(collection是没有forEach方法的,需要转化成数组)

window.onload = () => {
let collection = document.getElementsByTagName("div");
Array.from(collection).forEach(item => item.style.background = "blue");
}
 

5.JSON系

键值相同可以只写一个

let [a, b] = [1, 2];
json = { a, b, c: 3 };
console.log(json); // {a: 1, b: 2, c: 3} // 原来写法
// json = { a: a, b: b, c: 3 };

函数function可以省略

json = {
a: 1,
b: 2,
show() {
console.log(this.a, this.b);
}
};
json.show(); // 1 2 // 原来写法
// json = {
// a: 1,
// b: 2,
// show: function () {
// console.log(this.a, this.b);
// }
// };

基础复习

Json字符串的标准写法

  1. 只能用双引号
  2. 所有名字必须用引号包裹
let str1 = '{ a: 12, b: 5 }'; // 错误
let str2 = '{ "a": 12, "b": 5 }';// 正确
let str3 = "{ 'a': 'abc', 'b': 5 }";// 错误(单引号)
let str4 = '{ "a": "abc", "b": 5 }';// 正确(双引号) // 测试是否为字符串
[str1, str2, str3, str4].forEach(str => {
try {
let json = JSON.parse(str);// 转换成JSON对象
console.log(json);
} catch (ex) {
console.log(`字符串:${str}转换发生异常:${ex}`);
}
});

输出:

字符串:{ a: 12, b: 5 }转换发生异常:SyntaxError: Unexpected token a in JSON at position 2
1.base.json.html:21 {a: 12, b: 5}
1.base.json.html:23 字符串:{ 'a': 'abc', 'b': 5 }转换发生异常:SyntaxError: Unexpected token ' in JSON at position 2
1.base.json.html:21 {a: "abc", b: 5}

字符串和Json相互转换

  1. 字符串转换成Json对象:JSON.parse()
  2. Json对象转换成字符串:JSON.stringify()
let json1 = { name: "小明", age: 23, test: "我X!@#$%^&*(-_-)=+" };
let new_str = JSON.stringify(json1);
console.log(new_str); // encodeURI对有些特殊符号并不会编码替换
let urlstr = encodeURIComponent(`https://www.baidu.com/s?wd=${new_str}`);
console.log(urlstr);
console.log(decodeURIComponent(urlstr));

输出:

{"name":"小明","age":23,"test":"我X!@#$%^&*(-_-)=+"}

https://www.baidu.com/s?wd=%7B%22name%22:%22%E5%B0%8F%E6%98%8E%22,%22age%22:23,%22test%22:%22%E6%88%91X!@#$%25%5E&*(-_-)=+%22%7D

https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%7B%22name%22%3A%22%E5%B0%8F%E6%98%8E%22%2C%22age%22%3A23%2C%22test%22%3A%22%E6%88%91X!%40%23%24%25%5E%26*(-_-)%3D%2B%22%7D

https://www.baidu.com/s?wd={"name":"小明","age":23,"test":"我X!@#$%^&*(-_-)=+"}
 

5.字符串系

1.字符串模板

渲染变量

省的一个个去拼接了(PS:反单引号

let [name,age]=["小明",23];

// 我叫小明,我今年23
console.log(`我叫${name},我今年${age}`);

Python3用起来差不多

name, age = "小明", 23

# 我叫小明,今年23
print(f"我叫{name},今年{age}")

保持原有格式

注意一点:换行内容如果不想要空格就顶行写

console.log(`我叫:
小明
今年:
23`);

输出:

我叫:
小明
今年:
23

Python就换成了"""

print("""我叫:
小明
今年:
23
""")

2.开头结尾方法

基本用法

let url = "https://www.baidu.com";

if (url.startsWith("http://") || url.startsWith("https://")) {
console.log("B/S");
} if (url.endsWith(".com")) {
console.log(".com")
}

Python3

url = "https://www.baidu.com"

if url.startswith("https://") or url.startswith("http://"):
print("B/S") if url.endswith(".com"):
print(".com")
In [ ]:
 
 

Ⅱ.ES6~OOP

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes

以前JS的OOP严格意义上还是一个个函数,只是人为给他含义罢了,现在是真的支持了,性能和语法都优化了

1.封装

// People后面没有括号
class People {
// 构造函数
constructor(name, age) {
this.name = name;
this.age = age;
}
show() {
console.log(`我叫:${this.name},今年${this.age}`);
}
// 静态方法
static hello() {
console.log("Hello World!");
}
}
// new别忘记了
let xiaoming = new People("小明", 23);
xiaoming.show(); //我叫:小明,今年23
// xiaoming.hello(); 这个不能访问(PY可以)
People.hello(); //Hello World!

看看Python怎么定义的:(self每个都要写)

class People(object):
def __init__(self, name, age):
self.name = name
self.age = age def show(self):
print(f"我叫:{self.name},今年:{self.age}") @classmethod
def hello(cls):
print("Hello World!") xiaoming = People("小明", 23)
xiaoming.show() # 我叫:小明,今年:23
# 这个虽然可以访问到,但我一直都不建议这么用(不然用其他语言会混乱崩溃的)
xiaoming.hello() # Hello World!
People.hello() # Hello World!

PS:JS后来居上,看起来语法比PY更简洁点了

2.继承

class Teacher extends People {
constructor(name, age, work) {
super(name, age); // 放上面
this.work = work;
}
show_job() {
console.log(`我是做${this.work}工作的`);
}
}
let xiaozhang = new Teacher("小张", 25, "思想教育");
xiaozhang.show(); // 我叫:小张,今年25
xiaozhang.show_job(); // 我是做思想教育工作的
Teacher.hello(); // Hello World!

PS:如果子类中存在构造函数,则需要在使用this之前首先调用super()

看看Python语法:

class Teacher(People):
def __init__(self, name, age, work):
self.work = work
super().__init__(name, age) def show_job(self):
print(f"我是做{self.work}工作的") xiaozhang = Teacher("小张", 25, "思想教育")
xiaozhang.show() # 我叫:小张,今年:25
xiaozhang.show_job() # 我是做思想教育工作的
Teacher.hello() # Hello World!

3.多态

多态这方面和Python一样,有点后劲不足,只能伪实现,不能像Net、Java这些这么强大

class Animal {
constructor(name) {
this.name = name;
}
run() {
console.log(`${this.name}会跑`);
}
}
class Dog extends Animal {
run() {
console.log(`${this.name}会飞快的跑着`);
}
}
// 借助一个方法来实现多态
let run = obj => {
obj.run()
}
run(new Animal("动物")); // 动物会跑
run(new Dog("小狗")); // 小狗会飞快的跑着

Python也半斤八两,十分相似

class Animal(object):
def __init__(self, name):
self.name = name def run(self):
print(f"{self.name}会跑") class Dog(Animal):
def run(self):
print(f"{self.name}会飞快的跑着") # 借助一个方法来实现多态
def run(obj):
obj.run() run(Animal("动物")) # 动物会跑
run(Dog("小狗")) # 小狗会飞快的跑着
 

业余拓展

函数中的bind

直接指定函数中this的值,防止改变

如果指定一个事件执行函数的时候,class里面的this会变化,这时候不想外面套一层方法就可以使用bind

class People {
constructor(name, age) {
this.name = name;
this.age = age;
}
show() {
console.log(this);
console.log(`我叫:${this.name},今年${this.age}`);
}
} let p = new People("小明", 23); // 按照道理应该可以,但是因为this变了,所以不行
//document.onclick = p.show; // 我叫:undefined,今年undefined // 原来写法:外面包裹一层方法
//document.onclick = () => p.show(); // 我叫:小明,今年23 // 简写:bind
document.onclick = p.show.bind(p); // 我叫:小明,今年23

几个验证

小验证:直接指定函数中this的值,防止改变

function show() {
console.log(this);
}
document.onclick = show; // document
document.onclick = show.bind("mmd"); // String {"mmd"}

小验证箭头函数的优先级比bind高

document.onclick = function () {
let arr = [1, 2, 3, 4];
arr.show = () => {
console.log(this); // document
}
arr.show.bind("mmd"); // 箭头函数的优先级比bind高
arr.show();
}

ES6继承的不足

  1. 只支持静态方法,不支持静态属性
  2. class中不能定义私有变量和函数
    • class中定义的所有方法都会被放倒原型当中,都会被子类继承,而属性都会作为实例属性挂到this上

课后拓展:https://www.jianshu.com/p/5cb692658704

Python3与NetCore

Python3 与 C# 面向对象之~封装https://www.cnblogs.com/dotnetcrazy/p/9202988.html

Python3 与 C# 面向对象之~继承与多态https://www.cnblogs.com/dotnetcrazy/p/9219226.html

 

4.OOP实战

微信小程序出来后,组件化的概念越来越火(可以理解为模块化),结合OOP真的很方便

4.1.React组件引入

先看个React的基础案例(结合Next.js更爽)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>React组件化</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./js/react/16.6.3/react.production.min.js"></script>
<script src="./js/react-dom/16.6.3/react-dom.production.min.js"></script>
<script src="./js/babel-core/5.8.38/browser.min.js"></script>
<!-- 注意下类型是"text/babel" -->
<script type="text/babel">
window.onload=function () {
let item = document.getElementById("test");
ReactDOM.render(
<strong>公众号:逸鹏说道</strong>,
item
);
};
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>

输出:公众号:逸鹏说道

扩展说明

业余扩展:AMDCMDCJSUMDhttps://blog.csdn.net/yikewang2016/article/details/79358563

1.React and babel

PS:React 16.x开始

  1. react.js ==> react.development.js

    • react.min.js ==> react.production.min.js
  2. react-dom.js ==> react-dom.development.js
    • react-dom.min.js ==> react-dom.production.min.js

PS:如果自己找JS,搜索三个包:reactreact-dombabel-core 5.x(JSX)

2.npm and cnpm

npm国内镜像https://npm.taobao.org

配置一下即可:npm install -g cnpm --registry=https://registry.npm.taobao.org

然后就可以把cnpm当作npm来用了,比如上面三个js文件:

  1. cnpm install react
  2. cnpm install react-dom
  3. cnpm i babel-core@old

PS:iinstall的简写,-g是安装到全局环境中,不加就只是安装到当前目录


4.2.OOP组件

1.OOP改造

OOP来改造一下上面的案例:(ReactDOM在执行render渲染<MyTest>标签的时候会返回,MyTest类里面的return值

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>OOP组件</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./js/react/16.6.3/react.production.min.js"></script>
<script src="./js/react-dom/16.6.3/react-dom.production.min.js"></script>
<script src="./js/babel-core/5.8.38/browser.min.js"></script>
<script type="text/babel">
class MyTest extends React.Component{
// 可以省略
constructor(...args){
super(...args);
}
// 必须定义的方法
render(){
return <strong>公众号:逸鹏说道</strong>;
}
}
window.onload=()=>{
let test = document.getElementById("test");
ReactDOM.render(
<MyTest></MyTest>,
test
);
}
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>

输出:公众号:逸鹏说道

语法衍生

好处通过这个案例可能还看不出来,但是你想一下:当那些常用功能模板成为一个个自己的组件时,你的每一次前端开发是多么幸福的事情?

再语法衍生一下,来个稍微动态一点案例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>OOP组件</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./js/react/16.6.3/react.production.min.js"></script>
<script src="./js/react-dom/16.6.3/react-dom.production.min.js"></script>
<script src="./js/babel-core/5.8.38/browser.min.js"></script>
<script type="text/babel">
class Item extends React.Component{
render(){
console.log(this);
return <strong>{this.props.str}</strong>;
}
}
window.onload=()=>{
ReactDOM.render(<Item str="我叫小明"></Item>,document.getElementById("test"));
}
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>

输出:(两种方式传参:1.字符串,2.{}表达式)

自定义组件

有上面两个铺垫,现在做个自己的小组件:

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>OOP组件</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./js/react/16.6.3/react.production.min.js"></script>
<script src="./js/react-dom/16.6.3/react-dom.production.min.js"></script>
<script src="./js/babel-core/5.8.38/browser.min.js"></script>
<script type="text/babel">
class Item extends React.Component{
render(){
console.log(this);
return <li><strong>{this.props.str}</strong></li>;
}
}
class MyList extends React.Component{
render(){
console.log(this);
return <ul>
{this.props.names.map(x=> <Item str={x}></Item>)}
</ul>
}
}
window.onload=()=>{
let test = document.getElementById("test");
ReactDOM.render(
// 这边的值可以从后台获取
<MyList names={["Golang","Python","NetCore","JavaScript"]}></MyList>,
test
);
}
</script>
</head> <body>
<div id="test"></div>
</body>
</html>

输出:(两种方式传参:1.字符串,2.{}表达式)

In [ ]:
 
 

Ⅲ.ES6~EXT

课后拓展:https://www.babeljs.cn/learn-es2015/

1.异步

最后方案和写法类似于PythonNetCore,都是asyncawait,前面是一步步引入(本质)

1.1.JQ引入

常见情景

基于JQ的异步操作很常见,比如:

console.log("--------------------")
$.ajax({
url: "./data/user.json",
dataType: "json",
success(data) {
console.log(data);
}, error(ex) {
console.log("请求失败");
}
});
console.log("--------------------")

输出:(的确是异步操作,不等结果返回就先执行下面语句了)

--------------------
--------------------
{Name: "小明", Age: 23}

探讨本质

那么它的本质是什么呢?来看看返回什么:

let p1 = $.ajax({
url: "./data/user.json",
dataType: "json"
});
console.log(p1);

输出:(其实本质也是一个封装版的Promise

用等价写法改装一下:(then两个方法,一个处理成功,一个处理失败

let p1 = \$.ajax({
url: "./data/user.json",
dataType: "json"
}); // 不存在的文件
let p2 = \$.ajax({
url: "./data/mmd.json",
dataType: "json"
}); p1.then(data => console.log(data), ex => console.log("请求失败"));
p2.then(data => console.log(data), ex => console.log("请求失败"));

输出:(忽略上面的\我的渲染有的问题,需要转义一下)

{Name: "小明", Age: 23}
请求失败

1.2.Promise

简单的说就是:Promise:用同步的方式去写异步

语法:Promise(()=>{});

有点类似于NetCoreTask==> Task.Run(()=>{});

上面的那个例子本质上相当于:

let p1 = new Promise((resolve, reject) => {
$.ajax({
url: "./data/user.json",
dataType: "json",
success(data) {
resolve(data);
},
error(ex) {
reject(ex);
}
});
});
p1.then(data => console.log(data), ex => console.log("请求失败"));

业务上难免都有相互依赖,以前写法也只能在sucess回调函数里面一层层的嵌套

一个是比较麻烦,还有就是看起来特别不方便,一不小心就搞错了,现在就简单多了,then里面直接处理

咋一看,没啥好处啊?而且还复杂了,其实当任务多的时候好处就来了

比如结合JQ来模拟一个事务性的案例

let p1 = $.ajax({ url: "./data/user.json", dataType: "json" });
let p2 = $.ajax({ url: "./data/list.txt", dataType: "json" });
let p3 = $.ajax({ url: "./data/package.json", dataType: "json" }); // 进行一系列处理(有一个失败都会直接进入错误处理)
Promise.all([p1, p2, p3]).then(arr => {
// 这时候返回的是一个数组
console.log(arr);
}, ex => {
console.error(ex);
});

输出:

 

2.迭代器

这个简单过一下,和Python没有太多不同

2.1.引入

function*来定义一个迭代器

function* show() {
console.log("a");
yield "1";
console.log("b");
yield "2";
console.log("c");
return "d";
} let gen = show();
// 每一次next都执行到下一个yield停止
console.log(gen.next());
// 返回值.value 可以得到yield返回的值
console.log(gen.next().value);
// done==true的时候代表迭代结束
console.log(gen.next());

输出:

a
{value: "1", done: false}
b
2
c
{value: "d", done: true}

2.2.遍历

JavaScript

通过上面输出可以瞬间知道退出条件:done: true,那么遍历方式就来了:

function* show() {
yield "1";
yield "2";
return "d";
}
let gen = show(); while (true) {
let result = gen.next();
if (result.done) {
console.log(`返回值:${result.value}`);
break;
} else {
console.log(result.value);
}
}

输出:

1
2
返回值:d

JS也提供了for of来遍历:

for (let item of show()) {
console.log(item);
}

Python3

大体上差不多,结束条件是触发StopIteration异常

def show():
yield "1"
yield "2"
return "d" gen = show() while True:
try:
print(next(gen))
except StopIteration as ex:
print(f"返回值:{ex.value}")
break for item in show():
print(item) # 1 2

输出:

1
2
返回值:d
1
2

2.3.传参

JavaScript

function* show2() {
a = yield "111";
console.log(a);
b = yield a;
console.log(b);
c = yield b;
console.log(c);
return "over";
} let gen = show2();
// 和Python一样,第一个不传参
console.log(gen.next());
console.log(gen.next("aaa"));
console.log(gen.next("bbb"));
console.log(gen.next("ccc"));

输出:

{value: "111", done: false}
aaa
{value: "aaa", done: false}
bbb
{value: "bbb", done: false}
ccc
{value: "over", done: true}

Python3

传参Python是使用的send方法,其实next本质也是send,这个之前讲过了:

def show():
a = yield "111"
print(a)
b = yield a
print(b)
c = yield b
print(c)
return "over" gen = show()
# 第一个不传参
print(next(gen)) # gen.send(None)
print(gen.send("aaa"))
print(gen.send("bbb"))
try:
print(gen.send("ccc"))
except StopIteration as ex:
print(ex.value)

输出:

111
aaa
bbb
bbb
ccc
over
 

3.async/await

如果你现在还没有用过asyncawait的话...需要好好提升下了,还是通俗说下吧:

  1. await你可以理解为:等待后面异步方法的结果,这时候的结果就是你需要的
  2. async你可以理解为:使用了await的方法需要特殊标记一下

3.1.引入

ES6出来前,我们用异步一般是这么用的:

  1. 和下文JS不关联的外部JS,都打个异步标签来异步加载
  2. <script src="./js/test.js" async></script>

现在可以正经的使用了,继续把上面那个例子衍生下:(之前用then(()=>{},()=>{}),现在可以使用asyncawait来简化)

async function show(url) {
let data = await $.ajax({ url: url, dataType: 'json' });
console.log(data)
}
show("./data/list.txt")

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

3.2.批量

就算是批量任务也不用那么麻烦了:

let show = async (urls) => {
for (const url of urls) {
let data = await $.ajax({ url: url, dataType: "json" });
console.log(data);
}
} show(["./data/user.json", "./data/list.txt", "./data/package.json"]);

输出:

{Name: "小明", Age: 23}
[1, 2, 3, 4, 5, 6, 7, 8, 9]
{name: "data", version: "0.1.0", description: "测试", main: "index.js", scripts: {…}, …}

3.3.匿名

应用常见其实很多,比如执行某个事件、比如引入某个外部JS...,eg:

test.js

(async () => {
let data = await $.ajax({ url: "./data/list.txt", dataType: 'json' });
console.log(data);
})();

HTML中引用一下:<script src="./js/test.js" async></script>

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

3.4.嵌套

NetCore一样,可以嵌套使用的,await的对象一般都是Promise或者同是async修饰的方法

举个例子

test.js

let show = async (urls) => {
for (const url of urls) {
let data = await $.ajax({ url: url, dataType: "json" });
console.log(data);
}
return "ok";
} let test = async () => {
let result = await show(["./data/user.json", "./data/list.txt", "./data/package.json"]);
return result;
}

页面

<script src="./js/test.js"></script>
<script>
(async () => {
let data = await test();
console.log(data);
})();
</script>

输出:

{Name: "小明", Age: 23}
[1, 2, 3, 4, 5, 6, 7, 8, 9]
{name: "data", version: "0.1.0", description: "测试", main: "index.js", scripts: {…}, …}
ok

Python3

Python3.7开始,语法才开始简洁:

import asyncio

# 模拟一个异步操作
async def show():
await asyncio.sleep(1)
return "写完文章早点睡觉哈~" # 定义一个异步方法
async def test(msg):
print(msg)
return await show() # Python >= 3.7
result = asyncio.run(test("这是一个测试"))
print(result) # Python >= 3.4
loop = asyncio.get_event_loop()
result = loop.run_until_complete(test("这是一个测试"))
print(result)
loop.close()

输出:

这是一个测试
写完文章早点睡觉哈~
 

4.模块化

这个ES6里面有,但是浏览器并没有完全支持,所以现在大家还是用Require.jsSea.js更多点

简单看看就行:扩展链接 ~ https://www.cnblogs.com/diligenceday/p/5503777.html

模块定义:

export { a, test, user }

let test = () => {
console.log("test");
} let user = () => {
console.log("user");
return "小明";
} let a = 1;

导入模块:

import { a, test, user } from "./mod.js"
console.log(a);
test();
console.log(user());

一文读懂ES6(附PY3对比)的更多相关文章

  1. 一文读懂MapReduce 附流量解析实例

    1.MapReduce是什么 Hadoop MapReduce是一个软件框架,基于该框架能够容易地编写应用程序,这些应用程序能够运行在由上千个商用机器组成的大集群上,并以一种可靠的,具有容错能力的方式 ...

  2. 一文读懂高性能网络编程中的I/O模型

    1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...

  3. [转帖]一文读懂 HTTP/2

    一文读懂 HTTP/2 http://support.upyun.com/hc/kb/article/1048799/ 又小拍 • 发表于:2017年05月18日 15:34:45 • 更新于:201 ...

  4. kubernetes基础——一文读懂k8s

    容器 容器与虚拟机对比图(左边为容器.右边为虚拟机)   容器技术是虚拟化技术的一种,以Docker为例,Docker利用Linux的LXC(LinuX Containers)技术.CGroup(Co ...

  5. 大数据篇:一文读懂@数据仓库(PPT文字版)

    大数据篇:一文读懂@数据仓库 1 网络词汇总结 1.1 数据中台 数据中台是聚合和治理跨域数据,将数据抽象封装成服务,提供给前台以业务价值的逻辑概念. 数据中台是一套可持续"让企业的数据用起 ...

  6. 一文读懂HTTP/2及HTTP/3特性

    摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何 ...

  7. 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现

    一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...

  8. 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

    本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...

  9. 一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm)

    一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm) 2017-12-25  16:29:19   对于 A3C 算法感觉自己总是一知半解,现将其梳理一下,记录在此,也 ...

随机推荐

  1. Android 修改包名,导致安装错误

    一.app运行安装时出错 [安装时出错]: [百度翻译] 安装失败的消息未能敲定会议:install_failed_invalid_apk:/数据/应用程序/ vmdl292154713.tmp/9_ ...

  2. 面板JPanel,滚动面板JScrollPane,文本域JTextArea

    [面板JPanel] 面板就是一个容器 每一个容器都可以有一个自己的独立的布局和组件,这些容器之间也不会互相干扰 //导入Java类 import javax.swing.*; import java ...

  3. ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)分部视图简介 ASP.NET Core MVC (Razor)分部视图基础教程 ASP.NET Core MVC (Raz ...

  4. AjaxPro2完整入门教程

    一.目录 简单类型数据传送(介绍缓存,访问Session等) 表类型数据传送 数组类型数据传送(包含自定义类型数据) 二.环境搭建 1.这里本人用的是VS2012. 2.新建一个空的Web项目(.NE ...

  5. MySql 学习之路-高级1

    Mysql自学之路-高级1 目录: 1.CREATE DATABASE 创建数据库 2.CREATE TABLE 创建数据表 3.INSERT INTO SELECT 把一个表中的数据拷贝到另一个表中 ...

  6. 在Linux系统中同步更新我们的Github博客

    原理介绍 类似于版本管理,我们把我们的hexo博客文件系统在Github上建立一个分支,通过管理分支提交最新的博客文件系统,保证我们博客框架的更新.然后我们基于最新的博客框架,撰写文章,进行Githu ...

  7. 《Effective Java中文版第二版》读书笔记

    说明 这里是阅读<Effective Java中文版第二版>的读书笔记,这里会记录一些个人感觉稍微有些重要的内容,方便以后查阅,可能会因为个人实力原因导致理解有误,若有发现欢迎指出.一些个 ...

  8. SpringCloud 学习网址记录

    SpringCloud Gateway https://www.cnblogs.com/ityouknow/p/10141740.html 熔断降级的概念 https://blog.csdn.net/ ...

  9. ubuntu下安装飞鸽传书

    1.从官网下载Linux版本飞鸽传书(http://www.ipmsg.org.cn/) 2.解压后执行 ./QIpmsg 若报错 libstdc++.so.6: version `CXXABI_AR ...

  10. Mongo字符串类型的数值查询---$Where查询介绍

    ​        在Mongo中都知道字符串类型大小比较都是以ASCII进行比较的,所以无法真实比较字符串类型的数值大小 ​      比如查询age大于3的: db.getCollection(&q ...