Hawei

Say Hi.


  • Home

  • About

  • Tags

  • Categories

  • Archives

6.typescript.md

Posted on 2020-04-12 | In deep-js-foundations-v2-noteBook

typescript

Typescript/flow, and typt aware linting.

typescript benefits:

  1. Catch type-related mistake
  2. Communicate type intent (类型推断)
  3. Provide IDE feedback

caveats

  1. Inferencing is best-guess, not a guarantee
  2. Annotations is optional
  3. Any part of the application that isn’t typed introduces uncertainty.

Inferencing:

在使用静态语言编写代码的时就会进行类型推断,并且与IDE很好的支持(有提示插件)。但是推断解决的问题是, 我们对一个变量不确定类型,很容易造成’xxx is undefined.’等error

在定义时就确定了类型, 在之后给该变量赋值使用不同的类型时,就会报错。

1
2
3
4
5
6
7
8
// example 1
var name = 'keywen'

name = {
value: 'keywen' // throw Error.
}
// example 2: 显示的确定其类型
var name: String = 'keywen'

custom type

自定义类型: 语法

1
2
3
4
5
6
7
8
// ":" 后是指定的类型
type student = {
name: string
}

function getName (studentObj: student): string {
return studentObj.name
}

Validating Operand Types

1
2
3
// case1,在这种情况下,我们不会触发强制, 只会在特定的类型进行运算, 防止出现我们意料之外的错误
var studentName: string = 'Nacy';
var studentSum: number = 16 - studentName; // throw error: can't substract sting

compare typescript with flow

不用比较了typescript已经赢了

两者主要是解决了我们在编程过程中对类型的不确定,让我们的类型更加清晰(前面说过了, 如果你对你代码中的类型不确定,那么, 最好的方式是重构你的代码, 因为你对你的代码还不够了解)

typescript的优点

  1. They make our code more obvious.
  2. more like other language’s systems.
  3. Extremely popular these days.(生态将会更好)
  4. 微软做背书,值得投资学习。
  5. They’re very sophisticated and good at what they do.(根据社区的反馈,他们做得非常好,至少在类型判断这一点上)

typescript的缺点

  1. They use “non-js-standard”syntax(or code comments)
    从长远看, 这是很危险的, 因为不使用标准语法, 那么在未来的某一天,js改了标准,而ts又改了足够多的东西,要么ts继续往js的标准走,要么ts成为另一种方言, 或者取代js
  2. They require a build process, which raises the barrier to entry
  3. Their sophistication can be intimidating to those without prior formal types experience(对于没有静态语言经历的同学就有点可怕了)
  4. They focus more on “static type”(variables, parameters, returns, properties)then value types.(ts更多的关注在变量的静态, 而不是值的静态)

我们知道,代码中的bug很大一部分是type问题造成的,那么ts和flow就解决了这个问题,但要意识到,这并不是唯一的解决方法

总结

  1. js本身拥有一个(动态)类型系统,它使用不同形式的强制转换,value的类型转换,运算符的转换, 等号两边的转换
  2. 然鹅,这样的类型系统大家给出的回应, 或者说解决方案是: 尽可能避免这样的系统,尽可能的使用”===”, 保护你担忧的类型
  3. 避免整个JS的部分问题,比如假装==避免了您需要了解类型,是它倾向于系统地使bug永久存在。在某些场景下,你最好还是使用“==”, 例如你非常了解你的类型系统时, 使用== 会让事情更简单,如果强行使用 === 那么这会造成系统级别的bug.
  4. 如果你不是足够的了解js的类型系统,那么就无法编写高质量的js代码.
  5. 使用静态语言系统或许是你的一个选择, 但不是唯一的解决方案。
  6. js的类型系统相对于静态语言来说的类型系统比较怪异, 但是学习它也是解决类型问题的一种方式
  7. 对于有过静态语言学习经验的开发者来说,js的类型系统对他们来说很难接受,而静态语言学习起来较为容易
  8. 我的主张:更好的方法是拥抱和学习JS的类型系统,并采用一种编码风格,使类型尽可能明显

7.Object.md

Posted on 2020-04-12 | In deep-js-foundations-v2-noteBook

Object

