React学习笔记--JS部分

一,JS部分
1,Array(9).fill(null) --定义一个为9的数组,默认填充null
2,stringObject.slice(start,end)

 arrayObject.slice(start,end),与string对象的用法相似,返回一个新的数组。
  • start :要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。
  • var str=“Hello happy world!”
    document.write(str.slice(6))
    happy world!
  • var str=“Hello happy world!”
    document.write(str.slice(6,11))
    –happy

推荐资源
MDN (Mozilla Developer Network)
你所不知道的JS (书)
ES6 新特性和例子
WesBos 的博客 (ES6)
Reddit (JavaScript)
用 Google 来查找特定的博客和资源
StackOverflow

3,Object.assign()
var nObj = Object.assign({},obj,obj1);//花括号叫目标对象,后面的obj、obj1是源对象。对象合并是指:将源对象里面的属性添加到目标对象中去,若两者的属性名有冲突,后面的将会覆盖前面的

let obj = {name: '二月', age: {c: 12}}
let age = {c: 88}
let o2 = Object.assign({}, obj, {age})
o2.age.c = 66
console.log(obj, o2)

用ES6的扩展运算符来替换Object.assign

let obj = {name: '二月', age: {c: 12}}
let o1 = {...obj, age: {c: 88}}
o1.age.c = 99
console.log(obj, o1)

Object.assign(target, …sources),第一个参数target决定了你的对象被拷贝到哪个目标对象上面,如果你不想对原始对象产生影响,就定义一个空对象{}

4,push(),concat()方法的区别
var array=[1,2,3,4,5];

console.log(array);   //[1, 2, 3, 4, 5]

array.push(6,7);      //两个参数
console.log(array);   //[1, 2, 3, 4, 5, 6, 7]

array.push([6,7]);    //参数为数组
console.log(array);   //[1, 2, 3, 4, 5,  Array(2)]

var array=[1,2,3,4,5];

console.log(array);   //[1, 2, 3, 4, 5]

var array2=array.concat(6,7);    //两个参数
console.log(array);    //[1, 2, 3, 4, 5]
console.log(array2);   //[1, 2, 3, 4, 5, 6,7]

var array2=array.concat([6,7]);    //参数为数组
console.log(array);    //[1, 2, 3, 4, 5]
console.log(array2);   //[1, 2, 3, 4, 5, 6, 7]

push()是在原数组的基础上修改的,执行push()方法后原数组的值也会变;concat()是先把原数组复制到一个新的数组,然后在新数组上进行操作,所以不会改变原数组的值。
如果参数不是数组,不管参数个数有多少个,push()和concat()都会直接把参数添加到数组后;如果参数是一个数组,push()就会直接把数组添加到原数组后,而concat()会把数组里的值取出来添加到原数组后

5,map
原数组被“映射”成对应新数组。

var data = [1, 2, 3, 4];

var arrayOfSquares = data.map(function (item) {
  return item * item;
});

alert(arrayOfSquares); // 1, 4, 9, 16

可以利用map方法方便获得对象数组中的特定属性值们

var users = [
  {name: "张含韵", "email": "zhang@email.com"},
  {name: "江一燕",   "email": "jiang@email.com"},
  {name: "李小璐",  "email": "li@email.com"}
];

var emails = users.map(function (user) { return user.email; });

console.log(emails.join(", ")); // zhang@email.com, jiang@email.com, li@email.com

6,filter()
filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。

var arr = ['1','2',undefined, '3.jpg',undefined]
var newArr = arr.filter(item => item)
console.log(newArr)

var arr = ['1','2',null, '3.jpg',null]
var newArr = arr.filter(item => item)
console.log(newArr)

var arr = ['1','2','', '3.jpg','']
var newArr = arr.filter(item => item)
console.log(newArr)

var arr = ['10','12','23','44','42']
var newArr = arr.filter(item => item.indexOf('2')<0) 
console.log(newArr)
数组去重
var arr = [1, 2, 2, 3, 4, 5, 5, 6, 7, 7,8,8,0,8,6,3,4,56,2];
var arr2 = arr.filter((x, index,self)=>self.indexOf(x)===index)  
console.log(arr2); //[1, 2, 3, 4, 5, 6, 7, 8, 0, 56]

map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身

