arale 소스 코드 의 class 편 읽 기
arale 은 아 리, 개원 지역사회 의 스타 인물 인 옥 백 입 니 다. 개발 한 구성 요소 입 니 다. 코드 가 상당히 아름 답 고 옥 백 의 개원 정신 을 칭찬 합 니 다. 저 는 당신 의 팬 입 니 다.
이 소스 코드 에 대한 깨 달 음 을 공유 합 니 다. 잘못된 부분 이 있 으 면 지적 해 주세요. = ̄ω ̄=
먼저 원형 에 기초 한 계승 에 대해 이야기 하 다.
먼저 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 의 프로 토 타 입 체인 에 Function. prototype 이 없어 서 b 에 접근 할 수 없습니다.
원형 대상
__proto__
을 방문 하 는 것 은 비 표준 적 인 방법 이 며, ES5 표준 방법 은 Object. getPrototypeOf () 입 니 다.여기까지 원형 체인 을 바탕 으로 하 는 계승 은 이미 뚜렷 하 다.
function Animal() {}
function Dog() {}
Dog.prototype.__proto__ = Animal.prototype;
var dog = new Dog();
// dog.__proto__ --> Dog.prototype;
// dog.__proto__.__proto__ --> Animal.prototype
ES5 표준 표기 법 은?
Dog.prototype = Object.create(Animal.prototype);
아 라 엘 의 포장 을 보 겠 습 니 다.
//
function Ctor() {};
var createProto = Object.__proto__ ? function(proto) {
return {
__proto__: proto
}
} : function(proto) {
Ctor.prototype = proto;
return new Ctor();
}
원형 체인 계승 을 실현 할 수 있 는 세 가지 방법 이 있 지만 저 는 new Ctor 가 가장 느 립 니 다. Object. create 가 그 다음 에
__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
키 워드 를 사용 하지 않 을 때 인자
를 호출 하 는 것 입 니 다. 예 를 들 어:수정: 지원 되 지 않 는 방식 으로 호출 합 니 다.
function Animal() {}
Animal.prototype.talk = function() {}
//Class(Animal); Animal extend implement
var Dog = Class(Animal).extend({
swim: function() {}
})
Class 의 세 가지 변종 속성
new
Extends
Implements
이 세 가지 속성 은 특수 처 리 를 할 것 이다.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);
}
}
다시 한 번
Statics
방법 을 보 자. 그것 은 속성 을 섞 는 데 쓰 인 다.세 개의 변종 속성 이 실 행 됩 니 다.
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;
}
}
}
자, 가장 중요 한 방법
implement
이 왔 습 니 다. 클래스 를 만 드 는 데 사 용 됩 니 다. 부모 클래스 를 지정 할 수 있 습 니 다.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.create
을 살 펴 보 자. classify 의 클래스 는 하위 클래스 를 계속 만 들 수 있다.Class.extend = function(properties) {
properties || (properties = {});
//
properties.Extends = this;
return Class.create(properties);
}
마지막 으로 도구 류, Helpers 를 간단하게 소개 합 니 다.
// ,
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]";
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JavaScript 'getter' 대 'setter'Assalomu alaykum, bugun sizlar bilan JavaScriptda getter va setter metodlari tanishamiz. getter va setter metodlari orqa...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.