Overview

  1. this
  2. class {}
  3. Prototype
  4. Inheritance vs Behavior Delegation (继承 vs 代理)

this keyword

this 关键字最大的作用是, 提升了代码的复用性和赋予函数的多态性(通过使用this获取不同的context, 从而函数得到不同的返回)

implicitly && Explicit Binding

隐式绑定

1
2
3
4
5
6
7
8
9
var workspace = {
teacher: 'Kyle',
ask (quetion) {
// this显示的指定到了,调用的对象上, 也就是workspace
console.log(this.teacher, quetion);
}
}

workspace.ask('Why?');

代码复用:让同一个函数在不同的调用条件下得到不同的结果。但是他们引用的都是一个函数。节省了内存, 优化性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function ask(que) {
console.log(this.teacher, que);
}

var workspace1 = {
teacher: 'Kyle',
ask,
}
var workspace2 = {
teacher: 'Suzy',
ask,
}

workspace1.ask('Why?');
workspace2.ask('Why?');

显式绑定: call/apply/bind: 第一个参数就是函数的this.

new keyword

new是第四种调用函数的方式。

问题: new关键字做了哪四件事?

  1. 创建一个新的空对象
  2. 链接这个对象到另一个对象
  3. 和this调用这个函数并且设置一个新的对象
  4. 如果这个函数没有返回一个对象,那么把this返回
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function newOperator(ctor){
    if(typeof ctor !== 'function'){
    throw 'newOperator function the first param must be a function';
    }
    // ES6 new.target 是指向构造函数
    newOperator.target = ctor;
    // 1.创建一个全新的对象,
    // 2.并且执行[[Prototype]]链接
    // 4.通过`new`创建的每个对象将最终被`[[Prototype]]`链接到这个函数的`prototype`对象上。
    var newObj = Object.create(ctor.prototype);
    // ES5 arguments转成数组 当然也可以用ES6 [...arguments], Aarry.from(arguments);
    // 除去ctor构造函数的其余参数
    var argsArr = [].slice.call(arguments, 1);
    // 3.生成的新对象会绑定到函数调用的`this`。
    // 获取到ctor函数返回结果
    var ctorReturnResult = ctor.apply(newObj, argsArr);
    // 小结4 中这些类型中合并起来只有Object和Function两种类型 typeof null 也是'object'所以要不等于null,排除null
    var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
    var isFunction = typeof ctorReturnResult === 'function';
    if(isObject || isFunction){
    return ctorReturnResult;
    }
    // 5.如果函数没有返回对象类型`Object`(包含`Functoin`, `Array`, `Date`, `RegExg`, `Error`),那么`new`表达式中的函数调用会自动返回这个新的对象。
    return newObj;
    }

default binding

非严格模式下, this指向外部this。

严格模式下,this指向undefined.

尽量避免使用默认绑定。

binding precedence : this判定优先级

  1. Is the function called by new?
  2. Is the function called by call or apply?
  3. Is the function called by on a context object?
  4. Default: global object(strict this pointing undefined)

arrow function and lexical this

箭头函数没有自己的this, 此时, this会往外部找, 直到global object.

resolving this in arrow function

函数外部指的是在定义这个函数时的外部, 下面这个例子,定义函数的位置在workshop对象内,所以,this,并不指向workshop.而是workshop的外部, 也就是window.

1
2
3
4
5
6
7
8
9
10
var workshop = {
teacher: 'Kyle',
ask: (que) => {
console.log(this, que);
}
}

workspace.ask('What?');

workspace.ask.call(workshop, 'Still on this');

实际上, new关键字是一个语法糖: 我要调用这个函数, 在一个新的上下文调用。

class keyword

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Workshop {
constructor(teacher) {
this.teacher = teacher;
}
ask (que) {
console.log(this.teacher, que);
}
}

// extends方法, prototype
class AntherWorkshop extends Workshop {
speakUp (msg) {
this.ask(msg);
}

ask1 (msg) {
super.ask(msg); // 调用父级方法
}

ask (msg) {
console.log('children method');
}
}



var deepJs = new Workshop('Kyle');
var reactJs = new Workshop('Suzy');

deepJs.ask('what');
reactJs.ask('what');

fixing in Classes

