在 React – 修正children(上) 中我提到了React在遍历children过程当中是不允许修正个中的React Element的,这里我要做点补充,就是有个前提是:运用的React黑白紧缩版的,也就是说不是运用react.min.js这类,运用react.min.js则不会报错。
检察React非紧缩版的源码发明,里边有很多如许的代码块,而在紧缩版中是没有的。
if ("development" !== 'production') {
......
}
举个例子 React v0.14.4 (解释被我去掉了)
react.js
var ReactElement = function (type, key, ref, self, source, owner, props) {
var element = {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
ref: ref,
props: props,
_owner: owner
};
if ("development" !== 'production') {
......
Object.freeze(element.props);
Object.freeze(element);
}
return element;
};
react.min.js
u = function(e, t, n, r, o, i, u) {
var s = {
$$typeof: a,
type: e,
key: t,
ref: n,
props: u,
_owner: i
};
return s
};
对照紧缩前后,由if (“development” !== ‘production’) {} 包裹的代码块被直接strip掉了,申明紧缩工具确切了得。
这里重点是看紧缩前的,有两行代码很症结:
Object.freeze(element.props);
Object.freeze(element);
检察一下MDN关于Object.freeze的引见:
The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.
意义是说freeze防备了对象被修正,包含增删改属性。倘若在freeze以后修正对象属性,会有两种效果:
1若在非strict mode下,不会报错,然则任何修正都是不起作用的。
2若在strict mode 下,会throw TypeErrors。
看到这里可以晓得,为啥在运用非紧缩版的时刻修正React Element时会提醒报错,恰是由于该对象被freeze了;相反在紧缩版中由于没有freeze,所以可以胜利修正,不会报错。
谈到这里再趁便提下两点:
紧缩时怎样把if (“development” !== ‘production’) {} 去掉的?
React的README说起到:
To use React in production mode, set the environment variable NODE_ENV
to production
. A minifier that performs dead-code elimination such as UglifyJS is recommended to completely remove the extra code present in development mode.
晓得UglifyJS的朋侪应当晓得,UglifyJS在紧缩中,假如碰到if的前提是可估计获得的常数效果,那末就会疏忽掉没用的if/else分支。所以 “development” !== ‘production’ 即 false在紧缩时刻就被清算掉了。
UglifyJS细致的紧缩划定规矩引见看这里:解读UglifyJS(四)
为啥在开辟环境下要运用Object.freeze(),引stackoverflow中Sean Vieira的一句话:
We useObject.freeze
to freeze the router and route objects for non-production environments to ensure the immutability of these objects.
在开辟过程当中提醒报错,在线上环境不提醒,有点JAVA编译的滋味,编译时校验信息,提醒正告和毛病,在实行中不校验。
别的,Object.freeze()运转相对较慢,所以线上去掉这个操纵也是为了进步机能。
freeze vs seal vs normal 这个链接有测试的栗子。
总结:开辟过程当中照样用非紧缩版的React好,有利于实时发明问题。
完成!!!