7,reduce()
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
注意: reduce() 对于空数组是不会执行回调函数的。
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
initialValue 可选。传递给函数的初始值
function(total,currentValue, index,arr) 必需。用于执行每个数组元素的函数。
total 必需。初始值, 或者计算结束后的返回值。
currentValue 必需。当前元素
currentIndex 可选。当前元素的索引
arr 可选。当前元素所属的数组对象。

var items = [10, 120, 1000];
var reducer = function add(sumSoFar, item) { return sumSoFar + item; };
var total = items.reduce(reducer, 0);

console.log(total); // 1130

reduce函数的返回结果类型和传入的初始值相同,上个实例中初始值为number类型,同理,初始值也可为object类型。

var items = [10, 120, 1000];
var reducer = function add(sumSoFar, item) {
  sumSoFar.sum = sumSoFar.sum + item;
  return sumSoFar;
};
var total = items.reduce(reducer, {sum: 0});
console.log(total); // {sum:1130}

使用reduce方法可以完成多维度的数据叠加。

var reducers = {  
totalInEuros : function(state, item) {
    return state.euros += item.price * 0.897424392;
  },
  totalInYen : function(state, item) {
    return state.yens += item.price * 113.852;
  }
};

var manageReducers = function(reducers) {
  return function(state, item) {
    return Object.keys(reducers).reduce(
      function(nextState, key) {
        reducers[key](state, item);
        return state;
      },
      {}
    );
  }
};

var bigTotalPriceReducer = manageReducers(reducers);
var initialState = {euros:0, yens: 0};
var items = [{price: 10}, {price: 120}, {price: 1000}];
var totals = items.reduce(bigTotalPriceReducer, initialState);
console.log(totals);

再看一个例子,如何知道一串字符串中每个字母出现的次数?

var arrString = 'abcdaabc';
const aa=arrString.split('').reduce(function(res, cur) {
    res[cur] ? res[cur] ++ : res[cur] = 1
    return res;
}, {})
console.log(aa) //{a: 3, b: 2, c: 2, d: 1}

由于可以通过第二参数设置叠加结果的类型初始值,因此这个时候reduce就不再仅仅只是做一个加法了,我们可以灵活的运用它来进行各种各样的类型转换,比如将数组按照一定规则转换为对象,也可以将一种形式的数组转换为另一种形式的数组,

[1, 2].reduce(function(res, cur) { 
    res.push(cur + 1); 
    return res; 
}, [])

koa的源码中,有一个only模块,整个模块就一个简单的返回reduce方法操作的对象:

var only = function(obj, keys){
  obj = obj || {};
  if ('string' == typeof keys) keys = keys.split(/ +/);
  return keys.reduce(function(ret, key){
    if (null == obj[key]) return ret;
    ret[key] = obj[key];
    return ret;
  }, {});
};

通过对reduce概念的理解,这个模块主要是想新建并返回一个obj对象中存在的keys的object对象。

var a = {
    env : 'development',
    proxy : false,
    subdomainOffset : 2
}
only(a,['env','proxy'])   // {env:'development',proxy : false}

map、filter、reduce

const students = [
  { name: "Nick", grade: 10 },
  { name: "John", grade: 15 },
  { name: "Julia", grade: 19 },
  { name: "Nathalie", grade: 9 },
];
 
const aboveTenSum = students
  .map(student => student.grade) // 我们将学生数组映射到他们成绩的数组中
  .filter(grade => grade >= 10) // 我们过滤成绩数组以保持10分以上的元素
  .reduce((prev, next) => prev + next, 0); // 我们将合计所有10分以上的成绩
 
console.log(aboveTenSum) // 44 

Understanding map / filter / reduce in JS

8,在 JavaScript 中,有 3 个关键字可用于声明一个变量, var ,let 和 const

function myFunction() {
  var myVar = "Nick";
  if (true) {
    var myVar = "John";
    console.log(myVar); // "John"
    // 实际上,myVar是函数作用域,我们只是将之前 myVar 的值 "Nick" 抹去,重新声明为 "John"
  }
  console.log(myVar); // "John" - 看看 if 语句块中的指令是如何影响这个值的 
}
console.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问

在执行过程中,var声明的变量被移动到范围的顶部

console.log(myVar) // undefined -- 不会报错
var myVar = 2;

在执行时,被解析为:

JavaScript 代码:
var myVar;
console.log(myVar) // undefined -- 不会报错