1
2
3
4
5
6
7
8
9
10
11
12
13
class workshop {
constructor (teacher) {
this.teacher = teacher;
this.ask = que => {
console.log(this.teacher, que);
}
}
}


var deepJs = new workshop('Kyle');

setTimeout(deepJs.ask, 100, 'what?');

8.prototype.md

Posted on 2020-04-12 | In deep-js-foundations-v2-noteBook

Prototypes

Objects are build by ‘constructor calls’(via: new)

A “constructor call” makes an object it is own prototype.

(cs101:
什么是类,对一个事物的抽像描述: 属性和方法.这个东西有啥属性, 能做什么。
类和实例的关系: 实例是类的实现。
类的一些特性: 继承和多态。
)

A “constructor call” makes an object linked to its own prototype.

注意区分link(保存引用)和完全复制的区别.js为了性能, 并没有进行完全复制。

所以, js中的class的继承并不是copy而是link, 链接万物。当然,你需要完全copy也不是不可以.

Prototypal class

1
2
3
4
5
6
7
function Workshop (teacher) {
this.teacher = teacher;
}

Workshop.prototype.ask = (que) => {
console.log(this.teacher, que);
}

Dunder Prototypes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Workshop (teacher) {
this.teacher = teacher;
}

Workshop.prototype.ask = (que) => {
console.log(this.teacher, que);
}

var deepJS = new Workshop('Kyle');

deepJS.constructor === Workshop

deepJS.__proto__ === Workshop.prototype;
Object.getPrototypeOf(deepJS) === Workshop.prototype;

Object.setPrototypeOf

正常的函数有prototype, 箭头函数没有.

shadowing prototype

原型链重写会导致很多问题, 导致指向异常。

prototypal inhertance

原型链继承并不是复制, 而是引用。

js中的继承其实更像行为委托(代理).

class并不是唯一解,但是对于一些框架来说,class也许是他们的选择。原型模式对我们来说或许更加的适用。

OLOO Pattern (Object linked to other objects)

recall class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class workshop {
constructor(teacher) {
this.teacher = teacher;
}

ask(que) {
console.log(this.teacher, que);
}
}

class antherWorkshop extends workshop {
speakUp(msg) {
this.ask(msg);
}
}

OLOO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const workshop = {
setTeacher(teacher) {
this.teacher = teacher;
},
ask(que) {
console.log(this.teacher, que);
}
}

const antherWorkshop = Object.assign(Object.create(workshop), {
speakUp (msg) {
this.ask(msg);
}
})

const jsrecentParts = Object.create(antherWorkshop);
jsrecentParts.setTeacher('Kyle');
jsrecentParts.speakUp('What?');

ES5 polyfill: Object.create

1
2
3
4
5
6
7
if(!Object.create) {
Object.create = function (o) {
function F() {};
F.prototype = o;
return new F();
}
}

delegation: design pattern

其实class只是实现相同结构的一条路。我们通过组合, 可以达到和class相同的效果,并且由于js的只引用不复制的一个语言特性下, 我们使用组合或许更加符合js的语言特性.

class的一个思想趋势是, 区分父子关系然后链接。而组合则是点对点的关系。那么组合的层级还有方式就很多。可以说组合让代码的粒度更细了。

还有个好处是,this的指向在组合的设计模式下会更加清晰。因为调用关系明确。判断this指向的四个规则第一条就是, 谁调用, 指向谁。

css.md

Posted on 2020-04-12 | In fcc

相应式布局设计
vw:如 10vw的意思是视窗宽度的 10%。
vh:如 3vh的意思是视窗高度的 3%。
vmin:如 70vmin的意思是视窗中较小尺寸的 70% (高度 VS 宽度)。
vmax:如 100vmax的意思是视窗中较大尺寸的 100% (高度 VS 宽度)。

4.scopeAndFunctionExpress.md

Posted on 2020-04-12 | In deep-js-foundations-v2-noteBook

Function Expressions

来看个例子:

1
2
3
4
5
6
7
8
9
10
// 函数定义式
function teacher () {}
// 函数表达式
var myTeacher = function antherTeacher() {
console.log(antherTeacher) // 可以访问到, 因为函数定义也属于本级定义域
}

console.log(teacher) // 函数本身
console.log(myTeacher) // function antherTeacher() {....}
console.log(autherTeacher) // Reference Error

