04.JSX底层实操
巨量注释笔记😊因为自己写的处理jsx还是不够完善,后面的代码还是用会React官方的方法。所以可以先跳过本章
Part 1 jsx→viscalDOM
这里可以参看我的开源库
1 | /* |
对应的index.js,这里我们用03
的对象。
1 | // import React from "react"; |
如此完成createElement的覆盖
Part 2 viscalDOM →真实DOM
1 | /*part2.render函数:把虚拟DOM变为真实DOM(按v16),构建思路如下 |
定义一个对象迭代器:封装一个对象迭代的方法
- 基于传统的for/in循环,会存在一些弊端(性能较差(既可以迭代私有的,也可以迭代公有的);只能迭代“可枚举、非Symbol类型的”属性…)
一般而言,内置属性都是不可枚举的(枚举:可以被列举、例如for/in、Object.keys等列举出来的);自定义属性都是可枚举的,我们可以通过Object.defineProperty方法定义枚举属性
- 解决思路:获取对象所有的私有属性「私有的、不论是否可枚举、不论类型」
- Object.getOwnPropertyNames(arr) -> 获取对象非Symbol类型的私有属性「无关是否可枚举」
- Object.getOwnPropertySymbols(arr) -> 获取Symbol类型的私有属性
获取所有的私有属性:
let keys = Object.getOwnPropertyNames(arr).concat(Object.getOwnPropertySymbols(arr));
可以基于ES6中的Reflect.ownKeys代替上述操作「弊端:不兼容IE」
let keys = Reflect.ownKeys(arr);
1 | let function iterator(obj) { |
定义一个创建真实DOM的函数
这里先不对ref(获取真实DOM)和key(用于优化)进行处理
分析后函数任务就是:先根据type创建一个标签,然后把props中的属性设置给标签,最后把标签插入到指定的容器中。
于是接下来按步骤处理:
- type:标签名
- className
- style
- children
1 | export function render(virtualDOM, container) { |
完整代码
1 | //src\jsxHandle.js |
1 | //src\index.jsx |
踩坑
没想到运行时遇见这个,排错后发现是src\jsxHandle.js
文件中,each函数
的callback函数形参写反了
总结
- 底层真的用了很多js基础的内容
- 数据结构的运用很重要
因为自己写的处理jsx还是不够完善,后面的代码还是用会React官方的方法