araleのソースコードのclass編を読みます.
5854 ワード
更新:araleソースのatribute編を読みます.
アールはアリ、オープンソースのコミュニティのスターである玉伯です.開発されたセットはとても優美で、玉伯のオープンソース精神を絶賛しています.私はあなたのファンです.
ここで私はこのソースコードの悟りを共有します.間違ったところがあれば、ご指摘をお願いします.~ω ̄=
まず原型に基づく継承について話します.
まず、segement faultで議論されている問題を見てください.
なお、プロトタイプ
ここでは、プロトタイプチェーンの継承が明らかになりました.
3つの変数の属性が実行されます.
アールはアリ、オープンソースのコミュニティのスターである玉伯です.開発されたセットはとても優美で、玉伯のオープンソース精神を絶賛しています.私はあなたのファンです.
ここで私はこのソースコードの悟りを共有します.間違ったところがあれば、ご指摘をお願いします.~ω ̄=
まず原型に基づく継承について話します.
まず、segement faultで議論されている問題を見てください.
function F() {}
Object.prototype.a = function() {}
Function.prototype.b = function() {}
var f = new F()
// F.a F.b f.a
Fはaとbを呼び出すことができます.Fのプロトタイプチェーンはこのようなものです.(直観解釈:FはFunctionの例であり、FはObjectから継承される)F ----> Function.prototype ----> Object.prototype ----> null
// F.__proto__ === Function.prototype
// Function.prototype.__proto__ === Object.prototype
// Object.prototype.__proto__ === null
fはaだけ呼び出すことができます.fのプロトタイプチェーンはこのようです.(直観解釈:fはFの例であり、すべて対象であり、fはObjectから継承される)f ----> F.prototype ----> Object.prototype ----> null
// f.__proto__ === F.prototype
// F.prototype.__proto__ === Object.prototype
// Object.prototype.__proto__ === null
fのプロトタイプチェーンにFuntion.prototypeはありませんので、bにはアクセスできません.なお、プロトタイプ
__proto__
非標準的な方法であり、ES 5標準的な方法はObject.get ProttypeOf()である.ここでは、プロトタイプチェーンの継承が明らかになりました.
function Animal() {}
function Dog() {}
Dog.prototype.__proto__ = Animal.prototype;
var dog = new Dog();
// dog.__proto__ --> Dog.prototype;
// dog.__proto__.__proto__ --> Animal.prototype
ES 5に基づく表記はDog.prototype = Object.create(Animal.prototype);
araleのパッケージを見に来ました.//
function Ctor() {};
var createProto = Object.__proto__ ? function(proto) {
return {
__proto__: proto
}
} : function(proto) {
Ctor.prototype = proto;
return new Ctor();
}
プロトタイプのチェーン継承が可能な3つの書き方がありますが、new Ctorをテストするのは一番遅いです.Object.creaeteの次は、__proto__
一番早いです.function Ctor() {}
function getProto1(proto, c) {
Ctor.prototype = proto;
var o = new Ctor();
o.constructor = c;
return o;
}
function getProto2(proto, c) {
return Object.create(proto, {
constructor: {
value: c
}
})
}
function getProto3(proto, c) {
return {
__proto__: proto,
constructor: c
}
}
続いて下を見る.function Class(o) {
if (!(this instanceof Class) && isFunction(o)) {
return classify(o);
}
}
function classify(cls) {
cls.extend = Class.extend;
cls.implement = implement;
return cls;
}
この表記は、使用しないnew
キーワードを呼び出した場合、パラメータ
修正:サポートされていないnew
の呼び出しです.function Animal() {}
Animal.prototype.talk = function() {}
//Class(Animal); Animal extend implement
var Dog = Class(Animal).extend({
swim: function() {}
})
Classの三つのバリエーションExtends
Implements
・Statics
・implement
この3つの属性は特殊処理されます.Class.Mutators = {
// ,
Extends: function(parent) {
var existed = this.prototype;
//
var proto = createProto(parent.prototype);
mix(proto, existed);
//
proto.constructor = this;
this.prototype = proto;
// superclass ,
this.superclass = parent.prototype;
},
// ,
Implements: function(items) {
//
isArray(items) || (items = [ items ]);
var proto = this.prototype, item;
while (item = items.shift()) {
// (Function), (Object), 。
mix(proto, item.prototype || item);
}
},
Statics: function(staticProperties) {
// 。
mix(this, staticProperties);
}
}
また、Class.create
方法を見てください.属性を混ぜるためのものです.3つの変数の属性が実行されます.
function implement(properties) {
var key, value;
for (key in properties) {
value = properties[key];
if (Class.Mutators.hasOwnProperty(key)) {
Class.Mutators[key].call(this, value);
} else {
this.prototype[key] = value;
}
}
}
はい、一番重要な方法Class.extend
来ました.これはクラスを作るためのもので、親の種類を指定できます.Class.create = function(parent, properties) {
// , Class
if (!isFunction(parent)) {
properties = parent;
parent = null;
}
properties || (properties = {});
// Extends ,
parent || (parent = properties.Extends || Class);
properties.Extends = parent;
//
function SubClass() {
//
parent.apply(this, arguments);
// ,initialize
if (this.constructor === SubClass && this.initialize) {
this.initialize.apply(this, arguments);
}
}
// ,
if (parent !== Class) {
Mix(SubClass, parent, parent.StaticsWhiteList);
}
// , ,
implement.call(SubClass, properties);
//
return classify(SubClass);
}
最後に継承の方法を見てみます.Class.extend = function(properties) {
properties || (properties = {});
//
properties.Extends = this;
return Class.create(properties);
}
最後の最後に、簡単にその工具類を紹介します.// ,
function mix(r, s, wl) {
for (var p in s) {
// : for in hasOwnProperty。
if (s.hasOwnProperty(p)) {
if (wl && indexOf(wl, p) === -1) continue;
if (p !== "prototype") {
r[p] = s[p];
}
}
}
}
// [].indexOf ES5 , 。
// polyfill 。
var indexOf = Array.prototype.indexOf ? function(arr, item) {
return arr.indexOf(item);
} : function(arr, item) {
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i] === item) {
return i;
}
}
return -1;
}
// , Object.prototype.toString [[class]]
var toString = Object.prototype.toString;
var isArray = Array.isArray || function(val) {
return toString.call(val) === "[object Array]";
}
var isFunction = function(val) {
return toString.call(val) === "[object Function]";
}