这里要注意两个东西: 函数定义, 函数定义表达式

  1. 函数定义会提升,而函数定义表达式不会提升。
  2. 两者在内存中的不一致, 对于函数定义式, 在编译阶段的收集变量的时候就获得了这个函数在内存中的地址, 而对于函数定义表达式来说, var myTeacher属于LHS, 函数定义属于RHS, 在第二阶段 ,也就是执行阶段再执行的函数定义, 所以, 上面那段代码中,最后一个console会爆出引用错误,因为在编译过程中,js编译器在内存中就找不到antherTeacher了。
1
2
3
4
5
6
7
8
9
// 匿名函数表达式
var a = function() {

}

// 命名函数表达式
var a = function b () {

}

匿名函数更加常见, 但是大胡子建议我们尽可能的使用命名函数表达式.(命名表达式的作用在于, 如果爆出error我们可以获得完整的调用栈, 定位到错误的地方.

named function expression

why we need to alway uses named function expression?

  1. Reliable function self-reference: 命名函数提供了一个可靠的自身引用地址, 这对于递归函数来说很重要.(也就是我们第一章的示例中, 函数内部可以通过命名函数的函数名访问到函数本身, 想一下递归), 任何时候,你要访问函数本身,你都可以通过函数名访问到, 而匿名函数就无法访问到.函数也就更内聚。
  2. More debuggable stack traces: 触发错误后, 错误的调用栈会包含命名函数的信息,而不会有匿名函数的信息.
  3. More self-documenting code: 除去1, 2点不说, 多使用命名函数,对于你的代码来说,更具可读性. 我看函数名就知道咋回事了.OK, 如果你觉得麻烦,那么命名完全可以和你的变量一样,但是前提是你的变量也必须具有可读性。每个函数应该都是有意义的,如果你的函数没有意义,你可能要考虑一下你是否需要这个函数, 你不够理解你的代码,是否要把这个函数在切分成更小的模块?

Arrow function

箭头函数本质上是匿名函数,匿名函数就会有上面说的问题。 所以大胡子并不推荐我们无脑使用箭头函数.

function types hierarchy

(named)function declaration >
named function expression >
anonymous function expression

js.md

Posted on 2020-04-12 | In fcc

数组扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 我有个问题, 扁平化数组我这样写 没办法控制住depth
// 求一个优雅的方案, 解决扁平化数组时depth层级API问题
const flat = (arr, depth = 1) => {
while(depth > 0) {
arr = arr.reduce((sum, cur) => {
if(isType(cur) === 'Array') {
// 主要是这一段, 如果不使用递归, 那么就是根据depth控制, 扁平化的深度
sum = sum.concat(flat(cur))
} else {
sum.push(cur)
}
return sum
}, [])
depth--
}
return arr
}


const isType = (value) => {
return Object.prototype.toString.call(value).match(/(?<= )\w+/)[0]
// String Number Null Undefined Object Date RegExp Symbol Boolean Function Array
}

flat([1, 2, 3, [1]], 1)

数组根据Number分片

1
2
3
4
5
6
7
8
9
10
11
function chunkArrayInGroups(arr, size) {
// Break it up.
return arr.reduce((sum, cur, index) => {
if(index % size === 0) {
sum.push([cur])
} else {
sum[sum.length - 1].push(cur)
}
return sum
}, [])
}

constructor 属性可以被重写,作为判定父级的方法并不可靠.

isPrototypeOf: 判断原型链来自哪里?

注意,当我们使用原型的继承时, 我们要注意, 往prototype上面不可以使用字面量的方式去增加属性,但是你可以自己写一个方法, 以字面量作为参数传入.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Animal() { }
Animal.prototype.eat = function() { console.log("nom nom nom"); };

function Dog() { }

// 请把你的代码写在这条注释以下
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
Dog.prototype.bark = () => {
console.log('Woof!')
}
// 请把你的代码写在这条注释以下

let beagle = new Dog();

beagle.eat(); // 应该输出 "nom nom nom"
beagle.bark(); // 应该输出 "Woof!"

react基础.md

Posted on 2020-04-12 | In fcc
  1. 插值表达式 {}

  2. 在插值表达式中,可以使用js与jsx语法混用.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // write your code here
    const JSX = <div>
    <h1>{'h1'}</h1>
    <p>{'p'}</p>
    <ul>{ [1, 2, 3].map(item => {
    return <li>{item}</li>
    })}
    </ul>
    </div>;
  3. jsx注释 {/* */}

  4. 渲染 HTML 元素为 DOM 树
    使用reactRender(jsx组件, dom节点)

1
ReactDOM.render(JSX, document.getElementById('challenge-node'))
  1. react定义Html中的class属性, 不可以使用class, 只能使用className(class在js中为关键字)

  2. jsx中, 都存在自闭合标签, 就是不需要关闭标签 类似

    1
    <br />
  3. 好了, 在jsx语法中,也只能有一个父级标签

  4. 无状态组件

    1
    2
    3
    4
    5
    const mycomponent = () => {
    return (
    <div>some</div>
    )
    }
  5. 基于class语法创建一个 React 组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <h1>Hi</h1>
    );
    // change code above this line
    }
    };
  6. 用组合的方式创建一个 React 组件: z(x) = f(g(x))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    const child = () => {
    return (
    <div>
    { 'Hello child.' }
    </div>
    )
    }

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <div>
    <child></child>
    </div>
    );
    // change code above this line
    }
    };
  7. React 渲染嵌套组件
    没啥,也就组件嵌套组件.

  8. 渲染 class 组件为 Dom 树

