├── .vscode ├── launch.json └── settings.json ├── README.md ├── demo.html ├── demo.js └── utils.js /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceFolder}\\utils.js" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.glyphMargin": false, 3 | "editor.folding": false, 4 | "scm.diffDecorations": "none" 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript Objects, Prototypes and Classes 2 | This is the demo code for the Pluralsight course at https://app.pluralsight.com/courses/javascript-objects-prototypes-and-classes 3 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | (function() { 3 | 4 | display('Hello World'); 5 | 6 | })(); -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | let domActionBuffer = []; 5 | let flushTimeout; 6 | 7 | window.display = function () { 8 | if (!flushTimeout) flushTimeout = setTimeout(flushDomQueue, 100); 9 | 10 | domActionBuffer.push({ action: 'display', arguments: arguments }); 11 | }; 12 | 13 | window.displayRegexArray = function () { 14 | if (!flushTimeout) flushTimeout = setTimeout(flushDomQueue, 100); 15 | 16 | domActionBuffer.push({ action: 'displayRegexArray', arguments: arguments }); 17 | }; 18 | 19 | window.clearDisplay = function () { 20 | if (!flushTimeout) flushTimeout = setTimeout(flushDomQueue, 100); 21 | 22 | domActionBuffer.push({ action: 'clearDisplay' }); 23 | }; 24 | 25 | function doClearDisplay() { 26 | let outputTag = document.getElementById('output'); 27 | while (outputTag.firstChild) { 28 | outputTag.removeChild(outputTag.firstChild); 29 | } 30 | } 31 | 32 | function doDisplay() { 33 | for (var i = 0; i < arguments.length; i++) { 34 | if (typeof arguments[i] === 'object') displayObject(arguments[i], false); 35 | else displayValue(arguments[i], true); 36 | } 37 | } 38 | 39 | function doDisplayRegexArray() { 40 | displayObject(arguments[0], true) 41 | } 42 | 43 | function flushDomQueue() { 44 | flushTimeout = null; 45 | 46 | if (domActionBuffer.length === 0) return; 47 | 48 | const domActions = [...domActionBuffer]; 49 | domActionBuffer = []; 50 | for (let domAction of domActions) { 51 | switch (domAction.action) { 52 | case 'display': 53 | doDisplay(...domAction.arguments); 54 | break; 55 | case 'displayRegexArray': 56 | doDisplayRegexArray(...domAction.arguments); 57 | break; 58 | case 'clearDisplay': 59 | doClearDisplay(); 60 | break; 61 | } 62 | } 63 | } 64 | 65 | function displayValue(value, addMargin, addPadding) { 66 | let outputTag = document.getElementById('output'); 67 | let div = document.createElement('div'); 68 | div.innerHTML = value; 69 | if (addMargin) div.style.marginBottom = '30px'; 70 | if (addPadding) div.style.paddingLeft = '30px'; 71 | 72 | outputTag.appendChild(div); 73 | } 74 | 75 | function displayObject(object, regexArray) { 76 | if (object == null) return displayValue('null'); 77 | if (getTypeName(object) === 'Array' && !regexArray) { 78 | let appendedArrayValues = object.reduce((acc, cur) => acc+=cur+',', '') 79 | if (appendedArrayValues.length > 0) 80 | appendedArrayValues = appendedArrayValues.substr(0, appendedArrayValues.length - 1) 81 | displayValue('[' + appendedArrayValues + ']') 82 | if (Object.keys(object).length > object.length) { 83 | displayValue(' ') 84 | displayValue('Additional array properties:') 85 | } 86 | for (let propertyName in object) 87 | { 88 | if (!Number.isInteger(+propertyName) && object[propertyName] !== undefined) 89 | displayValue('  ' + propertyName + ": " + object[propertyName]) 90 | else if (typeof object[propertyName] === 'object', false) { 91 | return displayObject() 92 | } 93 | } 94 | return 95 | } 96 | 97 | displayValue(getTypeName(object) + ' {'); 98 | for (var propertyName in object) { 99 | if (typeof object[propertyName] === 'object', false) 100 | displayObject(object[propertyName]) 101 | else if (propertyName != 'constructor' && (!regexArray || object[propertyName] !== undefined)) { 102 | let prefix = Number.isInteger(+propertyName) && regexArray ? '[' : '' 103 | let suffix = Number.isInteger(+propertyName) && regexArray ? ']' : '' 104 | displayValue(prefix + propertyName + suffix + ': ' + object[propertyName], false, true); 105 | } 106 | } 107 | displayValue('}', true); 108 | } 109 | 110 | function getTypeName(object) { 111 | return object.constructor.name; 112 | } 113 | 114 | let reloadJS = () => { 115 | let oldScriptTag = document.getElementById('script'); 116 | 117 | let newScriptTag = document.createElement('script'); 118 | newScriptTag.id = 'script'; 119 | newScriptTag.src = 'demo.js'; 120 | newScriptTag.textContent = '//script'; 121 | var body = document.getElementsByTagName('body')[0]; 122 | 123 | oldScriptTag.remove(); 124 | 125 | clearDisplay(); 126 | body.appendChild(newScriptTag); 127 | }; 128 | 129 | setInterval(reloadJS, 1000); 130 | --------------------------------------------------------------------------------