var 和 let 大致相同,但是用 let 声明的变量时有以下几个特性:
块级作用域( block scoped )
在被分配之前, 无法 访问使用
在同一个作用域之下,不能重新声明

function myFunction() {
  let myVar = "Nick";
  if (true) {
    let myVar = "John";
    console.log(myVar); // "John"
    // 实际上 myVar 在块级作用域中,(在 if 语句块中)我们只是创建了一个新变量 myVar。
    // 此变量在 if 语句块之外不可访问,
    // 完全独立于创建的第一个 myVar 变量!
  }
  console.log(myVar); // "Nick", 可以看到 if 语句块中的指令不会影响这个值
}
console.log(myVar); // 抛出错误 ReferenceError,myVar 无法在函数外部被访问。

let 和 const 变量声明时也存在提升,但并不代表它们的赋值也会被提升。但由于它被设计成了赋值之前无法使用,

JavaScript 中的 Hoisting (变量提升和函数声明提升)
暂存死区(Temporal dead zone)
变量提升

扩展阅读
How let and const are scoped in JavaScript – WesBos
Temporal Dead Zone (TDZ) Demystified

9,箭头函数
在一个箭头函数中,this 等同于封闭执行上下文的 this 值。这意味着,一个箭头函数并不会创造一个新的 this,而是从它的外围作用域中抓取的。

Arrow functions introduction – WesBos
JavaScript arrow function – MDN

Default parameters – MDN

10,解构对象和数组

const person = {
  firstName: "Nick",
  lastName: "Anderson",
  age: 35,
  sex: "M"
}
const { firstName: first, age, city = "Paris" } = person; // 就是这么简单!
 
console.log(age) // 35 -- 一个新变量 age 被创建,并且其值等同于 person.age
console.log(first) // "Nick" -- 一个新变量 first 被创建,并且其值等同于 person.firstName A new variable first is created and is equal to person.firstName
console.log(firstName) // Undefined -- person.firstName 虽然存在,但是新变量名为 first
console.log(city) // "Paris" -- 一个新变量 city 被创建,并且因为 person.city 为 undefined(未定义) ,所以 city 将等同于默认值也就是 "Paris"。

注意: 在 const { age } = person; 中, const 关键字后的括号不是用于声明对象或代码块,而是 解构(structuring) 语法。

解构(structuring) 经常被用来解构函数中的对象参数。

不使用解构:

function joinFirstLastName(person) {
  const firstName = person.firstName;
  const lastName = person.lastName;
  return firstName + '-' + lastName;
}
 
joinFirstLastName(person); // "Nick-Anderson"

在解构对象参数 person 这个参数时,我们可以得到一个更简洁的函数:

function joinFirstLastName({ firstName, lastName }) { // 通过解构 person 参数,我们分别创建了 firstName 和 lastName 这两个变数
  return firstName + '-' + lastName;
}
 
joinFirstLastName(person); // "Nick-Anderson

箭头函数中使用解构

const joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;
 
joinFirstLastName(person); // "Nick-Anderson"

Array

const myArray = ["a", "b", "c"];
不使用解构:
const x = myArray[0];
const y = myArray[1];

使用解构:
JavaScript 代码:
const [x, y] = myArray; // 就是这么简单!
 
console.log(x) // "a"
console.log(y) // "b"

Destructuring Objects – WesBos
ExploringJS – Destructuring

函数式编程
JavaScript 中的 Currying(柯里化) 和 Partial Application(偏函数应用)
一步一步教你 JavaScript 函数式编程(第一部分)
一步一步教你 JavaScript 函数式编程(第二部分)
一步一步教你 JavaScript 函数式编程(第三部分)
JavaScript 函数式编程术语大全

11,展开操作符 “…”

 const arr1 = ["a", "b", "c"];
 const arr2 = [...arr1, "d", "e", "f"]; // ["a", "b", "c", "d", "e", "f"]

function createStudent(firstName, lastName, ...grades) {
  // firstName = "Nick"
  // lastName = "Anderson"
  // [10, 12, 6] -- "..." 将传递所有剩余参数,并创建一个包含它们的 "grades" 数组变量
  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // 根据 grade 计算平均成绩
 
  return {
    firstName: firstName,
    lastName: lastName,
    grades: grades,
    avgGrade: avgGrade
  }
}
 
const student = createStudent("Nick", "Anderson", 10, 12, 6);
console.log(student);

在这个示例中, createStudent 函数并没有去检查 grades.length 是否存在又或者它等于 0 的情况

