Skip to content

Commit

Permalink
feat: first push
Browse files Browse the repository at this point in the history
  • Loading branch information
qddegtya committed Feb 19, 2019
0 parents commit fc83cd0
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/test/*.js
26 changes: 26 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"rules": {
"indent": [
2,
2
],
"quotes": [
2,
"single"
],
"linebreak-style": [
2,
"unix"
],
"semi": [
2,
"never"
]
},
"env": {
"es6": true,
"node": true,
"browser": true
},
"extends": "eslint:recommended"
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
14 changes: 14 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/test/lang.test.js"
}
]
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# AJS

> 💗 A collection of utility libraries used by [@qddegtya](https://github.com/qddegtya)
Empty file added index.js
Empty file.
167 changes: 167 additions & 0 deletions lang/class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
*
* let A = ajs.lang.base.Class({
* $parent: Base
* $ctor: () => {
* // super
* this.$super()
* },
* $static: {
* foo: 1,
* bar: 2,
* test () {
*
* }
* },
*
* $_foo: 1,
*
* $_printFoo () {
*
* }
*
* test () {
*
* }
* })
*
* let B = A.$extends(function () {
* // private here
*
* // return your option
* return {
*
* }
* })
*
* let b = B.$new()
*
*/
const ClassShape = option => {
let INSTANCE_PROPERTY_REGEXP = /^\$_[^$_]+/
let _options = typeof option === 'function' ? option() : option

let _assign = function(dst, src) {
for (let k in src) {
dst[k] = src[k]
}
}

let _assignWithBind = function(thisArg, dst, src) {
for (let k in src) {
let val = src[k]
if (typeof val === 'function') {
dst[k] = val.bind(thisArg)
} else {
dst[k] = val
}
}
}

let _processOptions = function(option) {
let $parent = option.$parent,
$ctor = option.$ctor,
$static = option.$static || Object.create(null),
$instance = Object.create(null),
$prototype = Object.create(null)

for (let k in option) {
// 实例上不该访问到这些属性,但可以允许访问到 $ctor
if (k === '$parent' || k === '$static') {
continue
}

// 实例属性/方法
if (INSTANCE_PROPERTY_REGEXP.test(k)) {
$instance[k] = option[k]
continue
}

// 剩下的给原型
$prototype[k] = option[k]
}

return {
$parent,
$ctor,
$static,
$instance,
$prototype
}
}

const { $parent, $ctor, $static, $instance, $prototype } = _processOptions(
_options
)

// 父级原型
let parentPrototype =
typeof $parent === 'function' ? $parent.prototype : $parent

let AClass = function() {
let __super_is_called__ = false,
ins,
superThis

// this.$super()
this.$super = function() {
__super_is_called__ = true
superThis = $parent.apply(this, arguments)
}

// 继承的情况下可以省略 $ctor
if (!$ctor && $parent) {
ins = $parent.apply(superThis || this, arguments)
} else {
ins = $ctor.apply(superThis || this, arguments)

// 检查 super 调用
if ($parent && !__super_is_called__ && typeof $parent === 'function') {
throw new Error('You should call this.$super first before use `this`.')
}
}

// 如果存在继承的情况
// 处理 this.$super.xx
if ($parent) {
_assignWithBind(this, this.$super, parentPrototype)
}

// 处理实例属性
_assignWithBind(this, this, $instance)

return ins
}

// 处理继承
if ($parent) {
AClass.prototype = Object.create(parentPrototype)
AClass.prototype['$class'] = AClass
}

// 处理原型挂载
_assign(AClass.prototype, $prototype)

// 静态属性和方法的继承
AClass.__proto__ = $parent
// 处理静态属性和方法
_assign(AClass, $static)

// 标记
AClass.$parent = $parent

// chain
AClass.$extends = function(option) {
option.$parent = this
return ClassShape(option)
}

// new
AClass.$new = function() {
return new AClass()
}

return AClass
}

module.exports = ClassShape
9 changes: 9 additions & 0 deletions lang/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const Class = require('./class')

const _exportModule = {
base: {
Class
}
}

module.exports = _exportModule
Empty file added lang/util.js
Empty file.
22 changes: 22 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "ajs",
"version": "1.0.0",
"description": "ajs",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint **/*.js --fix"
},
"keywords": [
"ajs",
"util"
],
"author": "qddegtya",
"license": "MIT",
"devDependencies": {
"eslint": "^5.14.1"
}
}
85 changes: 85 additions & 0 deletions test/lang.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const lang = require("../lang");

let MyDate = lang.base.Class(function() {
let formatDate = function(date) {
return "格式化日期";
};

return {
$parent: Date,

toFormat: function(format_str) {
return formatDate(this, format_str);
}
};
});

let A = lang.base.Class(function() {
// 私有变量
let $privateA = "xiaoa";

return {
$ctor: function(name) {
this.a = 1;
this.name = name;
},

$static: {
foo: 1,
test: function() {
console.log("this is a test.");
}
},

$_a: 1,

print: function() {
this.$_print(this.a + $privateA);
},

$_print: function(msg) {
console.log(msg);
}
};
});

const B = A.$extends({
$static: {
bar: 2
},

print: function() {
this.$super.print();
console.log("this is " + this.name);
}
});

const C = lang.base.Class({
$parent: {
on: function() {
console.log("on");
}
},

$ctor: function(name) {
this.name = name;
},

test: function() {
this.on();
}
});

let b = B.$new("john");
console.log(B.foo);
console.log(B.bar);
B.test();
b.print();

let date = MyDate.$new("2019-01-02");
console.log(date.toFormat());

console.log(Object.getPrototypeOf(b) === B.prototype);

let c = C.$new();
c.test();

0 comments on commit fc83cd0

Please sign in to comment.