1
ReactDOM.render(<componentName>, document.getElementById('challenge-node'))
  1. props传递

    1
    2
    3
    <App>
    <Welcome user={如果是变量的化} />
    </App>
  2. 默认的props-defaultProps

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const ShoppingCart = (props) => {
    return (
    <div>
    <h1>Shopping Cart Component{props.items}</h1>
    </div>
    )
    };
    // change code below this line
    ShoppingCart.defaultProps = {
    items: 0
    }
  3. React:使用 PropTypes 来定义你期望的 Props // 限制props的类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 使用 PropTypes
    const Items = (props) => {
    return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
    };

    // change code below this line
    Items.propTypes = {
    quantity: PropTypes.number.isRequired
    }
    // change code above this line

    Items.defaultProps = {
    quantity: 0
    };
  4. 访问props
    状态组件使用this关键字: this.props
    无状态组件使用入参props

  5. 创建带自身状态的组件: state

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
// initialize state here
this.state = {
// describe your state here
name: 'fuck'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
</div>
);
}
};
  1. 在render函数的return语句前可以放任意的js, 那么意味着我们可以在渲染之前, 对state进行处理.

  2. 原则: 改变组件状态必须要使用 this.setState

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'Initial State'
    };
    this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
    // change code below this line
    this.setState({
    name: 'React Rocks!'
    });
    // change code above this line
    }
    render() {
    return (
    <div>
    <button onClick={this.handleClick}>Click Me</button>
    <h1>{this.state.name}</h1>
    </div>
    );
    }
    };
  3. 在react组件里, 组件里的方法是访问不到组件的this的, 这个时候就要我们手动去修复这个问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    itemCount: 0
    };
    // change code below this line
    this.addItem = this.addItem.bind(this)
    // change code above this line
    }
    addItem() {
    this.setState({
    itemCount: this.state.itemCount + 1
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    <button onClick={this.addItem}>Click Me</button>
    { /* change code above this line */ }
    <h1>Current Item Count: {this.state.itemCount}</h1>
    </div>
    );
    }
    };
  4. input框数据双向绑定(万年问题)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class ControlledInput extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    input: 'xxx'
    };
    // change code below this line
    this.assignText = this.assignText.bind(this)
    // change code above this line
    }
    // change code below this line
    assignText(e) {
    this.setState({
    input: e.target.value
    })
    }
    // change code above this line
    render() {
    return (
    <div>
    { /* change code below this line */}
    <input type='text' value={this.state.input} onChange={this.assignText}/>
    { /* change code above this line */}
    <h4>Controlled Input:</h4>
    <p>{this.state.input}</p>
    </div>
    );
    }
    };
  5. 将 State 作为 Props 传递给子组件—-父子数据传递
    遵循两个原则:

  • 单向数据流
  • 最小状态组件原则
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 父子数据传递
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'CamperBot'
    }
    }
    render() {
    return (
    <div>
    <Navbar name={this.state.name} />
    </div>
    );
    }
    };

    class Navbar extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h1>Hello, my name is: {this.props.name} </h1>
    </div>
    );
    }
    };
  1. 父级向子集传递的不只是state, 也可以是function
    传递function的原因是, 给子组件一个修改state的机会.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    inputValue: ''
    }
    this.handleChange = this.handleChange.bind(this);
    }
    handleChange(event) {
    this.setState({
    inputValue: event.target.value
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    {this.state.inputValue}
    <GetInput input={this.state.inputValue} handleChange={this.handleChange}/>

    <RenderInput input={this.state.inputValue} />

    { /* change code above this line */ }
    </div>
    );
    }
    };

    class GetInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Get Input:</h3>
    <input
    value={this.props.input}
    onChange={this.props.handleChange}/>
    </div>
    );
    }
    };

    class RenderInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Input Render:</h3>
    <p>{this.props.input}</p>
    </div>
    );
    }
    };
  2. 使用生命周期方法Overview

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    componentWillMount()
    // 即将挂载
    componentDidMount()
    // 挂载后
    componentWillReceiveProps()
    // 将要接收props
    shouldComponentUpdate()
    // 组件更新
    componentWillUpdate()
    // 组件即将更新
    componentDidUpdate()
    // 组件更新后
    componentWillUnmount()
    // 组件卸载
  3. componentDidMount — 组件装载到 DOM 后会调用
    这个生命周期:

  • 一般是放数据请求.请求后把数据放入模板, 再进行渲染.类似我们vue会把请求初始化放到created()
  • 挂载浏览器事件(特指全局的哦, 比如按回车然后, 执行某些搜索, 我们在componentDidMount周期里挂载, 在componentWillUnmount里卸载这个事件)
  1. componentWillReceiveProps — 组件接收到props或者props更新就会触发: 入参默认为该次传入的props

  2. componentDidUpdate — 组件再次重新渲染会触发: 入参默认为该次传入的props

  3. componentWillMount/componentDidMount — 首次渲染, 首次卸载会触发

  4. shouldComponentUpdate — 该生命周期控制组件是否需要更新, 入参默认为nextProps, nextState, 出参必须要一个boolean值, 告诉react是否需要更新该组件,因为, react的行为是, 如果传入了props那么无论怎样都会去更新组件, 触发渲染.(这个生命周期是作为一个优化提出的)

  5. react中的内联样式
    在react使用样式的方式有两种

  • 正常导入
  • 使用内联样式
    1
    <div style={{color: "yellow", fontSize: 16}}>Mellow Yellow</div>
    要点: 1. style中只接受对象 2. 不识别连字符, 要使用驼峰命名
  1. React:在 React Render 方法中使用 JavaScript
    在render函数的return语句之前,我们可以使用任意的js
  1. 使用 If/Else 条件进行渲染
    记住, 这种判断一般都抽离出来成为一个逻辑,不要再jsx中写入太多逻辑.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    let content
    if(this.state.toggleDisplay) {
    content = <h1>Hello</h1>
    } else {
    content = ''
    }
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {content}
    </div>
    );
    }
    };
  2. 使用 && 获得更简洁的条件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {this.state.display && <h1>markup</h1>}
    </div>
    );
    }
    };
  3. 使用三元表达式进行条件渲染

    1
    2
    3
    4
    5
    const buttonOne = <button onClick={this.submit}>Submit</button>;
    const buttonTwo = <button>You May Enter</button>;
    const buttonThree = <button>You Shall Not Pass</button>;

    this.state.input === '' ? buttonOne : (this.state.userAge >= 18 ? buttonTwo : buttonThree)
  4. 服务端渲染(待续)