const myObj = { x: 1, y: 2, a: 3, b: 4 };
const { x, y, ...z } = myObj; // 这里是对象被解构
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }
 
// z是对象解构后的剩余部分:myObj 对象除去 x 和 y 属性后剩余部分被解构
const n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }

TC39 – Object rest/spread
Spread operator introduction – WesBos
JavaScript & the spread operator
6 Great uses of the spread operator

Template literals
es6之template literals
一等公民(first-class citizens)

12,对象属性简写

const x = 10;
const y = 20;
 
const myObj = {
  x: x, // 将 x 分配给 myObj.x
  y: y // 将 y 变量给 myObj.y
};
 
console.log(myObj.x) // 10
console.log(myObj.y) // 20

当变量名与属性名称相同时,可以进行以下简写

const x = 10;
const y = 20;
 
const myObj = {
  x,
  y
};
 
console.log(myObj.x) // 10
console.log(myObj.y) // 20

13,模板字符串

const name = "Nick";
`Hello ${name}, the following expression is equal to four : ${2+2}`;
 
// Hello Nick, the following expression is equal to four: 4

14,带标签(tag)的模板字符串

模板标签是可以作为模板字符串(template literal)的前缀函数。当一个函数被这钟方式调用时,第一个参数是出现在模板插值变量之间的字符串数组,并且随后的参数是插值变量的值。可以使用展开运算符 … 捕获

function highlight(strings, ...values) {
  console.log(strings);//(3) ["I like ", " on ", ".", raw: Array(3)]
  console.log(values);//(2) ["jam", "toast"]
 
  const interpolation = strings.reduce((prev, current) => {
    return prev + current + (values.length ? "<mark>" + values.shift() + "</mark>" : "");
  }, "");
 
  return interpolation;
}
 
const condiment = "jam";
const meal = "toast";
 
highlight`I like ${condiment} on ${meal}.`;
// "I like <mark>jam</mark> on <mark>toast</mark>."
如果我们这样调用 highlight`I like ${condiment} on ${meal}` (注意最后面没”.”),
那么第一个参数还是一个 3 个元素的数组:[“I like “, ” on “, “”],特别注意最后一个元素是的空字符串””

strings 确实是一个数组,但是它还有一个 raw 属性。其属性值 strings.raw 也是一个数组,其元素分别表示 strings 中对应的,经过转义之前在 模板字符串(Template literals) 中由用户输入的字符串

const myTag = (strs, ...exprs) => {
    console.log(strs);                  //(3) ["x", "y", "", raw: Array(3)]
    console.log(strs.raw);              //(3) ["x", "\y", ""]
    console.log(exprs);                 //[1, 2]
};
 
const obj = { a: 1, b: 2 };
const result = myTag`x${obj.a}\y${obj.b}`;

后面剩余参数

function comma(strings, ...values) {
  return strings.reduce((prev, next) => {
    let value = values.shift() || [];
    value = value.join(", ");
    return prev + next + value;
  }, "");
}
 
const snacks = ['apples', 'bananas', 'cherries'];
comma`I like ${snacks} to snack on.`;
// "I like apples, bananas, cherries to snack on."

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
arrayObject.shift()
返回值
数组原来的第一个元素的值
如果数组是空的,那么 shift() 方法将不进行任何操作,返回 undefined 值。请注意,该方法不创建新数组,而是直接修改原有的 arrayObject。

var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"

document.write(arr + "<br />")  //George,John,Thomas
document.write(arr.shift() + "<br />")  //George
document.write(arr)  //John,Thomas

要删除并返回数组的最后一个元素,请使用 pop() 方法。

注意: 名为styled-components的著名库很大程度上依赖于此功能

15,导入 / 导出 (imports/ export)

// mathConstants.js
export const pi = 3.14;
export const exp = 2.7;
export const alpha = 0.35;
 
// -------------
 
// myFile.js
import { pi, exp } from './mathConstants.js'; // 命名导入 -- 类似于解构语法
console.log(pi) // 3.14
console.log(exp) // 2.7
 
// -------------
 
// mySecondFile.js
import * as constants from './mathConstants.js'; // 将所有导出的值注入到 constants 变量中
console.log(constants.pi) // 3.14
console.log(constants.exp) // 2.7

可以使用别名

import { foo as bar } from 'myFile.js'; // foo 被导入并注入到一个新的 bar 变量中

