1、类的定义
1、ES5语法类的定义
<body>
<script>
// ES5中如何定义类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.running= function() {
console.log(this.name, this.age, "running");
}
var p = new Person("why", 18);
console.log(p.name, p.age);
p.running();
</script>
</body>
2、ES6语法类的定义
<body>
<script>
class Person {
// 通过构造方法传递参数
constructor(name, age) {
this.name = name;
this.age = age;
}
// 定义方法,最终绑定到原型上
running() {
console.log(this.name, this.age, "running");
}
}
const p = new Person("why", 18);
console.log(p.name, p.age);
p.running();
// 下面关于this绑定的问题
// 方法1--通过call函数绑定
console.log("--func--")
const func = p.running;
// func()
var obj = {
name: "why",
age: 30
}
// 此时this绑定的是 obj
func.call(obj);
// 方法2--通过对call函数重新赋值
console.log("--func2--")
let func2 = p.running;
func2 = func2.bind(obj);
func2();
</script>
</body>
3、map高阶函数
<body>
<script>
const names = ["abc", "cba", "acb"];
// names.map(回调函数, 给前面的回调函数绑定this);
//
// names.map((item, index, arr) => {})
// 回调函数有三个参数
// 参数1、执行时的对应元素
// 参数2、对应的下标值
// 参数3、完整的数组对象 arr
</script>
</body>
2、JSX语法
JSX是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法;
它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;
它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
const element = <h2>Hello World</h2>
1、JSX书写规范:
1)、JSX的顶层只能有一个根元素
2)、jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写
3)JSX中的标签可以是单标签,也可以是双标签,如果是单标签,必须以/>结尾;
2、JSX嵌入变量
1)、当变量是Number、String、Array类型时,可以直接显示
2)、当变量是null、undefined、Boolean类型时,内容为空;
如果希望可以显示null、undefined、Boolean,那么需要转成字符串;
<body>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = {
name: "why", // String
age: 18, // Number
names: ["a", "b"], // Array
title: null,
nickname: undefined,
teacher: false,
man: true
}
}
render() {
// this.state对象解构出 name,age两个元素
const {name, age} = this.state;
return(
<div>
<h2>{tname}</h2>
<h2>{age}</h2>
<h2>{this.state.names}</h2>
{/* 转换为String类型,否则不显示*/}
<h2>{this.state.title + ""}</h2>
{/* 转换为String类型,否则不显示*/}
<h2>{this.state.nickname + ""}</h2>
{/* 转换为String类型,否则不显示*/}
<h2>{this.state.teacher.toString()}</h2>
{/* 为true显示"男士",否则什么都不显示*/}
<h2>{this.state.man && "男士"}</h2>
</div>
)
}
}
ReactDOM.render(<App />, document.body);
</script>
</body>
3)、对象类型不能作为子元素
3、在xml元素中标签的class属性和label标签的for属性需要用className和htmlFor代替
<body>
</script>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = {
title: "我是标题",
imgUrl: "http://p4.music.126.net/W-DSR98OUBA0ZWm6z8T0VQ==/109951166000855078.jpg",
link: "https://www.baidu.com",
active: false
}
}
getSizeImage(imgUrl, size) {
return imgUrl + `?param=${size}x${size}`;
}
render() {
const {link, active} = this.state;
return(
<div>
<h2 title="标题">我是标题</h2>
<img src={this.getSizeImage(this.state.imgUrl, 100)} alt=""/>
<a href={link} target={"_blank"}>www.baidu.com</a>
<div className={"div class " + active ? "active" : ""}>我是div元素</div>
<label htmlFor=""></label>
<div style={{color: "red", fontSize: "50px"}}>我是div style</div>
</div>
)
}
}
ReactDOM.render(<App />, document.body);
</script>
</body>
4、事件绑定以及对this的处理
事件绑定有三种方式
<body>
</script>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = {
message: "你好"
}
/*2、方案二:提前bind绑定this(显示绑定)*/
this.btnClick = this.btnClick.bind(this);
}
render() {
return(
<div>
<button onClick={this.btnClick}>按钮</button>
{/*1、方案一:bind绑定this(显示绑定)*/}
<button onClick={this.btnClick2.bind(this)}>按钮2</button>
{/*3、方案三:定义函数时,使用箭头函数 */}
<button onClick={this.increment}>+1</button>
{/*4、方案四:直接使用箭头函数,对this进行隐式绑定,往上一层作用域中找this */}
<button onClick={()=> { this.decrement() }}>-1</button>
</div>
)
}
btnClick () { console.log(this.state.message)}
btnClick2 () { console.log(this.state.message)}
// 箭头函数永远不绑定this
// 变量当前作用找不到this,会从上层作用域在找this
// ES6中给对象添加属性的语法: class field
increment = () => { }// 给increament属性赋值一个箭头函数
decrement () {}
name="sj"; // 给name属性赋值一个sj
}
ReactDOM.render(<App />, document.body);
</script>
</body>
5、逻辑&& 条件判断
<body>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = { isLogin: false }
}
render() {
const {isLogin} = this.state;
return(
<div>
<h2 style={{display: isLogin? "block":"none"}}>你好啊,我是登录</h2>
{/* 三元运算符 */}
<button onClick={e=> {
this.btnClick()
}}>{isLogin?"退出":"登录"}</button>
<hr />
{/* 逻辑与&& */}
<h2> {isLogin && "欢迎登录成功~"}</h2>
</div>
)
}
btnClick () {
this.setState({ isLogin: !this.state.isLogin })
}
}
ReactDOM.render(<App />, document.body);
</script>
</body>
6、模板字符串
// 1、模板字符串的基本使用
const name = "me";
const age = 18;
const message = `my name is ${name}`;
// 2、标签模板字符串:可以通过模板字符串的方式对一个函数调用
function test(...args) {
console.log(args);
}
1)、test
`aa
`
展示效果
[['aa', raw: Array(1)]]
2)、test
`my name is ${name} age is ${age}
`
展示效果
[['my name is ', ' age is ', '', raw: Array(3)], 'me', 18]
总结:函数调用模板字符串,直接将字符串分解成一个二维数组
7、纯函数
定义:
此函数在相同的输入值时,需产生相同的输出。函数的输出和输入值以外的其他隐藏信息或状态无关,也和由I/O设备产生的 外部输出无关。
该函数不能有语义上可观察的函数副作用,诸如“触发事件”,使输出设备输出,或更改输出值以外物件的内容等。
概括:
确定的输入,一定会产生确定的输出;
函数在执行过程中,不能产生副作用;
React中就要求我们无论是函数还是class声明一个组件,这个组件都必须像纯函数一样,保护它们的props不被修改:
<body>
<script>
// 纯函数
function sum(num1 , num2) {
return num1 + num2
}
// 不是纯函数,输出不确定
let foo = 10;
function add (num) {
return foo + num;
}
// 纯函数
const bra = 10;
function add (num) {
return bra + num;
}
// printInfo不是纯函数
function printInfo(info) {
info.name = "why";
console.log(info.name, info.age);
}
const obj = {
name: "why",
age: 18
};
printInfo(info);
console.log(obj);
</script>
</body>
8、generator使用
// 生成器函数定义
function *foo() {
console.log("1");
yield "Hello";
console.log("2");
yield "World";
console.log("3");
yield "coderwhy";
console.log("4");
}
// 迭代器 iterator
const result = foo()
console.log(result);
// 调用一次next就会消耗一次迭代器
const res1 = result.next()
console.log(res1); // 111 {value: "Hello", done: false}
const res2 = result.next()
console.log(res2);
const res3 = result.next()
console.log(res3);
const res4 = result.next()
console.log(res4); // 444 {value: undefined, done: false}
// 定义一个生成器函数 依次可以生成10=10数字
function *generateNumber() {
for (var i = 1; i <= 10; i ++) {
yield i;
}
}
const numIn1 = generateNumber();
console.log(numIn1.next().value);
console.log(numIn1.next().value);
console.log(numIn1.next().value);
// generator 和promise一起使用
function * bar() {
const result = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve("goddd")
}, 3000);
});
console.log(result);
}
const it = bar();
it.next().value.then(res => {
console.log("分割线")
console.log(res)
it.next(res) // 将上一次的结果res赋值给it.next()
})
网友评论