ReactElement是什么?
// s是我们写的jsx
const s = '<div>hello <span>wo<span>rld</span></span></div>'
// 下面是将s转为react语法代码,返回的都是ReactElement
React.createElement("div", null, "hello ",
React.createElement("span", null, "wo",
React.createElement("span", null, "rld")
)
);
// 将react代码转为AST

复制代码
ReactElement主要使用Object.defineProperty设置属性
Object.defineProperty
语法Object.defineProperty(obj,propkey,descriptor)
描述对象descriptor的属性有哪些
- configurable:是否可修改属性,若为false则不能修改该属性的任何描述,也不可以删除,设置为true才可以对属性描述进行修改和删除;默认为false;
var a = Object.defineProperty({},'key',{})// 默认configurable没false
/**
以下调用会报错:
Uncaught TypeError: Cannot redefine property: key
at Function.defineProperty (<anonymous>)
at <anonymous>:1:8
*/
Object.defineProperty(a,'key',{configurable:true})
delete a.key // 输出false,删除失败
复制代码
- enumerable:是否可枚举,默认false.
//继续以上例子
for(var key in a){console.log(key)} // 输出undefined
Object.keys(a) // 输出[]
复制代码
- value:属性对应的值
- writable:是否可以改变value的值,默认为false
//继续以上例子
a.key =1
console.log(a) // {key: undefined}
复制代码
- get:存取描述,返回属性的值,默认为undefined
Object.defineProperty(a,'key1',{
configurable:true,
enumerable:true,
get(){return '2'}
})
console.log(a.key1) // 2
// 存取描述和value、wriable不能同时使用
Object.defineProperty(a,'key1',{
configurable:true,
enumerable:true,
writable:true
get(){return '2'}
})
/**
VM2292:1 Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
at Function.defineProperty (<anonymous>)
at <anonymous>:1:8
*/
复制代码
- set:存取描述,设置属性值,默认返回undefined
var key1Value = '2'
// 存取描述和value、wriable不能同时使用
Object.defineProperty(a,'key1',{
configurable:true,
enumerable:true,
get(){return key1Value},
set(newV) {key1Value = newV}
})
复制代码
数据描述符
如果一个描述符不具有 value、writable、get 和 set 中的任意一个键,那么它将被认为是一个数据描述符。
ref和key均为数据描述符,因此react中判断ref和key是否有效是利用Object.getOwnPropertyDescriptor(a,'key').get
来判断
function hasValidRef(config) {
if (__DEV__) {
if (hasOwnProperty.call(config, 'ref')) {
const getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.ref !== undefined;
}
复制代码
Object.freeeze
冻结的对象不能被修改,但被冻结的对象的属性是个对象,那这个属性可以被修改的,因此属性不想被修改也需要被冻结
// ReactElement返回被冻结的对象
if (Object.freeze) {
Object.freeze(element.props);
Object.freeze(element);
}
复制代码
待续….
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END