默认导出,每个模块只能有一个默认导出。默认导出可以是函数,类,对象或其他任何东西。这个值被认为是“主要”的导出值

// coolNumber.js
const ultimateNumber = 42;
export default ultimateNumber;
 
// myFile.js
import number from './coolNumber.js';
// 默认导出,将独立于其名称,自动注入到 number 这个变量; 
console.log(number) // 42

// sum.js
export default function sum(x, y) {
  return x + y;
}
// -------------
 
// myFile.js
import sum from './sum.js';
const result = sum(1, 2);
console.log(result) // 3

ECMAScript 6 Modules(模块)系统及语法详解
ES6 Modules in bulletpoints
Export – MDN
Import – MDN
Understanding ES6 Modules
Destructuring special case – import statements
Misunderstanding ES6 Modules – Kent C. Dodds
Modules in JavaScript

16,Promises的三种状态
等待中 (Pending)
达成 (Fulfilled)
拒绝 (Rejected)

const xFetcherPromise = new Promise( // 使用 "new" 关键字创建promise,并把它保存至一个变量
  function(resolve, reject) { // Promise 构造函数需要一个带有着 resolve 和 reject 这两个参数的函数作为参数
    $.get("X") // 执行 Ajax 请求
      .done(function(X) { // 一旦请求完成...
        resolve(X); // ... 把 X 值做为参数去 resolve promise
      })
      .fail(function(error) { // 如果请求失败...
        reject(error); // ... 把 error 做为参数去 reject promise
      });
  }
)

Promise 对象需要一个带有两个参数 ( resolve 和 reject ) 的执行函数。这两个参数会把 pending 状态的 promise 分别进行 fulfilled 和 rejected 的处理。
Promise 在实例创建后处于待处理状态,并且它的执行器函数立即执行。一旦在执行函数中调用了 resolve 或 reject 函数,Promise 将调用相关的处理程序。

为了获得 promise 结果(或错误),我们必须通过执行以下操作来附加处理程序

xFetcherPromise
  .then(function(X) {
    console.log(X);
  })
  .catch(function(err) {
    console.log(err)
  })

如果 promise 成功,则执行 resolve ,并执行 .then 参数所传递的函数。
如果失败,则执行 reject ,并执行 .catch 参数所传递的函数。

回调地狱 (callback hell)
JavaScript Promises for dummies – Jecelyn Yeen
JavaScript Promise API – David Walsh
Using promises – MDN
What is a promise – Eric Elliott
JavaScript Promises: an Introduction – Jake Archibald

17,异步和等待(Async Await)
async / await 函数的目的是简化同步使用 promise 的行为,并对一组 promises 执行一些处理。
依赖于 promises
await 必须在async函数中使用

async function getGithubUser(username) { 
// async 关键字允许在函数中使用 await ,意味着函数返回一个 promise 
  const response = await fetch(`https://api.github.com/users/${username}`); 
  // 执行在这里暂停,直到fetch返回的 Promise 被 resolved 
  return response.json();
}
 
getGithubUser('mbeaudru')
  .then(user => console.log(user)) // 记录用户响应 - 不能使用 await 语法,因为此代码不在 async 函数中 
  .catch(err => console.log(err)); // 如果在我们的异步函数中抛出一个错误,我们将在这里捕获它 

async 操作符将一个函数标记为异步,并将始终返回一个 Promise 。你可以在 async 函数中使用 await 操作符来暂停该行代码的执行,直到表达式中返回的 Promise resolves 或 rejects 。
当异步函数运行到 return 语句时,将会使用返回的值来 fulfilled Promise。 如果在 async 函数中抛出错误,则 Promise 状态将转为 rejected 。 如果没有从 async 函数返回任何值,则在执行 async 函数完成时,仍然会返回 Promise 并 resolves 为无值。
await 操作符用于等待 Promise fulfilled ,只能在 async 函数体内使用。 遇到这种情况时,代码执行将暂停,直到 promise fulfilled。

注意: fetch 是一个允许执行 AJAX 请求,返回一个 Promise 的函数

function getGithubUser(username) {
  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());
}
 
getGithubUser('mbeaudru')
  .then(user => console.log(user))
  .catch(err => console.log(err));

当你需要链接(chain)相互依赖的 promises 时,async / await 语法特别方便 。
例如,如果您需要获取一个令牌(token) ,以便能够在数据库上获取博客文章,然后获取作者信息:

