Comments (2)
第二代
import { extend, isFn, inherit, noop } from "./util";
import { Component } from "./Component";
/**
* 为了兼容0.13之前的版本
*/
var MANY = "DEFINE_MANY";
var MANY_MERGED = "MANY_MERGED";
var ReactClassInterface = {
mixins: MANY,
statics: MANY,
propTypes: MANY,
contextTypes: MANY,
childContextTypes: MANY,
getDefaultProps: MANY_MERGED,
getInitialState: MANY_MERGED,
getChildContext: MANY_MERGED,
render: "ONCE",
componentWillMount: MANY,
componentDidMount: MANY,
componentWillReceiveProps: MANY,
shouldComponentUpdate: "DEFINE_ONCE",
componentWillUpdate: MANY,
componentDidUpdate: MANY,
componentWillUnmount: MANY
};
var specHandle = {
displayName(Ctor, value, name) {
Ctor[name] = value;
},
mixins(Ctor, value) {
if (value) {
for (var i = 0; i < value.length; i++) {
mixSpecIntoComponent(Ctor, value[i]);
}
}
},
propTypes: mergeObject,
childContextTypes: mergeObject,
contextTypes: mergeObject,
getDefaultProps(Ctor, value, name) {
if (Ctor[name]) {
Ctor[name] = createMergedResultFunction(Ctor[name], value);
} else {
Ctor[name] = value;
}
},
statics(Ctor, value) {
extend(Ctor, Object(value));
},
autobind: noop
};
function mergeObject(fn, value, name) {
fn[name] = Object.assign({}, fn[name], value);
}
//防止覆盖Component内部一些重要的方法或属性
var protectedProps = {
mixin: 1,
setState: 1,
forceUpdate: 1,
__processPendingState: 1,
__pendingCallbacks: 1,
__pendingStates: 1
};
function mixSpecIntoComponent(Ctor, spec) {
if (!spec) {
return;
}
if (isFn(spec)) {
console.warn("createClass(spec)中的spec不能为函数,只能是纯对象"); // eslint-disable-line
}
var proto = Ctor.prototype;
var autoBindPairs = proto.__reactAutoBindPairs;
if (spec.hasOwnProperty("mixin")) {
specHandle.mixins(Ctor, spec.mixins);
}
for (var name in spec) {
if (!spec.hasOwnProperty(name)) {
continue;
}
if (protectedProps[name] === 1) {
continue;
}
var property = spec[name];
var isAlreadyDefined = proto.hasOwnProperty(name);
if (specHandle.hasOwnProperty(name)) {
specHandle[name](Ctor, property, name);
} else {
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
var shouldAutoBind =
isFn(property) &&
!isReactClassMethod &&
!isAlreadyDefined &&
spec.autobind !== false;
if (shouldAutoBind) {
autoBindPairs.push(name, property);
proto[name] = property;
} else {
if (isAlreadyDefined) {
var specPolicy = ReactClassInterface[name];
//合并多个同名函数
if (specPolicy === MANY_MERGED) {
//这个是有返回值
proto[name] = createMergedResultFunction(proto[name], property);
} else if (specPolicy === MANY) {
//这个没有返回值
proto[name] = createChainedFunction(proto[name], property);
}
} else {
proto[name] = property;
}
}
}
}
}
function mergeOwnProperties(one, two) {
for (var key in two) {
if (two.hasOwnProperty(key)) {
one[key] = two[key];
}
}
return one;
}
function createMergedResultFunction(one, two) {
return function mergedResult() {
var a = one.apply(this, arguments);
var b = two.apply(this, arguments);
if (a == null) {
return b;
} else if (b == null) {
return a;
}
var c = {};
mergeOwnProperties(c, a);
mergeOwnProperties(c, b);
return c;
};
}
function createChainedFunction(one, two) {
return function chainedFunction() {
one.apply(this, arguments);
two.apply(this, arguments);
};
}
function bindAutoBindMethod(component, method) {
var boundMethod = method.bind(component);
return boundMethod;
}
function bindAutoBindMethods(component) {
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);
}
}
//创建一个构造器
function newCtor(className) {
var curry = Function(
"ReactComponent",
"bindAutoBindMethods",
`return function ${className}(props, context) {
ReactComponent.call(this, props, context);
this.state = this.getInitialState ? this.getInitialState() : {};
if (this.__reactAutoBindPairs.length) {
bindAutoBindMethods(this);
}
};`
);
return curry(Component, bindAutoBindMethods);
}
var warnOnce = 1;
export function createClass(spec) {
if (warnOnce) {
warnOnce = 0;
console.warn("createClass已经过时,强烈建议使用es6方式定义类"); // eslint-disable-line
}
var Constructor = newCtor(spec.displayName || "Component");
var proto = inherit(Constructor, Component);
proto.__reactAutoBindPairs = [];
delete proto.render;
mixSpecIntoComponent(Constructor, spec);
if (isFn(Constructor.getDefaultProps)) {
Constructor.defaultProps = Constructor.getDefaultProps();
}
//性能优化,为了防止在原型链进行无用的查找,直接将用户没有定义的生命周期钩子置为null
for (var methodName in ReactClassInterface) {
if (!proto[methodName]) {
proto[methodName] = null;
}
}
return Constructor;
}
from anu.
第三代
import {extend, isFn, inherit} from "./util";
import {Component} from "./Component";
/**
* 为了兼容0.13之前的版本
*/
const LiFECYCLE = {
render: 1,
shouldComponentUpdate: 1,
componentWillReceiveProps: 1,
componentWillUpdate: 1,
componentDidUpdate: 1,
componentWillMount: 1,
componentDidMount: 1,
componentWillUnmount: 1,
componentDidUnmount: 1
};
function collectMixins(mixins) {
let keyed = {};
for (let i = 0; i < mixins.length; i++) {
let mixin = mixins[i];
if (mixin.mixins) {
applyMixins(mixin, collectMixins(mixin.mixins));
}
for (let key in mixin) {
if (mixin.hasOwnProperty(key) && key !== 'mixins') {
(keyed[key] || (keyed[key] = [])).push(mixin[key]);
}
}
}
return keyed;
}
var MANY_MERGED = {
getInitialState: 1,
getDefaultProps: 1,
getChildContext: 1
}
function flattenHooks(key, hooks) {
let hookType = typeof hooks[0];
if (hookType === 'object') {
// Merge objects
hooks.unshift({});
return Object
.assign
.apply(null, hooks);
} else if (hookType === 'function') {
return function () {
let ret;
for (let i = 0; i < hooks.length; i++) {
let r = hooks[i].apply(this, arguments);
if (r && MANY_MERGED[key]) {
if (!ret)
ret = {};
Object.assign(ret, r);
}
}
return ret;
};
} else {
return hooks[0];
}
}
function applyMixins(proto, mixins) {
for (let key in mixins) {
if (mixins.hasOwnProperty(key)) {
proto[key] = flattenHooks(key, mixins[key].concat(proto[key] || []));
}
}
}
//创建一个构造器
function newCtor(className) {
var curry = Function("ReactComponent", "blacklist",
`return function ${className}(props, context) {
ReactComponent.call(this, props, context);
for (let methodName in this) {
let method = this[methodName];
if (typeof method === 'function'&& !blacklist[methodName]) {
this[methodName] = method.bind(this);
}
}
if (spec.getInitialState) {
this.state = spec.getInitialState.call(this);
}
};`);
return curry(Component, LiFECYCLE);
}
var warnOnce = 1;
export function createClass(spec) {
if (warnOnce) {
warnOnce = 0;
console.warn("createClass已经过时,强烈建议使用es6方式定义类"); // eslint-disable-line
}
var Constructor = newCtor(spec.displayName || "Component");
var proto = inherit(Constructor, Component);
//如果mixins里面非常复杂,可能mixin还包含其他mixin
if (spec.mixins) {
applyMixins(spec, collectMixins(spec.mixins));
}
extend(proto, spec);
if (spec.statics) {
extend(Constructor, spec.statics);
}
"propTypes,contextTypes,childContextTypes,displayName"
.replace(/\w+/g, function (name) {
if (spec[name]) {
Constructor[name] = spec[name];
}
})
if (isFn(spec.getDefaultProps)) {
Constructor.defaultProps = spec.getDefaultProps();
}
return Constructor;
}
from anu.
Related Issues (20)
- input输入汉字不触发onChange事件 HOT 2
- 项目是否考虑升级为ts HOT 1
- 二次元魔法师希望你在那边过的开心
- 1 HOT 1
- 致敬,大佬走好 HOT 9
- RIP
- RIP HOT 5
- 致敬
- 致敬,默哀 HOT 3
- 一路走好
- 走好 HOT 3
- RIP
- 官方Q群加不进去
- 走好 大佬
- RIP ,走好大佬
- 大佬 走好
- 大佬 走好!
- 还有人维护这个库吗?
- IE8别用这个库,有内存泄漏问题,我因为自己的机器是ie11写完了才发现,特此提醒你们,并且以后也不会有人维护了 HOT 1
- 大佬走好
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from anu.