diff --git a/js/async.js b/js/JS-async.md similarity index 64% rename from js/async.js rename to js/JS-async.md index b0aad05..564694f 100644 --- a/js/async.js +++ b/js/JS-async.md @@ -1,23 +1,27 @@ -// https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf -// https://www.youtube.com/watch?v=8aGhZQkoFbQ +# Async in JavaScript -///////////////////////////////////////////////////////////////////////// -// Is JS one- or multiple-threaded? How are async operations done in JS? +JavaScript is single-threaded, non-blocking, synchronous language. It uses browser's event loop to handle async operations. -///////////////////////////////////////////////////////////////////////// + + + + +```text // what is call stack (execution stack)? -/* + call stack is a data structure which records basically where in the program we are. It is part of JS engine (V8 in Chrome). Each entry in the call stack is called 'Stack Frame' (visible in stack trace). Stack overflow may happen using infinite recursion. (aka while true) -*/ -///////////////////////////////////////////////////////////////////////// +``` + +```text // what is event loop, how does it work (message queue)? -/* - https://learn.javascript.ru/event-loop - good explanation article - https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model - specification details + + - good explanation article + - specification details + event loop constantly monitors msg queue (for tasks) and call stack and pushes 1st cb onto it when its empty There are 2 queues: 'macro-tasks' (tasks) - timers, i/o @@ -30,62 +34,70 @@ Add new macro-task: setTimeout(f) Add new micro-task: queueMicrotask(f) iframe has its own js process -*/ -///////////////////////////////////////////////////////////////////////// +``` + +```text // what are async operations in JS? -/* + Web APIs: timers (cb run in main thread). Exact delay is not guaranteed, run when empty call stack. AJAX (XHR, fetch) DOM Promises - */ -///////////////////////////////////////////////////////////////////////// +``` + +```text // TODO // promise vs observable +``` -///////////////////////////////////////////////////////////////////////// +```text // async & await -/* + async keyword tells a function to return a promice instead of a value. await keyword used to call a func that returns a promise, can be used in async func only. It blocks execution of code until promise fulfills (sync operation) used to wait for a response in async functions. -*/ -///////////////////////////////////////////////////////////////////////// +``` + +```text // promises vs callbacks? -/* + Callback is old approach, used for sync (loops) & async (dom) operations, may run into callback hell. - Promises done for async operations, return obj, can be chained with multiple .then() instead of cb hell, + Promises done for async operations, return obj, can be chained with multiple .then() instead of cb hell, run in order, better error handling, avoid inversion of control. -*/ -///////////////////////////////////////////////////////////////////////// +``` + +```text // What is promise? -/* + Promise is an object representing intermediate state of async operation. Used for async operations only, return only 1 result var promise = new Promise((resolve, reject) => {.....}); promise.then(onFulfilled, onRejected).catch(onRejected).finally(onFinish); -*/ -///////////////////////////////////////////////////////////////////////// +``` + +```text // What is Web Worker, why to use it? new Worker('worker.js'); -/* used to run code in separate thread, they can exchange messages with main thread, but they have own event queue, they don't have access to the DOM, so mainly used for calculations, they can use several processor cores */ +/*used to run code in separate thread, they can exchange messages with main thread, but they have own event queue, they don't have access to the DOM, so mainly used for calculations, they can use several processor cores*/ +``` -///////////////////////////////////////////////////////////////////////// +```js // What does this construction mean, why to use it with 0 delay? Will it run strictly in 0 ms? setTimeout(f, 0); /* run func in the end of a call stack (reasons: finish script, loop, DOM render etc.), may run later then 0 ms (4-10) */ +``` -///////////////////////////////////////////////////////////////////////// +```js // What is the order of logs? console.log(1); setTimeout(function() { @@ -97,8 +109,9 @@ setTimeout(function() { }, 0); console.log(5); // 1, 5, 4, 3, 2 +``` -///////////////////////////////////////////////////////////////////////// +```js // what output and why? How to fix? for (var i = 0; i < 3; i++) { setTimeout(function() { @@ -116,3 +129,4 @@ for (var i = 0; i < 3; i++) { ); } // 0, 1, 2 //Fix 3: use forEach // [1,2,3,4,5].forEach(function (value, i) {...}) +``` diff --git a/js/js-general.js b/js/JS-general.md similarity index 65% rename from js/js-general.js rename to js/JS-general.md index 4ef96d4..996a41a 100644 --- a/js/js-general.js +++ b/js/JS-general.md @@ -1,114 +1,106 @@ -.//Ctrl+K+0 - unfold +# JavaScript general info -{/* Interview questions links: +TODO: review and update general docs - awesome-interview-questions: - https://github.com/MaximAbramchuck/awesome-interview-questions +## Interview questions links - Front-end-Developer-Interview-Questions: - https://github.com/h5bp/Front-end-Developer-Interview-Questions +- [awesome-interview-questions](https://github.com/MaximAbramchuck/awesome-interview-questions) +- [Front-end-Developer-Interview-Questions](https://github.com/h5bp/Front-end-Developer-Interview-Questions) +- [21 Essential JavaScript Interview Questions](https://www.codementor.io/@nihantanu/21-essential-javascript-tech-interview-practice-questions-answers-du107p62z) +- [37 Essential JavaScript Interview Questions (TopTal)](https://www.toptal.com/javascript/interview-questions) +- [JS: Basics and Tricky Questions](http://www.thatjsdude.com/interview/js2.html) - 21 Essential JavaScript Interview Questions: - https://www.codementor.io/@nihantanu/21-essential-javascript-tech-interview-practice-questions-answers-du107p62z +## GENERAL QUESTIONS - 37 Essential JavaScript Interview Questions (TopTal) - https://www.toptal.com/javascript/interview-questions +- general: + - event bubbling / event capturing (trickling) + - mutable vs immutable - JS: Basics and Tricky Questions: - http://www.thatjsdude.com/interview/js2.html +- JS core: + - data types + - scope / lexical environment + - closure + - hoisting + - prototypes + - this + - new O() + - call, apply, bind + - obj.func() + - func() + - () => + - async + - single threaded + - JS Engine / JS execution context + - heal, call stack + - web api (timers, XHR, DOM etc.) + - event loop, callback queue + - promise, micro-tasks -*/ -} +- function, class + - class vs function + - pure function + - first-class functions + - IIFE / module pattern + - static -{ /* GENERAL QUESTIONS - - general: - - event bubbling / event capturing (trickling) - - mutable vs immutable - - js core: - - data types - - scope / lexical environment - - closure - - hoisting - - prototypes - - this - - new O() - - call, apply, bind - - obj.func() - - func() - - () => - - async - - single threaded - - JS Engine / JS execution context - - heal, call stack - - web api (timers, XHR, DOM etc.) - - event loop, callback queue - - promice, microtasks - - function, class - - class vs function - - pure function - - first-class functions - - IIFE / module pattern - - static - - DOM manipulations - - */ -} +- DOM manipulations -{ // Two main programming paradigms in JavaScript, its difference -/* - - OOP (SOLID, classes, prototypal inheritance) - OOP pros: easy to understand, use imperative over declarative style, reads more straight-forward - OOP cons: depends on shared state, may lead to race condition - - - Functional programming (first class funtions, closures, ) - FP pros: no shared state or side-effects leads to no bugs related to race conditions, easy to recompose functions - for more reusable code. Things don't compete for shared resources. Object composition over class inheritance. - FP cons: code may lock less concrete, more abstractly specified, may be comfusing for those who come from OOP -*/ -} +```text +Q: Two main programming paradigms in JavaScript, its difference -{ // What is functional programming? - /* - It is a paradigm to provide programs by composing functions and avoid shared atate & mutable data. - It is one of two essential concepts in JavaScript (OOP as another one). - Features: pure functions, no side effects, function composition, first-class func, HOF, func as arguments/values, Immutability - Other functional langs: Lisp, Haskell, Erlang, Closure, F Sharp. - */ -} +A: + +- OOP (SOLID, classes, prototypal inheritance) + - pros: easy to understand, use imperative over declarative style, reads more straight-forward + - cons: depends on shared state, may lead to race condition + +- Functional programming (first class functions, closures) + - pros: no shared state or side-effects leads to no bugs related to race conditions, easy to recompose functions for more reusable code. Things don't compete for shared resources. Object composition over class inheritance. + - cons: code may lock less concrete, more abstractly specified, may be confusing for those who come from OOP +``` + +```text +Q: What is functional programming? + +A: It is a paradigm to provide programs by composing functions and avoid shared state & mutable data. It is one of two essential concepts in JavaScript (OOP as another one). -{ // Classical vs prototypal inheritance? - /* - Class Inheritance: instances inherit from classes, and create tight coupling, hierarchical relationships. +Features: pure functions, no side effects, function composition, first-class func, HOF, func as arguments/values, Immutability + +Other functional langs: Lisp, Haskell, Erlang, Closure, F Sharp. +``` + +```text +Q: Classical vs prototypal inheritance? + +A: Class Inheritance: instances inherit from classes, and create tight coupling, hierarchical relationships. Instances are typically instantiated via constructor functions with the `new` keyword. Class inheritance may or may not use the `class` keyword from ES6. Prototypal Inheritance: instances inherit directly from other objects. Instances are typically instantiated via factory functions or `Object.create()`. Instances may be composed from many different objects, allowing for easy selective inheritance. Concatenative inheritance, prototype delegation, functional inheritance, object composition. Delegation (prototype chain), Concatenative (mixins, Object.assign()), Functional (create closure for private state/encapsulation) - */ -} +``` -{ // Describe what means 'object composition over class inheritance' - /* - https://www.youtube.com/watch?v=wfMtDGfHWpA&feature=emb_title +```text +Q: Object composition over Class inheritance' - It means that code reuse should be achieved by assembling smaller units of functionality into new objects instead - of inheriting from classes and creating object taxonomies. In other words, use can-do, has-a, or uses-a - relationships instead of is-a relationships. +A: + - Avoid class hierarchies, avoid brittle base class problem (changes in a base class may lead to problem in child - classes), avoid tight coupling, avoid forced is-a relationship, avoid gorilla-banana problem (get entire jungle - but not simple banana), makes code more flexible - */ -} + It means that code reuse should be achieved by assembling smaller units of functionality into new objects instead + of inheriting from classes and creating object taxonomies. In other words, use can-do, has-a, or uses-a + relationships instead of is-a relationships. + + Avoid class hierarchies, avoid brittle base class problem (changes in a base class may lead to problem in child + classes), avoid tight coupling, avoid forced is-a relationship, avoid gorilla-banana problem (get entire jungle + but not simple banana), makes code more flexible +``` + +```text +Q: ES6(2015)+ features -{ // ES6+ features https://github.com/lukehoban/es6features - /* +A: ES6 (2015): () => @@ -165,23 +157,23 @@ Object.fromEntries: reverse operation from Object.entries String.trimStart() & String.trimEnd(): Remove extra spaces in a string Optional Catch binding: remove the need to add a param to the catch (Now you can do } catch {instead of } catch(e) { - Function.toString has been revisited to have a consistent behaviour + Function.toString has been revisited to have a consistent behavior Symbol Description BigInt — arbitrary large numbers (Thanks @redeyes2015 for correction) Improvement on Unicode support for JSON.stringify() Array.sort now retains order if keys are equal Make JavaScript a superset of JSON - */ -} +``` -{ // 'use strict' - /* - Used to enforce stricter parsing and error handling of a js code at a runtime. - Errors that would normally be ignored would generate errors, or throw exceptions - */ -} +```text +Q: 'use strict' + +A: Used to enforce stricter parsing and error handling of a js code at a runtime. Errors that would normally be ignored would generate errors, or throw exceptions +``` + +```text +Q: Data Types -{ // Data Types // Primitives, value type undefined: typeof instance === 'undefined'; Boolean: typeof instance === 'boolean'; @@ -203,8 +195,11 @@ new Date(); Function: typeof instance === 'function'; // derived from Object } +``` + +```text +Q: Comparison, Castings, find Data Type -{ // Comparison, Castings, find Data Type // == vs === // cast string to number (if wrong input, might return NaN) '10' * 1 + // the fastest @@ -249,100 +244,119 @@ (1 == 1) == 1; // true (1 === 1) === 1; // false 0.1 + 0.2 == 0.3; // false (could be true, floating value issue) +``` + +```text +Q: Monolithic vs Microservice architecture? + + Monolithic: + App written as one unit of code, whose components designed to work together, sharing same memory and resources. + Pros: cover large number of cross-cutting concerns, shared memory process are faster then inter-process communication (IPC) + Cons: tightly coupled, difficult to isolate services (scalability, maintainability problem), harder to understand due to deps, side-effects + + Microservice: + App consists of several smaller independent apps that run in their own memory and space and scale independently from + each other across potentially many separate machines + Pros: better organized, separation of concern, easy to recompose, reconfigure, scale only what you need. Perform + and scale better in long run. + Cons: shared middleware, more devOps job needed, higher initial cost } +``` -{ //Monolithic vs Microservice architecture? - /* - Monolithic: - App written as one unit of code, whose components designed to work together, sharing same memory and resources. - Pros: cover large number of cross-cutting concerns, shared memory process are faster then inter-process communication (IPC) - Cons: tightly coupled, difficult to isolate services (scalability, maintainability problem), harder to understand due to deps, side-effects - - Microservice: - App consists of several smaller independent apps that run in thei own memory and space and scale independantly from - each other across potentially many separate machines - Pros: better organized, separation of concern, easy to recompose, reconfigure, scale only what you need. Perform - and scale better in long run. - Cons: shared middleware, more devOps job needed, higher initial cost - */ -} - -{ // WHAT OUTPUT & WHY ? +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? // NFE (Named Function Expression) var foo = function bar(){ return 12; }; typeof bar(); // ReferenceError: bar is not defined, // to fix - check type of assigned variable instead, or use function declaration and check func type +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var z = 1, y = z = typeof y; // here associativity of the assignment is Right to Left console.log(y); // undefined +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var trees = ["redwood","bay","cedar","oak"]; delete trees[2]; console.log(trees.length); // 4 console.log(trees); // ["redwood","bay", empty ,"oak"] console.log(trees[2]); // undefined +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var output = (function(x){ delete x; // delete won't work here because it deletes only obj props, but not variables (neither local nor global) return x; })(0); // 0 +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var x = { foo : 1}; var output = (function(){ delete x.foo; return x.foo; })(); console.log(output); // undefined +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? console.log( (function f(n) { return n > 1 ? n * f(n - 1) : n; })(10) ); // 10! +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var foo = new Object(); var bar = new Object(); var map = new Object(); map[foo] = 'foo'; // map = {[object Object]: 'foo'} map[bar] = 'bar'; // map = {[object Object]: 'bar'} console.log(map[foo]); // bar +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var a = {}, b = { key: 'b' }, c = { key: 'c' }; a[b] = 123; // a = {[object Object]: 123} a[c] = 456; // a = {[object Object]: 456} console.log(a[b]); // {[object Object]: 456} +``` +```js +// WHAT OUTPUT & WHY ? -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? var arr1 = 'john'.split(''); var arr2 = arr1.reverse(); var arr3 = 'jones'.split(''); arr2.push(arr3); console.log('array 1: length=' + arr1.length + ' last=' + arr1.slice(-1)); // "array 1: length=5 last=j,o,n,e,s" console.log('array 2: length=' + arr2.length + ' last=' + arr2.slice(-1)); // "array 2: length=5 last=j,o,n,e,s" +``` - - -///////////////////////////////////////////////// WHAT OUTPUT & WHY ? RECURSION +```js +// WHAT OUTPUT & WHY ? +// RECURSION // how to fix? + let counter = 0; (function doJob() { if (counter > 3) return 'done!'; @@ -350,17 +364,18 @@ let counter = 0; doJob(); // fix: return doJob() }()) // undefined, because only last function in a stack returned value, rest just finished -// bubble up returned value, return recurcive call but not just call +// bubble up returned value, return recursive call but not just call +``` -} - - -{ // COMMON TASKS +## Common tasks +```js { // reverse string '0123456789'.split('').reverse().join(''); } +``` +```js { // check if input string is palindrome function isPalindrome(str) { var strAlphaNumeric = str.replace(/\W/g, '').toLowerCase(); @@ -370,14 +385,18 @@ let counter = 0; console.log(isPalindrome('levels')); // logs 'false' console.log(isPalindrome('A car, a man, a maraca')); // logs 'true' } +``` +```js { // how to empty an array? array = []; array.length = 0; while(array.length > 0) { array.pop(); } array.splice(0, array.length) } +``` +```js { // how to remove duplicates from array? // solution #1 (Fast #1) @@ -411,11 +430,15 @@ let counter = 0; return unique; } } +``` +```js { // find SUM of all array elements [1, 2, 3, 4, 5, 6, 7, 8, 9].reduce((acc, current) => acc + current, 0); } +``` +```js { // create func that will give such result (relates to Partial Applied function) var addSix = createBase(6); addSix(10); // returns 16 // closure @@ -430,10 +453,12 @@ let counter = 0; }; } - // solution #2 (usine arrow f) + // solution #2 (using arrow fn) const createBase = base => n => base + n; // second function is a closure. } +``` +```js { // create func that will give such result add(2, 5); // 7 add(2)(5); // 7 // closure @@ -441,11 +466,13 @@ let counter = 0; // solution const add = (a, b) => (b ? a + b : b => a + b); } +``` +```js { // how to copy/clone object || arr // Shallow copy - (/* Object.assign - shallow copy */) => { + (/*Object.assign - shallow copy*/) => { let a = { x: { z: 1 }, y: 2 }; let b = Object.assign({}, a); b.x.z = 0; @@ -453,7 +480,7 @@ let counter = 0; console.log(JSON.stringify(b)); // {"x":{"z":0},"y":2} }; - (/* ... - shallow copy */) => { + (/*... - shallow copy*/) => { let a = { x: { z: 1 }, y: 2 }; let b = { ...a }; b.x.z = 0; @@ -461,7 +488,7 @@ let counter = 0; console.log(JSON.stringify(b)); // {"x":{"z":0},"y":2} }; - (/* Array.from(arr) */) => { + (/*Array.from(arr)*/) => { let a = [{ x: 1, y: 2, z: 3 }]; let b = Array.from(a); b[0].x = 0; @@ -471,7 +498,7 @@ let counter = 0; // Deep copy - (/* Solution 3: converting to JSON and back (be careful, source should be JSON safe) */) => { + (/*Solution 3: converting to JSON and back (be careful, source should be JSON safe)*/) => { let a = [{ x: { z: 1 }, y: 2 }]; let b = JSON.parse(JSON.stringify(a)); b[0].x.z = 0; @@ -479,7 +506,7 @@ let counter = 0; console.log(JSON.stringify(b)); // [{"x":{"z":0},"y":2}] - only copy changed }; - (/* Solution 4: deep copy using iteration */) => { + (/*Solution 4: deep copy using iteration*/) => { function iterationCopy(src) { let target = {}; for (let prop in src) { @@ -508,9 +535,10 @@ let counter = 0; // deep copy array var newArr = JSON.parse(JSON.stringify(arr)); }; +``` +```js { // pull data from public API and show it on FE // TODO }; - -} \ No newline at end of file +``` diff --git a/js/JS-prototype.md b/js/JS-prototype.md new file mode 100644 index 0000000..cb7b9a8 --- /dev/null +++ b/js/JS-prototype.md @@ -0,0 +1,71 @@ +# Object Prototypes + +Prototypes are the mechanism by which JavaScript objects inherit features from one another. In JavaScript, each object has a prototype, which is another object that it uses as a fallback source of properties. When an object gets a request for a property that it does not have, its prototype will be searched for the property, then the prototype’s prototype, and so on. + +## Questions + +```js +// Q: write your own func that will duplicate string n times + +'a'.duplicate(3); // should return 'aaa' + +String.prototype.duplicate = function(n) { + // return Array(n + 1).join(this); + return this.repeat(n); +}; +``` + +```text +Q: Describe inheritance and the prototype chain in JavaScript. Give an example. + +A: Each object has its prototype, so there is a prototype chain, with null in the end. Used for inheritance simulation. When we look for a property that object doesn't have, it traverse all proto chain to find it. +``` + +```text +Q: How to assign a prototype to an object? + +A: Use `Object.create(proto)` or set `__proto__` property. +``` + +```js +// Q: what output and why? + +var product = { category: 'fastfood' }; +var burger = Object.create(product); + +burger.category = 'drinks'; +delete burger.category; + +console.log(burger.category); // 5 - because it is still in proto +``` + +```js +// Q: describe different ways of creating an objects + +// proto chain: null +var o = Object.create(null); + +// proto chain: Object.prototype -> null +var o = { id: 5, name: 'Elvis' }; + +// proto chain: Array.prototype -> Object.prototype -> null +var o = ['Elvis']; + +function F() {} + +// proto chain: F.prototype -> Object.prototype -> null +var o = new F(); +``` + +```js +// Q: what output and why? how to fix? + +for (var i = 0; i < 3; i++) { + setTimeout(function() { + console.warn(i); + }); +} + +// 3, 3, 3 - because warn calls after the end of the loop, +// can be fixed by using 'let', 'forEach', of IIFE closure (i => {..})(i) +``` diff --git a/js/JS-this.md b/js/JS-this.md new file mode 100644 index 0000000..932b977 --- /dev/null +++ b/js/JS-this.md @@ -0,0 +1,124 @@ +# `this` keyword in JavaScript + +`this` is a keyword in JavaScript that refers to the object. It has different values depending on how the functions is called. + +- `fn();` + - `this` is `window` in browser or `global` in Node, or `undefined` in browser if strict mode. +- `obj.fn();` + - `this` is `obj`. +- `fn().call({ a: 1 }, 5, 7);` + - `this` is `{ a: 1 }`. Ignored in arrow fn. +- `fn().apply({ a: 1 }, [5, 7]);` + - `this` is `{ a: 1 }`. Ignored in arrow fn. +- `fn().bind({ a: 1 });` + - `this` is `{ a: 1 }`. +- `() => {};` + - `this` is the same as in the enclosing lexical context. +- `new Person();` + - `this` is the new object `Person`. +- `DOM callbacks` + - `this` is the element that triggered the event. this === e.currentTarget, this === e.target (if target === currentTarget) + +## Questions + +```js +// what output and why? + +var myObject = { + xz: 'New York', + + func: function() { + var self = this; + + console.log('outer func: this.xz = ' + this.xz); + console.log('outer func: self.xz = ' + self.xz); + + (function() { + console.log('inner func: this.xz = ' + this.xz); + console.log('inner func: self.xz = ' + self.xz); + })(); + } +}; + +myObject.func(); + +// outer func: this.foo = bar +// outer func: self.foo = bar +// inner func: this.foo = undefined +// inner func: self.foo = bar +``` + +```js +// what output and why? + +var value = 1; + +var f = () => { + console.log(this.value); +}; + +f.call({ value: 2 }); // 1, because new context is ignored in arrow functions +``` + +```js +// what output and why? +var o = { + f1: function() { console.warn(this.f1); }, + f2: () => { console.warn(this.f2); } +}; + +o.f1(); +o.f2(); + +var f1_ref = o.f1; +var f2_ref = o.f2; + +f1_ref(); +f2_ref(); + +// ƒ () { console.warn(this.b) } +// undefined - ('this' = window) - because ()=> +// undefined - ('this' = window) - because f() +// undefined - ('this' = window) - because ()=> + +``` + +```js +// what output and why? + +var o = { + f: function() { + return this.a + this.b; + } +}; + +var p = Object.create(o); + +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +``` + +```js +// what output and why? + +var length = 10; + +function fn() { + console.log(this.length); +} + +var obj = { + length: 5, + method: function(fn) { + fn(); + arguments[0](); + } +}; + +obj.method(fn, 1); + +// 10 +// 2 - because arguments[0](); will have this=arguments +``` diff --git a/js/Node.js b/js/Node.js deleted file mode 100644 index e69de29..0000000 diff --git a/js/prototypes.js b/js/prototypes.js deleted file mode 100644 index a781953..0000000 --- a/js/prototypes.js +++ /dev/null @@ -1,34 +0,0 @@ -///////////////////////////////////////////////////////////////////////// -// write your own func that will duplicate string n times -'abc'.duplicate(3); // should return 'abcabcabc' -// TODO - -// Describe inheritance and the prototype chain in JavaScript. Give an example. -/* Each object has its prototype, so there is a prototype chain, with null in the end. Used for inheritance simulation. -When we look for a property that object doesn't have, it traverse all proto chain to find it. */ - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var product = { category: 'fastfood' }; -var burger = Object.create(product); -burger.category = 'drinks'; -delete burger.category; -console.log(burger.category); // 5 - because it is still in proto - -///////////////////////////////////////////////////////////////////////// -// describe different ways of creating an objects -var o = Object.create(null); // proto chain: null -var o = { id: 5, name: 'Elvis' }; // proto chain: Object.prototype -> null -var o = ['Elvis']; // proto chain: Array.prototype -> Object.prototype -> null -function F() {} -var o = new F(); // proto chain: F.prototype -> Object.prototype -> null - -///////////////////////////////////////////////////////////////////////// -// what output and why? how to fix? -for (var i = 0; i < 3; i++) { - setTimeout(function() { - console.warn(i); - }); -} -// 3, 3, 3 - because warn calls after the end of the loop, -// can be fixed by using 'let', 'forEach', of IIFE closure (i => {..})(i) diff --git a/js/this.js b/js/this.js deleted file mode 100644 index 86d1e6e..0000000 --- a/js/this.js +++ /dev/null @@ -1,94 +0,0 @@ -(/* this */) => { - // 'this' keyword is a function execution context. - // It refers to specific object depending on how function is called. - // It also depends if js runs in scrict mode or not ('use strict') - - func(); // simple call - this = 'window' in browser or 'global' in Node, or 'undefined' in browser if scrict mode - obj.func(); // function called as a method. 'this' points to 'obj' - func().call({ a: 1 }, 5, 7); // function called with explicit context. 'this' refers to {a:1}, ignored in arrow f - func().apply({ a: 1 }, [5, 7]); // function called with explicit context. 'this' refers to {a:1}, ignored in arrow f - bind({ a: 1 }); // context is set explicitly, regardless how it is called. In this case this always points to {a:1} - () => {}; // doesn't provide own 'this' binding, but it retains value from the enclosing lexical context - new O(); // this = 'O' - DOM callbacks // this === e.currentTarget, this === e.target (if target === currentTarget) -}; - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var myObject = { - xz: 'New York', - func: function() { - var self = this; - console.log('outer func: this.xz = ' + this.xz); - console.log('outer func: self.xz = ' + self.xz); - (function() { - console.log('inner func: this.xz = ' + this.xz); - console.log('inner func: self.xz = ' + self.xz); - })(); - } -}; -myObject.func(); -(/* output */) => { - /* - outer func: this.foo = bar - outer func: self.foo = bar - inner func: this.foo = undefined - inner func: self.foo = bar - */ -}; - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var value = 1; -var f = () => { - console.log(this.value); -}; -f.call({ value: 2 }); // 1, because new context is ignored in arrow functions - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var o = { - f1: function() { console.warn(this.f1); }, - f2: () => { console.warn(this.f2); } -}; -o.f1(); -o.f2(); -var f1_ref = o.f1; -var f2_ref = o.f2; -f1_ref(); -f2_ref(); -(/* output */) => { - // ƒ () { console.warn(this.b) } - // undefined - ('this' = window) - because ()=> - // undefined - ('this' = window) - because f() - // undefined - ('this' = window) - because ()=> -}; - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var o = { - f: function() { - return this.a + this.b; - } -}; -var p = Object.create(o); -p.a = 1; -p.b = 4; -console.log(p.f()); // 5 - -///////////////////////////////////////////////////////////////////////// -// what output and why? -var length = 10; -function fn() { - console.log(this.length); -} -var obj = { - length: 5, - method: function(fn) { - fn(); - arguments[0](); - } -}; -obj.method(fn, 1); -// 10 -// 2 - because arguments[0](); will have this=arguments \ No newline at end of file