async function fetchPostById(postId) {
  const token = (await fetch('token_url')).json().token;
  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();
  const author = (await fetch(`/users/${post.authorId}`)).json();
 
  post.author = author;
  return post;
}
 
fetchPostById('gzIrzeo64')
  .then(post => console.log(post))
  .catch(err => console.log(err));

使用 ES2017 中的 Async(异步) 函数 和 Await(等待)
ES2017 新特性:Async Functions (异步函数)
Async/Await – JavaScript.Info
ES7 Async/Await
JavaScript awaits
Async Function
Await
Using async / await in express with node 8

18,真值/假值(Truthy / Falsy)
在 JavaScript 中,truthy 或 falsy 值是在布尔上下文中求值时被转换为布尔值的值。布尔上下文的一个最常见的例子是求值 if 条件:

每个值将被转换为true,除非它们等于以下值:

  • false
  • 0
  • “” (空字符串)
  • null
  • undefined
  • NaN

if (myVar) {}
myVar 可以是任何 一等公民(first-class citizen) (变量, 函数, 布尔值) ,但它会被转换成一个布尔值,因为它会在布尔上下文中进行就值。

逻辑非 !

!0 // true -- 0 是 falsy(假) 值,所以它返回 true
!!0 // false -- 0 是 falsy(假) 值, 所以 !0 返回 true , 所以 !(!0) 返回 false
!!"" // false -- 空字符串是 falsy(假) 值, 所以 NOT (NOT false) 等于 false
new Boolean(0) // false
new Boolean(1) // true

Truthy (MDN)
Falsy (MDN)
Truthy and Falsy values in JS – Josh Clanton

19,静态方法

class Repo{
  static getName() {
    return "Repo name is modern-js-cheatsheet"
  }
  useName(){
    //作为构造函数的属性来调用静态方法
    return this.constructor.getName() + ' and it contains some really important stuff'
  }
}
 
// 我们需要实例化这个 class(类),以使用非静态方法 
let r = new Repo()
console.log(r.useName()) //Repo name is modern-js-cheatsheet and it contains some really important stuff

更好的理解原型:

Understanding Prototypes in JS – Yehuda Katz
A plain English guide to JS prototypes – Sebastian Porto
Inheritance and the prototype chain – MDN
更好的理解类:

ES6 Classes in Depth – Nicolas Bevacqua
ES6 Features – Classes
JavaScript Classes – MDN

ECMAScript 2015(ES6)的十大特征
JavaScript ES6(ES2015)入门-核心特性概述
ES6 新特性范例大全
现在就可以使用的5个 ES6 特性
面向对象的 JavaScript – 深入了解 ES6 类
使用 ES2017 中的 Async(异步) 函数 和 Await(等待)
JavaScript ECMAScript 2015 (ES6) 和 ECMAScript 2016 (ES7) 新特性速查表
ECMAScript 6 Modules(模块)系统及语法详解
学习 ES2015 新特性
JavaScript ES2015 中对象继承的模式
JavaScript 新书:探索 ES2016 与 ES2017

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React 18是React的最新版本,它引入了一些新的功能和改进。在学习React 18时,你可以关注以下几个方面: 1. React组件:React组件是构建用户界面的基本单元。你可以使用React.createElement()函数或JSX语法来创建React元素和组件。React元素是不可变的,而React组件是可复用的。\[1\] 2. react-dom.development.jsreact-dom/client模块:这些模块提供了处理真实DOM的功能,包括Diff算法和渲染成真实DOM的过程。你可以在HTML文件中引入这些模块,并使用ReactDOM.createRoot()方法来渲染React的DOM。\[2\] 3. Hook:Hook是React中的特殊函数,它允许你在函数组件中添加状态和其他特性。例如,useState是一个Hook,它可以让你在函数组件中添加状态。你可以使用useState来定义和更新状态,并在组件中使用它们。\[3\] 在学习React 18时,你可以通过阅读官方文档、参考教程和实践项目来深入了解这些概念和用法。同时,你也可以与其他开发者交流和分享经验,加深对React的理解。 #### 引用[.reference_title] - *1* *2* *3* [2023年React18笔记【慕课网imooc】【尚硅谷】【Vue3+React18 + TS4考勤系统】](https://blog.csdn.net/qq_28838891/article/details/124598439)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值