mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Make createClass 10-15% faster on complex specs
This commit is contained in:
@@ -414,7 +414,7 @@ function validateTypeDef(Constructor, typeDef, location) {
|
||||
}
|
||||
}
|
||||
|
||||
function validateMethodOverride(proto, name) {
|
||||
function validateMethodOverride(isAlreadyDefined, name) {
|
||||
var specPolicy = ReactClassInterface.hasOwnProperty(name) ?
|
||||
ReactClassInterface[name] :
|
||||
null;
|
||||
@@ -431,7 +431,7 @@ function validateMethodOverride(proto, name) {
|
||||
}
|
||||
|
||||
// Disallow defining methods more than once unless explicitly allowed.
|
||||
if (proto.hasOwnProperty(name)) {
|
||||
if (isAlreadyDefined) {
|
||||
invariant(
|
||||
specPolicy === SpecPolicy.DEFINE_MANY ||
|
||||
specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
|
||||
@@ -465,6 +465,7 @@ function mixSpecIntoComponent(Constructor, spec) {
|
||||
);
|
||||
|
||||
var proto = Constructor.prototype;
|
||||
var autoBindPairs = proto.__reactAutoBindPairs;
|
||||
|
||||
// By handling mixins before any other properties, we ensure the same
|
||||
// chaining order is applied to methods with DEFINE_MANY policy, whether
|
||||
@@ -484,7 +485,8 @@ function mixSpecIntoComponent(Constructor, spec) {
|
||||
}
|
||||
|
||||
var property = spec[name];
|
||||
validateMethodOverride(proto, name);
|
||||
var isAlreadyDefined = proto.hasOwnProperty(name);
|
||||
validateMethodOverride(isAlreadyDefined, name);
|
||||
|
||||
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
|
||||
RESERVED_SPEC_KEYS[name](Constructor, property);
|
||||
@@ -495,7 +497,6 @@ function mixSpecIntoComponent(Constructor, spec) {
|
||||
// 2. Overridden methods (that were mixed in).
|
||||
var isReactClassMethod =
|
||||
ReactClassInterface.hasOwnProperty(name);
|
||||
var isAlreadyDefined = proto.hasOwnProperty(name);
|
||||
var isFunction = typeof property === 'function';
|
||||
var shouldAutoBind =
|
||||
isFunction &&
|
||||
@@ -504,10 +505,7 @@ function mixSpecIntoComponent(Constructor, spec) {
|
||||
spec.autobind !== false;
|
||||
|
||||
if (shouldAutoBind) {
|
||||
if (!proto.__reactAutoBindMap) {
|
||||
proto.__reactAutoBindMap = {};
|
||||
}
|
||||
proto.__reactAutoBindMap[name] = property;
|
||||
autoBindPairs.push(name, property);
|
||||
proto[name] = property;
|
||||
} else {
|
||||
if (isAlreadyDefined) {
|
||||
@@ -700,14 +698,14 @@ function bindAutoBindMethod(component, method) {
|
||||
* @param {object} component Component whose method is going to be bound.
|
||||
*/
|
||||
function bindAutoBindMethods(component) {
|
||||
for (var autoBindKey in component.__reactAutoBindMap) {
|
||||
if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
|
||||
var method = component.__reactAutoBindMap[autoBindKey];
|
||||
component[autoBindKey] = bindAutoBindMethod(
|
||||
component,
|
||||
method
|
||||
);
|
||||
}
|
||||
var pairs = component.__reactAutoBindPairs;
|
||||
for (var i = 0; i < pairs.length; i += 2) {
|
||||
var autoBindKey = pairs[i];
|
||||
var method = pairs[i + 1];
|
||||
component[autoBindKey] = bindAutoBindMethod(
|
||||
component,
|
||||
method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,7 +810,7 @@ var ReactClass = {
|
||||
}
|
||||
|
||||
// Wire up auto-binding
|
||||
if (this.__reactAutoBindMap) {
|
||||
if (this.__reactAutoBindPairs.length) {
|
||||
bindAutoBindMethods(this);
|
||||
}
|
||||
|
||||
@@ -846,6 +844,7 @@ var ReactClass = {
|
||||
};
|
||||
Constructor.prototype = new ReactClassComponent();
|
||||
Constructor.prototype.constructor = Constructor;
|
||||
Constructor.prototype.__reactAutoBindPairs = [];
|
||||
|
||||
injectedMixins.forEach(
|
||||
mixSpecIntoComponent.bind(null, Constructor)
|
||||
|
||||
Reference in New Issue
Block a user