完结撒花

正则.md

Posted on 2020-04-12 | In fcc

正则:

  1. /a|b|c|d/ 匹配a或者b, c, d

  2. 用通配符.匹配任何内容

  3. 匹配a, b 或 c

  4. 匹配集合 [0-9] [a-z0-9]

  5. 匹配差集 [^0-9] // 注意, 这个^ 在字符集里面是否定的意思, 而在字符集外面, 是开始的意思

  6. 匹配1个或者多个a : /a+/

  7. 匹配零个或者多个ao : /ao*/ 会匹配出 a

  8. 惰性匹配: 匹配长度为最小字符串 /<.*?>/ (注意了, js中的正则本身是贪婪匹配)

  9. 前置断言 (<=[xxx]?)

  10. 以xxx开始的字符串: /^xxx/

  11. 以xxx结尾的字符串: /xxx$/

  12. 元字符:
    \w // 所有的数字和字母
    \W // w的差集
    \d // 所有数字
    \D // 所有非数字
    \s // 此匹配模式不仅匹配空格,还匹配回车符、制表符、换页符和换行符,你可以将其视为与[\r\t\f\n\v]类似。所有非数字字母
    \S // 匹配所有非空白字符
    /a{3,5}h/ // 指定匹配模式的上界下界
    /a{3,}h/ // 指定匹配模式的下界
    /a{3}h/ // 指定数量匹配
    /colou?r/ // 模糊查询可选项: u就是可选项, 可以有, 也可以没有, 但是不可以是其他字符

  13. 前置断言 (?=…) 以…开头
    正向先行断言会查看并确保搜索匹配模式中的元素存在,但实际上并不匹配。

  14. 后置断言 (?!…) 不以…开头
    负向先行断言会查看并确保搜索匹配模式中的元素不存在。

  15. 使用捕获组重用模式

    1
    2
    3
    let repeatStr = "regex regex";
    let repeatRegex = /(\w+)\s\1/;
    repeatStr.match(repeatRegex); // Returns ["regex regex", "regex"]
  16. 使用捕获组搜索和替换

    1
    "Code Camp".replace(/(\w+)\s(\w+)/, '$1'); // 此时, 使用括号括起来的元素就是一个组, 这个组会命名为$1 - $n在替换的时候可以使用到
  17. 用正则表达式写一个trim

    1
    2
    3
    let hello = "   Hello, World!  ";
    let wsRegex = /(\s+)(\w+.+\w+\S)(\s+)/;
    let result = hello.replace(wsRegex, '$2');
  18. 注意 reg.test()中的reg正则对象存在一个值, 这个值表示我使用test()方法匹配的起点index, 如果稍不注意,就很容易翻车

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (function(){
    const reg = /o/g;
    function isHasO(str){
    // reg.lastIndex = 0; 这样就可以避免这种情况
    return reg.test(str)
    }
    var str = 'google';
    console.log(isHasO(str))
    console.log(isHasO(str))
    console.log(isHasO(str))
    }())

