├── .eslintignore ├── .eslintrc.json ├── .github └── FUNDING.yml ├── .gitignore ├── JavaScript ├── 1-object.js ├── 2-prototype.js ├── 3-class.js ├── 4-closure.js ├── 5-bind.js ├── 6-logger.js ├── 7-prototype.js ├── 8-class.js ├── 9-inherits.js ├── a-class.js ├── b-set.js ├── c-alternative.js ├── d-get-set.js ├── e-array.js ├── f-functor.js └── g-functor.js ├── LICENSE └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "parserOptions": { 9 | "ecmaVersion": 2020 10 | }, 11 | "globals": { 12 | "BigInt": true 13 | }, 14 | "rules": { 15 | "indent": [ 16 | "error", 17 | 2 18 | ], 19 | "linebreak-style": [ 20 | "error", 21 | "unix" 22 | ], 23 | "quotes": [ 24 | "error", 25 | "single" 26 | ], 27 | "semi": [ 28 | "error", 29 | "always" 30 | ], 31 | "no-loop-func": [ 32 | "error" 33 | ], 34 | "block-spacing": [ 35 | "error", 36 | "always" 37 | ], 38 | "camelcase": [ 39 | "error" 40 | ], 41 | "eqeqeq": [ 42 | "error", 43 | "always" 44 | ], 45 | "strict": [ 46 | "error", 47 | "global" 48 | ], 49 | "brace-style": [ 50 | "error", 51 | "1tbs", 52 | { 53 | "allowSingleLine": true 54 | } 55 | ], 56 | "comma-style": [ 57 | "error", 58 | "last" 59 | ], 60 | "comma-spacing": [ 61 | "error", 62 | { 63 | "before": false, 64 | "after": true 65 | } 66 | ], 67 | "eol-last": [ 68 | "error" 69 | ], 70 | "func-call-spacing": [ 71 | "error", 72 | "never" 73 | ], 74 | "key-spacing": [ 75 | "error", 76 | { 77 | "beforeColon": false, 78 | "afterColon": true, 79 | "mode": "minimum" 80 | } 81 | ], 82 | "keyword-spacing": [ 83 | "error", 84 | { 85 | "before": true, 86 | "after": true, 87 | "overrides": { 88 | "function": { 89 | "after": false 90 | } 91 | } 92 | } 93 | ], 94 | "max-len": [ 95 | "error", 96 | { 97 | "code": 80, 98 | "ignoreUrls": true 99 | } 100 | ], 101 | "max-nested-callbacks": [ 102 | "error", 103 | { 104 | "max": 7 105 | } 106 | ], 107 | "new-cap": [ 108 | "error", 109 | { 110 | "newIsCap": true, 111 | "capIsNew": false, 112 | "properties": true 113 | } 114 | ], 115 | "new-parens": [ 116 | "error" 117 | ], 118 | "no-lonely-if": [ 119 | "error" 120 | ], 121 | "no-trailing-spaces": [ 122 | "error" 123 | ], 124 | "no-unneeded-ternary": [ 125 | "error" 126 | ], 127 | "no-whitespace-before-property": [ 128 | "error" 129 | ], 130 | "object-curly-spacing": [ 131 | "error", 132 | "always" 133 | ], 134 | "operator-assignment": [ 135 | "error", 136 | "always" 137 | ], 138 | "operator-linebreak": [ 139 | "error", 140 | "after" 141 | ], 142 | "semi-spacing": [ 143 | "error", 144 | { 145 | "before": false, 146 | "after": true 147 | } 148 | ], 149 | "space-before-blocks": [ 150 | "error", 151 | "always" 152 | ], 153 | "space-before-function-paren": [ 154 | "error", 155 | { 156 | "anonymous": "never", 157 | "named": "never", 158 | "asyncArrow": "always" 159 | } 160 | ], 161 | "space-in-parens": [ 162 | "error", 163 | "never" 164 | ], 165 | "space-infix-ops": [ 166 | "error" 167 | ], 168 | "space-unary-ops": [ 169 | "error", 170 | { 171 | "words": true, 172 | "nonwords": false, 173 | "overrides": { 174 | "typeof": false 175 | } 176 | } 177 | ], 178 | "no-unreachable": [ 179 | "error" 180 | ], 181 | "no-global-assign": [ 182 | "error" 183 | ], 184 | "no-self-compare": [ 185 | "error" 186 | ], 187 | "no-unmodified-loop-condition": [ 188 | "error" 189 | ], 190 | "no-constant-condition": [ 191 | "error", 192 | { 193 | "checkLoops": false 194 | } 195 | ], 196 | "no-console": [ 197 | "off" 198 | ], 199 | "no-useless-concat": [ 200 | "error" 201 | ], 202 | "no-useless-escape": [ 203 | "error" 204 | ], 205 | "no-shadow-restricted-names": [ 206 | "error" 207 | ], 208 | "no-use-before-define": [ 209 | "error", 210 | { 211 | "functions": false 212 | } 213 | ], 214 | "arrow-parens": [ 215 | "error", 216 | "always" 217 | ], 218 | "arrow-body-style": [ 219 | "error", 220 | "as-needed" 221 | ], 222 | "arrow-spacing": [ 223 | "error" 224 | ], 225 | "no-confusing-arrow": [ 226 | "error", 227 | { 228 | "allowParens": true 229 | } 230 | ], 231 | "no-useless-computed-key": [ 232 | "error" 233 | ], 234 | "no-useless-rename": [ 235 | "error" 236 | ], 237 | "no-var": [ 238 | "error" 239 | ], 240 | "object-shorthand": [ 241 | "error", 242 | "always" 243 | ], 244 | "prefer-arrow-callback": [ 245 | "error" 246 | ], 247 | "prefer-const": [ 248 | "error" 249 | ], 250 | "prefer-numeric-literals": [ 251 | "error" 252 | ], 253 | "prefer-rest-params": [ 254 | "error" 255 | ], 256 | "prefer-spread": [ 257 | "error" 258 | ], 259 | "rest-spread-spacing": [ 260 | "error", 261 | "never" 262 | ], 263 | "template-curly-spacing": [ 264 | "error", 265 | "never" 266 | ] 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: tshemsedinov 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /JavaScript/1-object.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const p1 = { 4 | x: 10, 5 | y: 20, 6 | 7 | move(x, y) { 8 | this.x += x; 9 | this.y += y; 10 | }, 11 | 12 | toString() { 13 | return `[${this.x}, ${this.y}]`; 14 | }, 15 | }; 16 | 17 | p1.move(-5, 10); 18 | 19 | console.log(p1); 20 | console.log(p1.toString()); 21 | console.log(p1 + ''); 22 | -------------------------------------------------------------------------------- /JavaScript/2-prototype.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Point(x, y) { 4 | this.x = x; 5 | this.y = y; 6 | } 7 | 8 | Point.from = function(obj) { 9 | const { x, y } = obj; 10 | return new Point(x, y); 11 | }; 12 | 13 | Point.prototype.move = function(x, y) { 14 | this.x += x; 15 | this.y += y; 16 | }; 17 | 18 | Point.prototype.toString = function() { 19 | return `[${this.x}, ${this.y}]`; 20 | }; 21 | 22 | console.log('function prototype:', (function() {}).prototype); 23 | console.log('lambda prototype:', (() => {}).prototype); 24 | 25 | console.log('Point prototype:', Point.prototype); 26 | console.log('move prototype:', Point.prototype.move.prototype); 27 | 28 | const p1 = new Point(10, 20); 29 | p1.move(-5, 10); 30 | 31 | console.log(p1); 32 | console.log(p1.toString()); 33 | console.log(p1 + ''); 34 | -------------------------------------------------------------------------------- /JavaScript/3-class.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Point { 4 | constructor(x, y) { 5 | this.x = x; 6 | this.y = y; 7 | } 8 | 9 | move(x, y) { 10 | this.x += x; 11 | this.y += y; 12 | } 13 | 14 | toString() { 15 | return `[${this.x}, ${this.y}]`; 16 | } 17 | 18 | static from(obj) { 19 | const { x, y } = obj; 20 | return new Point(x, y); 21 | } 22 | } 23 | 24 | const point1 = new Point(0, 0); 25 | point1.move(1, -1); 26 | point1.move(10, 0); 27 | 28 | const point2 = Point.from(point1); 29 | point2.move(-7, 25); 30 | 31 | console.log('Point prototype:', Point.prototype); 32 | console.log('move prototype:', Point.prototype.move.prototype); 33 | console.log('constructor prototype:', Point.constructor.prototype); 34 | 35 | const p1 = new Point(10, 20); 36 | p1.move(-5, 10); 37 | 38 | console.log(p1); 39 | console.log(p1.toString()); 40 | console.log(`${p1}`); 41 | -------------------------------------------------------------------------------- /JavaScript/4-closure.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const point = (x, y) => { 4 | const p = {}; 5 | 6 | p.move = (dx, dy) => { 7 | x += dx; 8 | y += dy; 9 | }; 10 | 11 | p.toString = () => `[${x}, ${y}]`; 12 | 13 | return p; 14 | }; 15 | 16 | const p1 = point(10, 20); 17 | p1.move(-5, 10); 18 | 19 | console.log(p1); 20 | console.log(p1.toString()); 21 | console.log(`${p1}`); 22 | -------------------------------------------------------------------------------- /JavaScript/5-bind.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function move(x, y) { 4 | this.x += x; 5 | this.y += y; 6 | } 7 | 8 | function toString() { 9 | return `[${this.x}, ${this.y}]`; 10 | } 11 | 12 | const p1 = { x: 10, y: 20 }; 13 | const p1move = move.bind(p1); 14 | const p1toString = toString.bind(p1); 15 | p1move(-5, 10); 16 | 17 | console.log(p1); 18 | console.log(p1toString()); 19 | console.log(`${p1}`); 20 | -------------------------------------------------------------------------------- /JavaScript/6-logger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = (kind) => { 4 | const color = logger.colors[kind] || logger.colors.info; 5 | return (s) => { 6 | const date = new Date().toISOString(); 7 | console.log(color + date + '\t' + s); 8 | }; 9 | }; 10 | 11 | logger.colors = { 12 | warning: '\x1b[1;33m', 13 | error: '\x1b[0;31m', 14 | info: '\x1b[1;37m', 15 | }; 16 | 17 | // Usage 18 | 19 | const warning = logger('warning'); 20 | const error = logger('error'); 21 | const debug = logger('debug'); 22 | const slow = logger('slow'); 23 | 24 | slow('I am slow logger'); 25 | warning('Hello'); 26 | error('World'); 27 | debug('Bye!'); 28 | -------------------------------------------------------------------------------- /JavaScript/7-prototype.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Logger(kind) { 4 | this.color = Logger.colors[kind] || Logger.colors.info; 5 | } 6 | 7 | Logger.colors = { 8 | warning: '\x1b[1;33m', 9 | error: '\x1b[0;31m', 10 | info: '\x1b[1;37m', 11 | }; 12 | 13 | Logger.prototype.log = function(s) { 14 | const date = new Date().toISOString(); 15 | console.log(this.color + date + '\t' + s); 16 | }; 17 | 18 | // Usage 19 | 20 | const warning = new Logger('warning'); 21 | const error = new Logger('error'); 22 | const debug = new Logger('debug'); 23 | const slow = new Logger('slow'); 24 | 25 | slow.log('I am slow logger'); 26 | warning.log('Hello'); 27 | error.log('World'); 28 | debug.log('Bye!'); 29 | -------------------------------------------------------------------------------- /JavaScript/8-class.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Logger { 4 | constructor(kind) { 5 | this.color = Logger.colors[kind] || Logger.colors.info; 6 | } 7 | 8 | log(s) { 9 | const date = new Date().toISOString(); 10 | console.log(this.color + date + '\t' + s); 11 | } 12 | } 13 | 14 | Logger.colors = { 15 | warning: '\x1b[1;33m', 16 | error: '\x1b[0;31m', 17 | info: '\x1b[1;37m', 18 | }; 19 | 20 | // Usage 21 | 22 | const warning = new Logger('warning'); 23 | const error = new Logger('error'); 24 | const debug = new Logger('debug'); 25 | const slow = new Logger('slow'); 26 | 27 | slow.log('I am slow logger'); 28 | warning.log('Hello'); 29 | error.log('World'); 30 | debug.log('Bye!'); 31 | -------------------------------------------------------------------------------- /JavaScript/9-inherits.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Rect(x, y, width, height) { 4 | this.x = x; 5 | this.y = y; 6 | this.width = width; 7 | this.height = height; 8 | } 9 | 10 | Rect.prototype.toString = function() { 11 | return `[${this.x}, ${this.y}, ${this.width}, ${this.height}]`; 12 | }; 13 | 14 | function Square(x, y, side) { 15 | Rect.call(this, x, y, side, side); 16 | } 17 | 18 | Object.setPrototypeOf(Square.prototype, Rect.prototype); 19 | 20 | // const util = require('util'); 21 | // util.inherits(Square, Rect); // for Node.js 22 | 23 | // Square.prototype = Object.create(Rect.prototype); 24 | // Square.prototype.constructor = Square; 25 | 26 | // Square.prototype = new Rect(); 27 | // Square.prototype.constructor = Square; 28 | 29 | const p1 = new Square(10, 20, 50); 30 | 31 | console.log(p1); 32 | console.log(p1.toString()); 33 | console.log(`${p1}`); 34 | -------------------------------------------------------------------------------- /JavaScript/a-class.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Rect { 4 | constructor(x, y, width, height) { 5 | this.x = x; 6 | this.y = y; 7 | this.width = width; 8 | this.height = height; 9 | } 10 | 11 | toString() { 12 | return `[${this.x}, ${this.y}, ${this.width}, ${this.height}]`; 13 | } 14 | } 15 | 16 | class Square extends Rect { 17 | constructor(x, y, side) { 18 | super(x, y, side, side); 19 | } 20 | } 21 | 22 | const p1 = new Square(10, 20, 50); 23 | 24 | console.log(p1); 25 | console.log(p1.toString()); 26 | console.log(`${p1}`); 27 | -------------------------------------------------------------------------------- /JavaScript/b-set.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Rect { 4 | toString() { 5 | return `[${this.x}, ${this.y}, ${this.width}, ${this.height}]`; 6 | } 7 | } 8 | 9 | const p1 = { x: 10, y: 20, width: 50, height: 50 }; 10 | Object.setPrototypeOf(p1, Rect.prototype); 11 | //p1.__proto__ = Rect.prototype; 12 | 13 | console.log(p1); 14 | console.log(p1.toString()); 15 | console.log(`${p1}`); 16 | -------------------------------------------------------------------------------- /JavaScript/c-alternative.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Rect(x, y, width, height) { 4 | this.x = x; 5 | this.y = y; 6 | this.width = width; 7 | this.height = height; 8 | this.toString = function() { 9 | return `[${this.x}, ${this.y}, ${this.width}, ${this.height}]`; 10 | }; 11 | } 12 | 13 | const p1 = new Rect(10, 20, 50, 50); 14 | 15 | console.log(p1); 16 | console.log(p1.toString()); 17 | console.log(`${p1}`); 18 | -------------------------------------------------------------------------------- /JavaScript/d-get-set.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Rect { 4 | constructor(x, y, width, height) { 5 | this.x = x; 6 | this.y = y; 7 | this.width = width; 8 | this.height = height; 9 | } 10 | 11 | get area() { 12 | return this.width * this.height; 13 | } 14 | 15 | set side(l) { 16 | this.width = l; 17 | this.height = l; 18 | } 19 | 20 | get side() { 21 | if (this.width !== this.height) throw new Error('not a Square'); 22 | return this.width; 23 | } 24 | } 25 | 26 | const p1 = new Rect(10, 20, 50, 100); 27 | console.log(p1.area); 28 | p1.side = 150; 29 | console.log(p1.side); 30 | console.log(p1.area); 31 | -------------------------------------------------------------------------------- /JavaScript/e-array.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const data = [ 4 | ['Marcus Aurelius', '121-04-26', 'Rome'], 5 | ['Commodus Antoninus', '161-08-31', 'Rome'], 6 | ['Victor Glushkov', '1923-08-24', 'Rostov on Don'], 7 | ['Ibn Arabi', '1165-11-16', 'Murcia'], 8 | ['Mao Zedong', '1893-12-26', 'Shaoshan'], 9 | ['Rene Descartes', '1596-03-31', 'La Haye en Touraine'] 10 | ]; 11 | 12 | class Person { 13 | get name() { 14 | return this[0]; 15 | } 16 | 17 | get birth() { 18 | return this[1]; 19 | } 20 | 21 | get city() { 22 | return this[2]; 23 | } 24 | 25 | get age() { 26 | const difference = new Date() - new Date(this.birth); 27 | return Math.floor(difference / 31536000000); 28 | } 29 | 30 | toString() { 31 | return this.name + ' age is ' + this.age; 32 | } 33 | } 34 | 35 | const query = (person) => ( 36 | person.name !== '' && 37 | person.age > 18 && 38 | person.city === 'Rome' 39 | ); 40 | 41 | console.dir(data); 42 | 43 | data.forEach((person) => { 44 | Object.setPrototypeOf(person, Person.prototype); 45 | // person.__proto__ = Person.prototype 46 | }); 47 | 48 | const res = data.filter(query); 49 | console.log(res.join('\n')); 50 | -------------------------------------------------------------------------------- /JavaScript/f-functor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Functor() {} 4 | 5 | Functor.prototype.method = function() { 6 | console.log('Functor.prototype.method'); 7 | console.dir({ 8 | property: this.property, 9 | method: this.method, 10 | }); 11 | this(); // you can call this as a function 12 | }; 13 | 14 | const factory = () => { 15 | 16 | const functor = function() { 17 | console.log('functor'); 18 | functor.property = 'value'; 19 | console.dir({ 20 | property: functor.property, 21 | method: functor.method, 22 | }); 23 | }; 24 | 25 | Object.setPrototypeOf(functor, Functor.prototype); 26 | return functor; 27 | 28 | }; 29 | 30 | // Usage 31 | 32 | const fn = factory(); 33 | fn(); 34 | fn.method(); 35 | -------------------------------------------------------------------------------- /JavaScript/g-functor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Functor extends Function { 4 | method() { 5 | console.log('Functor.prototype.method'); 6 | console.dir({ 7 | property: this.property, 8 | method: this.method, 9 | }); 10 | this(); // you can call this as a function 11 | } 12 | } 13 | 14 | const factory = () => { 15 | 16 | const functor = function() { 17 | console.log('functor'); 18 | functor.property = 'value'; 19 | console.dir({ 20 | property: functor.property, 21 | method: functor.method, 22 | }); 23 | }; 24 | 25 | Object.setPrototypeOf(functor, Functor.prototype); 26 | return functor; 27 | 28 | }; 29 | 30 | // Usage 31 | 32 | const fn = factory(); 33 | fn(); 34 | fn.method(); 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2021 How.Programming.Works contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prototype 2 | [![Массивы, объекты, классы, прототипы](https://img.youtube.com/vi/VBMGnAPfmsY/0.jpg)](https://www.youtube.com/watch?v=VBMGnAPfmsY) 3 | --------------------------------------------------------------------------------