简评:debug 的时候看到 element 对象中有 $$typeof 这属性,于是查了一下这到底干嘛的。我们知道,通过 JSX 创建一个 React Elements 时:<marquee bgcolor="#ffa7c4">hi</marquee>实际上调用的是 React.createElement 方法:React.createElement( /* type / ‘marquee’, / props / { bgcolor: ‘#ffa7c4’ }, / children / ‘hi’)该方法会返回一个 React Element 对象,大概长这样:{ type: ‘marquee’, props: { bgcolor: ‘#ffa7c4’, children: ‘hi’, }, key: null, ref: null, $$typeof: Symbol.for(‘react.element’), // ???? Who dis}这个 $$typeof 是什么? 各种前端框架出现之前,应用通常会构造 HTML 并将它们插入到 DOM 中,例如:const messageEl = document.getElementById(‘message’);messageEl.innerHTML = ‘<p>’ + message.text + ‘</p>’;这代码一般能正常工作,除非你的 message.text 返回 ’<img src onerror=“stealYourPassword()">’ 这样的字符串。为了防止这种情况,可以使用类似于 document.createTextNode()或textContent 仅处理 text 的 api。也可以通过预处理替换 < > 这类特殊的字符。但是这样还是有很多潜在的问题。所以现代前端框架像 React 会为字符串转义成文字内容:<p> {message.text}</p>就算 message.text 返回 <img> 也会当成字符串处理。要在 React 元素中呈现 HTML ,则需要编写dangerouslySetInnerHTML={{ __html: message.text }},这有助于你在审查代码的时候重视它。但是这样仍然无法完全禁止注入攻击,例如:<a href={user.website}>,注意 website 为 ‘javascript: stealYourPassword()‘的情况。 对用户输入使用 … 运算符也很危险 <div {…userData}>。 为什么需要 $$typeof通过上面的介绍你可能已经猜到了,$$typeof 是为了防止 XSS 攻击。前面介绍了,React 元素大概是这样的(没有包含 $$typeof 这个属性的情况):{ type: ‘marquee’, props: { bgcolor: ‘#ffa7c4’, children: ‘hi’, }, key: null, ref: null}试想这样一种情况,服务器允许用户储存任意的 JSON 数据。那么就可以手动构建 React Element 对象传入到元素中。例如:// Server could have a hole that lets user store JSONlet expectedTextButGotJSON = { type: ‘div’, props: { dangerouslySetInnerHTML: { __html: ‘/ put your exploit here */’ }, }, // …};let message = { text: expectedTextButGotJSON };// Dangerous in React 0.13<p> {message.text}</p>所以 React 0.14 使用 Symbol 标记每个 React 元素。{ type: ‘marquee’, props: { bgcolor: ‘#ffa7c4’, children: ‘hi’, }, key: null, ref: null, $$typeof: Symbol.for(‘react.element’),}这样就可以规避这个问题,使用 Symbol 类型是因为 JSON 中无法传递 Symbol。React 会检查 element.$$typeof 然后拒绝处理非法的元素。原文: Why Do React Elements Have a $$typeof Property?