futureEnglish.md

Posted on 2020-04-12 | In futureLearnEnglish

week3: About Hobbies

vocabulary:
Coughing
Slapping
Carrying

Singing
Sailing
Sneezing

essay

Presentation
Prayer

Listen pratice

Mo is coughing paracetamol.

Grammar

I like + v-ing(动词ING形式) + Obj(主语)

positive
I like playing football.

Nagative
I don’t like play football.

Expressing strong Like and dislike

like -> love

I like reading./ I love reading

don’t like -> hate

I don’t like study./ I love study.

Asking question about likes and dislikes

Quetion style 1

Do you like + v-ing?

positive

Yes. I do/I love + v-ing

nagative

No, I don’t./I hate + v-ing.

Quetion style 2

What do you like doing?

answer

I like/love + v-ing

Asking more information.

Quetion style 1

What kind of + non + do you like?

answer

I like + adj + non

explames

What kind of books do you like?

I like tech book.

futureEnglish-week4.md

Posted on 2020-04-12 | In futureLearnEnglish

week3: About Hobbies

vocabulary:
character
rugby
cricket

A
reading book
not like study
playing football
like cook
dancing
single
music- rock

B 
cooking
music - rock 
dancing

Grammar

The Present Continuous Tense

主语 + Be动词 + 动词-ing

positive
I am playing football.

Nagative
I am not playing football.

Asking question about present continuous tense

Quetion style 1

Be动词 + 主语 + 动词-ing

positive

Are you reading?

<1234…7>

Hawei

Fullstack Engineer

61 posts
16 categories
3 tags
RSS
© 2022 Hawei
Powered by Hexo
|
Theme — NexT.Muse v5.1.4