Всем привет!
Есть несколько мелких вопросов: 1. Почему счетчик, вызванный первым способом, работает корректно, а вторым - нет? let counter = () => { let i = 0; return () => i++; }; let cnt = counter(); console.log(cnt(), cnt(), cnt()); // 0 1 2 console.log((counter())(), (counter())(), (counter())()); // 0 0 0 2. Какой из этих двух вариантов реализации суммирующей функции лучше (выразительнее и быстрее)? let sum = (...arr) => { if (arr.every(item => typeof(item) === "number")) return arr.reduce((acc, cur) => acc + cur, 0) else throw new Error("wrong type"); }; let sum2 = (...arr) => arr.reduce((acc, cur) => { if (typeof(cur) === "number") return acc + cur; else throw new Error("wrong type"); }, 0); 3. Как вообще работает этот код? console.log(20e-1["toString"](2)); // 10 |
1. Во втором случае создаются и сразу вызываются три разных счётчика. Естественно каждый из них находится на нуле.
2. Второй, очевидно: два полных перебора массива против одного. Единственное что else можно убрать, return всё равно прерывает дальнейшее выполнение в случае успеха if. 3. NeX - экспоненциальная запись числа, равносильно: N умножить на 10 в степени X. (т.е. в данном случае: 20 * 10 ** -1 == 2) O["x"]() - вызов метода x объекта O. (отличается от O.x() только тем, что можно использовать строку). N.toString(base) - метод приводящий число N к строке в base системе счисления. (в данном случае двоичной: 2 == 102 ) |
1. Почему не получается выбрать DOM элемент плеера vimeo?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width initial-scale=1 shrink-to-fit=no"> <title>JS</title> </head> <body> <iframe src="https://player.vimeo.com/video/76979871" width="640" height="360" frameborder="0"></iframe> <script src="https://player.vimeo.com/api/player.js"></script> <script> let bar = document.querySelector(".play-bar"); // выбор полосы воспроизведения console.log(bar); // null </script> </body> </html> 2. Есть сайт, у которого на первой странице ссылка на вторую, а на второй - кнопка. Можно ли ввести в консоль на первой странице такой скрипт, чтобы сработал переход по ссылке, а потом клик по кнопке? Нерабочий вариант: let link = document.querySelector("a"); setTimeout(() => { let btn = document.querySelector("button"); btn.click(); }, 5000); link.click(); |
1. iframe - отдельный полноценный документ. В текущем документе существует как элемент только сам iframe. Вам нужно лезть внутрь:
document.querySelector("iframe").onload = function(){ //ждём пока загрузится let bar = this.contentWindow.document.querySelector(".play-bar"); // выбор полосы воспроизведения console.log(bar); }Но работать это будет только если данный код используется под доменом "vimeo.com" или vimeo посылает серверные разрешающие заголовки. В обычном случае это работать не будет: ограничения безопасности. Скорее всего у vimeo есть откртый api для управления. 2. Это возможно при соблюдении двух условий: а) Как и в предыдущем случае, обе страницы должны быть под одним доменом, либо вторая должна посылать рзрешающие заголовки. б) Ссылку открываем в новой вкладке\окне. var win = window.open(link.href); win.onload=function(){ let btn = win.document.querySelector("button"); btn.click(); } |
Пишу библиотеку для работы с классами ES5. Не знаю, как задать имя функции через аргумент метода.
function Classes() { this.createClass = function(className, keys) { this[className] = function(...values) { // здесь как-то надо указать className в качестве имени функции keys.map(key => this[key] = values[keys.indexOf(key)]); }; return this; }; } let classes = new Classes(); classes.createClass("Test", ["a", "b"]); let test = new classes.Test(1, 2); console.log(test); // (anonymous function) {a: 1, b: 2} вместо Test {a: 1, b: 2} Нашел подходящий способ с использованием new Function(), однако не могу в нем разобраться: function renameFunction(name, fn) { return (new Function(`return function (call) { return function ${name} () { return call(this, arguments) }; };`)())(Function.apply.bind(fn)); // здесь какая-то магия со сменой контекста }; let Book = renameFunction("Book", function (title) { this.title = title; }); let book = new Book("Cookbook"); console.log(book); Автор примера выше лихо завернул, можно проще: function rename(name, prop) { return new Function(`return function ${name} (val) { this.${prop} = val; // сначала писал this[${prop}], но это не работало }`); } let Test = rename("Test", "type")(); let test = new Test("js"); console.log(test); // Test {type: "js"} |
Привязка к <button> клавитуры hotkeys
case "w":alert('текст сообщения!');break; без проблем работает
как привязать событие на клик <button id="up">▲</button> по аналогии с нажатием мышью ? Вот пример моего html <!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <title>Р РѕР±РѕС‚</title> <link rel="stylesheet" href="script.css"> <script src="/jquery.js"></script> <script src="/script.js"></script> </head> <body> <div id="wrapper"> <button id="up">▲</button> <button id="left">◄</button> <button id="right">►</button> <button id="down">▼</button> </div> </body> <script src="https://unpkg.com/hotkeys-js/dist/hotkeys.min.js"></script> <script type="text/javascript"> hotkeys('w,s,a,d', function(event,handler) { switch(handler.key){ case "w":document.getElementById('up').click();break; case "s":document.getElementById('down').click();break; case "a":document.getElementById('left').click();break; case "d":document.getElementById('down').click();break; } }); </script> </html> пример script.js var robot = { ports: { up: 6, right: 13, left: 19, down: 26 }, ready: function() { console.log('started'); $('#up, #right, #left, #right, #down').on({ mousedown: robot.start, mouseup: robot.end }); }, start: function() { robot.send(this.id, 1); }, end: function() { robot.send(this.id, 0); }, send: function(port, value) { $.ajax({ type: 'POST', url: '/GPIO/' + robot.ports[port] + '/value/' + value }); } }; $(document).ready(robot.ready); |
Кодер Кой-Команд
<html><head> <title>Koyaanisqatsi Instructions Encoder</title> <style> body { font-size:2em; } input { font-size:1em; width:90%; } </style> <script> function parse_vector(text) { var i, j; var prd = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; var ofs = 0, sign = 1, scan = 0, mode = 0; var codes = [], code, parts, part; var uses, used = 0, using, usings = [], base; if(text.match(/[0-7_]+#/)) mode = +(text.replace(/0/g, "8").replace(/_/g, "9").match(/(\d+)/)[1]), parts = text.replace(/[0-7_]+#/, "").match(/(D\d)|(\+\d*D\d)|([-+]\d+)/gi); else parts = text.match(/(D\d)|(\+\d*\*?D\d)|([-+]?\d+)/gi); if(parts) { if(parts[0].match(/^D\d$/i)) base = +(parts[0].substr(-1)); else if(parts[0].match(/[-+]\d+/)) ofs = +(parts[0].substr(1)), base = 9; for(part of parts) { if(part.match(/\+\d*D\d/i)) { prd[+(part.substr(-1))] += isFinite(parseInt(part.substr(1))) ? parseInt(part.substr(1)) : 1; } else if(part.match(/[-+]\d+/)) { if(part.match(/-\d+/)) sign = -1; ofs = +(part.substr(1)); } } for(i = 0; i <= 9; ++ i) { j = -1; while((prd[i] >> (j + 1)) > 0) ++ j; if(scan < j) scan = j; } usings.push(base); while(scan >= 0) { uses = 0; using = []; i = usings.pop(); code = []; if((prd[i] >> scan) > 0) { prd[i] -= 1 << scan; uses |= 1 << i; code.push(i); if(scan > 0 && ((prd[i] >> (scan - 1)) & 1) > 0) using.push(String(i)); } for(i = 0; i <= 9; ++ i) { if((prd[i] >> scan) > 0) { uses |= 1 << i; code.push(String(i)); if(scan > 0 && ((prd[i] >> (scan - 1)) & 1) > 0) using.push(i); } } if((used & uses) == 0) codes.push(String(base)); codes = codes.concat(code); for(i = 0; i <= 9; ++ i) { if((prd[i] >> scan) > 0) prd[i] -= 1 << scan; } -- scan; used = uses; usings = [base].concat(using); } } i = codes.length; while(-- i >= 0) codes[i] += String(ofs % 10), ofs = (ofs / 10) | 0; while(ofs > 0) codes.unshift(base + String(ofs % 10)), ofs = (ofs / 10) | 0; if(sign < 0) codes.unshift(base + "0"); if(typeof mode != "number") mode = mode ? Number(mode[1]) : 0; while(mode > 0) codes.unshift((mode % 10) + "0", (mode % 10) + "0"), mode = (mode / 10) | 0; return codes.join(" "); } function encode(el) { var alu = { ADD:10, ADC:10, INC:10, DEC:11, SBB:11, SUB:11, AND:12, CLR:12, CON:12, DIS:13, OR:13, SET:13, EOR:14, NOT:14, XOR:14, FOR:15, MOV:15 }; var rex = /(?<Label>[^:;"'`\s]*(?::))?(?:\s)*(?<Instruction>[A-Z]*)(?<Junk>[\d_]*)(?:\s*)(?<Operand1>[^\s,;"'`]*)(?:[,\s]*)?(?<Operand2>[^\s,;"'`]*)?(?:[,\s]*)?(?<Operand3>[^\s,;"'`]*)(?:[,\s]*)?(?:(?:("(?:\\.|.)*?")|('(?:\\.|.)*?')|(`(?:\\.|.)*?`)|[^;"'`]*)*)*(\.*)/i; var part = rex.exec(el.value); var command = (part.groups.Instruction + " " + part.groups.Operand1 + (part[4] ? "," + part[4] + (part[5] ? "," + part[5] : "") : "")).toUpperCase(); var arg = []; var inf = []; var __, _ = []; var encode = "", codes = ""; var prefixes = ""; var junks = ""; var group = part.groups.Instruction .replace(/^(ADC|ADD|AND|CON|DIS|EOR|FOR|MOV|OR|SBB|SUB|XOR)$/i, "ALU") .replace(/^(CLR|DEC|INC|NOT|SET)$/i, "UNA"); var no_carry = (part[2].match(/^(ADD|SUB)$/i)) ? "CE " : ""; if(part[2].toUpperCase() in alu) encode = alu[part[2].toUpperCase()]; for(var j = 4; j <= 6 && j < part.length; ++ j) { if(part[j] && part[j] != "") { if(part[j].match(/^(BC\d|D\d\+)$|[-+]\d+$|^[0-7_]*#/g)) _.push("@"), arg.push(prefixes = parse_vector(part[j].toUpperCase().replace("BC", "D"))); else _.push(part[j]), arg.push(part[j]); } else arg.push(""); } if(part.groups.Junk) junks = part.groups.Junk.replace(/_/g, "9").replace(/0/g, "8").replace(/(\d)/g, "$10 $10 "); inf.push(0); __ = part[2].toUpperCase() + (_.length > 0 ? " " + _.join() : ""); __ = __.search.bind(__); _ = group + (_.length > 0 ? " " + _.join() : ""); _ = _.search.bind(_); switch(0) { case __(/MOV (A0|FLG|FLAGS|PSW),@$/i): codes = "AA A0 :: 0F"; break; case __(/MOV @,(A0|FLG|FLAGS|PSW)$/i): codes = ":: A0"; break; case _(/UNA @$/i): codes = "AA A0 :: 0_"; break; case _(/EXI$/i): codes = "AA A0 0E"; break; case _(/SWP @,D[0-9]$/i): codes = "AY A0 :: yF"; break; case _(/SWP D[0-9],@$/i): codes = "AX A0 :: xF"; break; case __(/MOV @,([ABCD][0-9])$/i): codes = ":: Yy"; break; case _(/ALU @,D[0-9]$/i): codes = "AY A0 ~:: y_"; break; case _(/INF D[0-9]$/i): codes = "AX A0 #xF"; break; case _(/EHI|EI|STI$/i): codes = "AD A0 #0C"; break; case _(/UNA D[0-9]$/i): codes = "AD A0 #x_"; break; case _(/SWP (A[1-9]|[BC][0-9]),@$/i): codes = "AX A0 :: xF"; break; case _(/SWP @,(A[1-9]|[BC][0-9])$/i): codes = "AY A0 :: yF"; break; case _(/ALU @,(A[1-9]|[BC][0-9])$/i): codes = "AY A0 ~:: y_"; break; case __(/MOV (A0|FLG|FLAGS|PSW),(A[1-9]|[BC][0-9])$/i): codes = "AY A0 #yF"; break; case _(/UNA (A[1-9]|[BC][0-9])$/i): codes = "AX A0 #x_"; break; case _(/ALU D[0-9],@$/i): codes = "XA Xx ~:: 0_"; break; case _(/OUF D[0-9]$/i): codes = "XA Xx #0F"; break; case _(/UNA D[0-9],CF$/i): codes = "XA Xx #0_"; break; case _(/ALU (A[1-9]|[BC][0-9]),@$/i): codes = "XA Xx ~:: 0_"; break; case __(/MOV (A[1-9]|[BC][0-9]),(A0|FLG|FLAGS|PSW)$/i): codes = "XA Xx #0F"; break; case _(/UNA (A[1-9]|[BC][0-9]),CF$/i): codes = "XA Xx #0_"; break; case _(/LEA D[0-9],@$$/i): codes = "XX Xx :: xF"; break; case _(/ORD @,(A[1-9]|[BCD][0-9]),(A[1-9]|[BCD][0-9])$$/i): codes = "YZ Yy :: zF"; break; case _(/ALU D[0-9],@,D[0-9]$/i): codes = "XZ Xx :: z_"; break; case _(/ALU D[0-9],D[0-9]$/i): codes = "XY Xx #y_"; break; case _(/LEX (A[1-9]|[BCD][0-9]),@,(A[1-9]|[BC][0-9])$$/i): codes = "XZ Xx :: zF"; break; case _(/ALU D[0-9],@,(A[1-9]|[BC][0-9])$/i): codes = "XZ Xx :: z_"; break; case _(/OUT D[0-9],(A[1-9]|[BC][0-9])$/i): codes = "XY Xx #yF"; break; case _(/ALU D[0-9],(A[1-9]|[BC][0-9])$/i): codes = "XY Xx ~#y_"; break; case _(/ALU (A[1-9]|[BC][0-9]),@,D[0-9]$/i): codes = "XZ Xx ~:: z_"; break; case _(/IN (A[1-9]|[BC][0-9]),D[0-9]$/i): codes = "XY Xx #yF"; break; case _(/ALU (A[1-9]|[BC][0-9]),D[0-9]$/i): codes = "XY Xx ~#y_"; break; case _(/ALU (A[1-9]|[BC][0-9]),@,(A[1-9]|[BC][0-9])$/i): codes = "XZ Xx ~:: z_"; break; case _(/ALU (A[1-9]|[BC][0-9]),(A[1-9]|[BC][0-9])$/i): codes = "XY Xx ~#y_"; break; case _(/ALU R[0-9]$/i): codes = "~#x_"; break; case _(/ALU R,@,R[0-9]$/i): codes = "~:: z_"; break; case _(/REG [ABCD][0-9],[ABCD][0-9],[ABCD][0-9]$/i): codes = "#Xx #Yy #Zz"; break; case _(/REG [ABCD][0-9],[ABCD][0-9]$/i): codes = "#Xx #Yy"; break; case _(/REG [ABCD][0-9]$/i): codes = "#Xx"; break; case _(/ARG [ABCD][0-9],[ABCD][0-9]$/i): codes = "#XY Xx Yy"; break; case _(/ARG [ABCD][0-9],[ABCD]$/i): codes = "#XY Xx"; break; case _(/ARG [ABCD],[ABCD]$/i): codes = "#XY"; break; case _(/BRK|HA?LT$/i): codes = "#00"; break; case _(/(HA?LT|JU?MP) @$/i): codes = ":: 00"; break; case __(/(CLR|ERA) [ABCD]F$/i): codes = "#XE"; break; case __(/(CMP|FLP|INV|NOT) [ABCD]F$/i): codes = "#Xx"; break; case __(/SET [ABCD]F$/i): codes = "#XE #Xx"; break; case _(/(BRK|HA?LT|JU?MP|LOOP|RET) @,[ABCD]F$/i): codes = ":: Yy"; break; case _(/DO @,[ABCD]F$/i): codes = ":: YE"; break; case _(/(BRK|HA?LT|JU?MP|LOOP|RET) @,[ABCD]F,[ABCD]F$/i): codes = ":: YZ"; break; case _(/(BRK|HA?LT|JU?MP|LOOP|RET) @,[ABCD]F,[ABCD]E$/i): codes = "ZF :: YZ ZF"; break; case _(/(BRK|HA?LT|JU?MP|LOOP|RET) @,[ABCD]E,[ABCD]F$/i): codes = "YF :: YZ YF"; break; case _(/(BRK|HA?LT|JU?MP|LOOP|RET) @,[ABCD]E,[ABCD]E$/i): codes = "YF ZF :: YZ ZF YF"; break; } if(codes != "") { codes = codes .replace(/::/g, (junks + prefixes).trim()) .replace(/#/g, junks) .replace(/~/g, no_carry) .replace(/_/g, encode.toString(16)) .replace(/X/g, arg[0].charAt(0)) .replace(/x/g, arg[0].charAt(1)) .replace(/Y/g, arg[1].charAt(0)) .replace(/y/g, arg[1].charAt(1)) .replace(/Z/g, arg[2].charAt(0)) .replace(/z/g, arg[2].charAt(1)) .toUpperCase() .split(/\s/); } else codes = ["Error"]; document.querySelector(el.dataset.for).textContent = codes.join(" "); } </script> </head> <body> <input type=text data-for='#Dump' placeholder='Type assembly at here' list=Samples onchange='encode(this)' spellcheck=false> <pre id=Dump></pre> <datalist id=Samples> <option value='JUMP #D8+65536'>Jump [BC<sub>8</sub>+65536]</option> <option value='SET CF'>Set Carry Flag</option> <option value='INF D5'>Query Information about Port #5 and set Flags ZF/CF/OF/SF</option> <option value='IN A4,D5'>Input data from Port #5 to Register A4</option> <option value='ADC A7,C3'>Add C<sub>3</sub> to A<sub>7</sub> with Carry</option> <option value='ADD86 A7,C3'>Add C<sub>3</sub> to A<sub>7</sub> in mode #86</option> <option value='INC A7'>Increment Register A<sub>7</sub></option> <option value='SBB A1,#D2'>Subtract from Register A<sub>1</sub> data from Memory cell pointed by D<sub>2</sub> with Borrow</option> <option value='SUB #D2,A1'>Subtract from Memory cell pointed by D<sub>2</sub> the Register A<sub>1</sub></option> <option value='DEC 7#D2'>Decrement Memory cell pointed by D<sub>2</sub> in mode #7</option> <option value='LEA D1,#D2+3D3+4D4+56789'>Load Effective Address: Like x86-LEA</option> <option value='LEX C1,#D2+3D3+4D4+56789,B0'>Lexical transform: Like x86-XLAT</option> <option value='ORD #D1+234,D5,D6'>Put in Order Data from Memory and Register pairs BC<sub>6</sub> and set to BC<sub>5</sub> the average</option> <option value='ORD #D1+234,C5,B6'>Put in Order Data from Memory and Register pairs BC<sub>6</sub> and set to C<sub>5</sub> the average</option> </datalist> </body> |
Цитата:
Number.prototype.__defineGetter__ ("test", function(){ this.TEST = 'Test'; return this; } ); Number.prototype.__defineGetter__ ("Show", function(){ alert(this.TEST); return this; } ); const a = new Number() alert((a.test).Show) У стрелочных функций есть особенность работы с this... |
Симуляция микросхемы К155ИЕ8 в графике
<html> <head> <title>SN7497 simulation & Line drawing</title> <script> var hCnv; var cnt97; var set97; function sn7497() { cnt97 = (cnt97 + 1) & 0x3F; return (set97 & 0x20) > 0 && (cnt97 & 0x01) == 0x01 ? 1 : (set97 & 0x10) > 0 && (cnt97 & 0x03) == 0x02 ? 1 : (set97 & 0x08) > 0 && (cnt97 & 0x07) == 0x04 ? 1 : (set97 & 0x04) > 0 && (cnt97 & 0x0F) == 0x08 ? 1 : (set97 & 0x02) > 0 && (cnt97 & 0x1F) == 0x10 ? 1 : (set97 & 0x01) > 0 && (cnt97 & 0x3F) == 0x20 ? 1 : 0; } function main() { hCnv = document.querySelector("canvas").getContext("2d"); cnt97 = 0; set97 = 0; loop(); } function loop() { var x = 0, y, z; hCnv.fillStyle = "blue"; if(cnt97 > 0 || set97 > 0) hCnv.fillRect(0, 0, hCnv.canvas.width / 2, hCnv.canvas.height); else hCnv.fillRect(0, 0, hCnv.canvas.width, hCnv.canvas.height); hCnv.fillStyle = "yellow"; for(y = 0; y <= 64; ++ y) { hCnv.fillRect(x * 4, y * 4, 4, 4); z = sn7497(); x += z; if(z) hCnv.fillRect(256 + cnt97 * 4, set97 * 4, 2, 3); } set97 ++; if(set97 > 63) set97 = 1; setTimeout(loop, 50); hCnv.fillStyle = "blue"; hCnv.fillRect(256, set97 * 4, 256, 3); } </script> </head> <body onload='main()'> <canvas width=512 height=256></canvas> </body> |
Alikberov,
вам влом написать function? |
Часовой пояс GMT +3, время: 06:00. |