loading...

Resources to Master Javascript

deen_john profile image Deen John Updated on ・44 min read

Master Javascript

Fork,StarThe GITHub link

Fundamentals Javascript Reading:

http://dmitrysoshnikov.com/category/ecmascript/

http://exploringjs.com/impatient-js/ch_syntax.html#statement-vs.expression
https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch1.md
https://stackoverflow.com/questions/12703214/javascript-difference-between-a-statement-and-an-expression

  • Values & Types

http://speakingjs.com/es5/ch08.html
https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch1.md#values--types
https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md

Primitive Values Versus Objects
http://speakingjs.com/es5/ch01.html#basic_prim_vs_obj

Manually Converting to Boolean
There are three ways any value can be converted to a boolean:

1)Boolean(value)

(Invoked as a function, not as a constructor)

2)value ? true : false

3)!!value
https://stackoverflow.com/questions/10467475/double-negation-in-javascript-what-is-the-purpose
var x = "somevalue"
var isNotEmpty = !!x.length;
Let's break it to pieces:

x.length   // 9
!x.length  // false
!!x.length // true
So it's used convert a "truethy" \"falsy" value to a boolean.

A single “not” converts to negated boolean; use twice for the nonnegated conversion.

var a = "0";
var b = [];
var c = {};

var d = "";
var e = 0;
var f = null;
var g;

!!a;    // true
!!b;    // true
!!c;    // true

!!d;    // false
!!e;    // false
!!f;    // false
!!g;    // false

https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript)

https://stackoverflow.com/questions/27509/detecting-an-undefined-object-property)

Well, they are semantically different, the Number constructor called
as a function performs type conversion and parseInt performs parsing.

But in real life we often have values in units, like "100px" or "12pt" in CSS. Also in many countries the currency symbol goes after the amount, so we have "19€" and would like to extract a numeric value out of that.

That’s what parseInt and parseFloat are for.

They “read” a number from a string until they can’t. In case of an error, the gathered number is returned.
The function parseInt returns an integer, whilst parseFloat will return a floating-point number:

 alert( parseInt('100px') ); // 100
alert( parseFloat('12.5em') ); // 12.5

alert( Number("   123   ") ); // 123
alert( Number("123z") );      // NaN (error reading a number at "z")
alert( Number(true) );        // 1
alert( Number(false) );       // 0

http://speakingjs.com/es5/ch11.html#isNaN best

https://stackoverflow.com/questions/2652319/how-do-you-check-that-a-number-is-nan-in-javascripthttps://stackoverflow.com/questions/825402/why-does-isnan-equal-falsehttps://stackoverflow.com/questions/8965364/comparing-nan-values-for-equality-in-javascript
https://stackoverflow.com/questions/6736476/how-to-turn-nan-from-parseint-into-0-for-an-empty-string
https://stackoverflow.com/questions/34261938/what-is-the-difference-between-nan-nan-and-nan-nan
https://stackoverflow.com/questions/20534887/break-on-nan-in-javascript
https://stackoverflow.com/questions/26962341/number-isnan-doesnt-exist-in-ie
https://stackoverflow.com/questions/15176076/understanding-underscores-implementation-of-isnan

I would recommend: typeof value === 'number' && !isNaN(value). Because typeof NaN === 'number'.

NaN is the only value that is not equal to itself:


> NaN === NaN
false

So we can use If you want to check whether a value is NaN, you have to use the global function isNaN():

> isNaN(NaN)
true
> isNaN(33)
false


But :
isNaN does not work properly with nonnumbers, because it first converts those to numbers. That conversion can produce NaN and then the function incorrectly returns true:


> isNaN('xyz')
true


Thus, it is best to combine isNaN with a type check:

function myIsNaN(value) {
    return typeof value === 'number' && isNaN(value);
}


Alternatively, you can check whether the value is unequal to itself (as NaN is the only value with this trait). But that is less self-explanatory:

function myIsNaN(value) {
    return value !== value;
}

isNaN() and Number.isNaN() both test if a value is (or, in the case of isNaN(), can be converted to a number-type value that represents) the NaN value. In other words, "NaN" does not simply mean "this value is not a number", it specifically means "this value is a numeric Not-a-Number value according to IEEE-754".

The reason all your tests above return false is because all of the given values can be converted to a numeric value that is not NaN:

Number('')    // 0
Number('   ') // 0
Number(true)  // 1
Number(false) // 0
Number([0])   // 0

The reason isNaN() is "broken" is because, ostensibly, type conversions aren't supposed to happen when testing values. That is the issue Number.isNaN() is designed to address. In particular, Number.isNaN() will only attempt to compare a value to NaN if the value is a number-type value. Any other type will return false, even if they are literally "not a number", because the type of the value NaN is number. See the respective MDN docs for isNaN() and Number.isNaN().

If you simply want to determine whether or not a value is of the number type, even if that value is NaN, use typeof instead:

typeof 'RAWRRR' === 'number' // false

Something hasn't been initialized : undefined.
Something is currently unavailable: null.

If you want to test for a null value using its type, you need a compound condition:

var a = null;

(!a && typeof a === "object"); // true

When youre trying to identify null, use triple equals so that you can correctly identify the type.
ex : console.log(undefined == null); // true
console.log(undefined === null); // false

null is the only primitive value that is "falsy" (aka false-like; see Chapter 4) but that also returns "object" from the typeof check.

Pitfall: typeof null
Unfortunately, typeof null is 'object'. This is considered a bug (null is not a member of the internal type Object), but it can’t be fixed, because doing so would break existing code. You thus have to be wary of null. For example, the following function checks whether value is an object:

function isObject(value) {
return (value !== null
&& (typeof value === 'object'
|| typeof value === 'function'));

  • Use of null in prototype Use null Prototypes to Prevent Prototype Pollution

function C() { }
C.prototype = null;
But instantiating this constructor still results in instances of Object:
var o = new C();
Object.getPrototypeOf(o) === null; // false
Object.getPrototypeOf(o) === Object.prototype; // true

Numeric conversion using a plus + or Number() is strict. If a value is not exactly a number, it fails:
alert( +"100px" ); // NaN

There are situations when parseInt/parseFloat will return NaN. It happens when no digits could be read:

alert( parseInt('a123') ); // NaN, the first symbol stops the process

And (&&)
If the first operand is falsy, return it. Otherwise, return the second operand:

> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'
Or (||)
If the first operand is truthy, return it. Otherwise, return the second operand:

> 'abc' || 123
'abc'
> '' || 123
123

var a = 42;
var b = "abc";
var c = null;

a || b;     // 42
a && b;     // "abc"

c || b;     // "abc"
c && b;     // null

a || b;
// roughly equivalent to:
a ? a : b;

a && b;
// roughly equivalent to:
a ? b : a;

https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch2.md#testing-for-integers
42.3 % 1 is in decimal but 42 % 1 is 0

Number.isInteger( 42 );     // true
Number.isInteger( 42.000 ); // true
Number.isInteger( 42.3 );   // false

this behaviour can be use in :  
To polyfill Number.isInteger(..) for pre-ES6:

if (!Number.isInteger) {
    Number.isInteger = function(num) {
        return typeof num == "number" && num % 1 == 0;
    };
}

from book : Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript

This chapter taught me some more hidden things about closures and scopes.

https://www.safaribooksonline.com/library/view/effective-javascript-68/9780132902281/ch02.html#ch02lev1sec4)

https://stackoverflow.com/questions/111102/how-do-javascript-closures-work
https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript
https://stackoverflow.com/questions/2728278/what-is-a-practical-use-for-a-closure-in-javascript
https://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue

in vs for ...in

The for-in statement by itself is not a "bad practice", however it can be mis-used,
for example, to iterate over arrays or array-like objects.

The purpose of the for-in statement is to enumerate over object properties.
This statement will go up in the prototype chain, also enumerating over inherited properties, a thing that sometimes is not desired.

for..in isn't guaranteed to preserve element ordering

https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)

https://www.w3schools.com/jsref/jsref_forin.asp
https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea

http://adripofjavascript.com/blog/drips/the-problem-with-for-in-and-javascript-arrays.html

Coercion

  • Equality comparisons and sameness

Coercion

http://speakingjs.com/es5/ch09.html
http://speakingjs.com/es5/ch10.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness)
http://ecma-international.org/ecma-262/5.1/#sec-11.9.3)
http://getify.github.io/coercions-grid/)

http://speakingjs.com/es5/ch09.html
Use case: working with numbers in strings
If you are not sure whether a value x is a number or a number-as-a-string, you can use checks such as the following:


if (x == 123) ...

The preceding checks whether x is either 123 or '123'. Again, this is very compact, and again, it is better to be explicit:

if (Number(x) === 123)

Use case: comparing wrapper instances with primitives
Lenient equals lets you compare primitives with wrapped primitives:


> 'abc' == new String('abc')
true

There are three reasons against this approach. First, lenient equality does not work between wrapped primitives:

> new String('abc') == new String('abc')
false
Second, you should avoid wrappers anyway. 
Third, if you do use them, it is better to be explicit:

if (wrapped.valueOf() === 'abc') 

https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch4.md#comparing-strings-to-numbers

var a = "42";

// bad (will fail!):
if (a == true) {
    // ..
}

// also bad (will fail!):
if (a === true) {
    // ..
}

// good enough (works implicitly):
if (a) {
    // ..
}

// better (works explicitly):
if (!!a) {
    // ..
}

// also great (works explicitly):
if (Boolean( a )) {
    // ..
}

Object.is
https://javascript.info/number

How is this experssion evaluated ? x < y*
The Algorithm (http://speakingjs.com/es5/ch08.html#toprimitive)
https://javascript.info/object-toprimitive

You evaluate a comparison:

x < y

by taking the following steps:

Ensure that both operands are primitives. Objects obj are converted to primitives via the internal operation ToPrimitive(obj, Number) (refer to Algorithm: ToPrimitive()—Converting a Value to a Primitive), which calls obj.valueOf() and, possibly, obj.toString() to do so.
If both operands are strings, then compare them by lexicographically comparing the 16-bit code units (see Chapter 24) that represent the JavaScript characters of the string.
Otherwise, convert both operands to numbers and compare them numerically.
The other ordering operators are handled similarly

null becomes 0 if coerced to a number:

Number(null)
0
5 + null
5

Number(undefined)
NaN
5 + undefined
NaN

3 + ' times'
'3 times'

String(null)
'null'
String(123.45)
'123.45'
String(false)
'false'

Number({})
NaN ..why ?Algorithm: ToPrimitive()—Converting a Value to a Primitive. http://speakingjs.com/es5/ch08.html

typeof vs instanceof vs {}.toString

https://javascript.info/instanceof
https://stackoverflow.com/questions/899574/which-is-best-to-use-typeof-or-instanceof)

*typeof : It returns a string describing the “type” of value.*

> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'

typeof undefined
'undefined'

typeof null
'object'

var a = null;

(!a && typeof a === "object"); // true
null is the only primitive value that is "falsy" 
but that also returns "object" from the typeof check.

practical use :
in Jquery https://code.jquery.com/jquery-3.3.1.js

function isArrayLike( obj ) {

    // Support: real iOS 8.2 only (not reproducible in simulator)
    // `in` check used to prevent JIT error (gh-2145)
    // hasOwn isn't used here due to false negatives
    // regarding Nodelist length in IE
    var length = !!obj && "length" in obj && obj.length,
        type = toType( obj );

    if ( isFunction( obj ) || isWindow( obj ) ) {
        return false;
    }

    return type === "array" || length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}

  • instanceof

http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

https://javascript.info/instanceof

instanceof operator essentially checks whether anything from left-hand object’s prototype chain is
the same object as what’s referenced by prototype property of right-hand object.

var arr = [];
arr instanceof Array; // true
This statement returns true because Array.prototype (being a prototype property of a right-hand object)
references the same object as an internal [[Prototype]] of left-hand object ([[Prototype]]
is “visible” via arr.proto in clients that have proto extension).
An alternative constructor check, which I mentioned earlier, would usually look like:

var arr = [];
arr.constructor == Array; // true

The instanceof operator tests the presence of constructor.prototype i.e Array.prototype in object's prototype chain.

a instanceof Foo; // true

The instanceof operator takes a plain object as its left-hand operand and a function as its right-hand operand.
The question instanceof answers is: in the entire [[Prototype]] i.e proto chain of a, does the object arbitrarily pointed to by Foo.prototype ever appear?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof)

http://speakingjs.com/es5/ch01.html#basic_prim_vs_obj
value instanceof Constr
It returns true if value is an object that has been created by the constructor Constr (see Constructors: Factories for Objects). Here are some examples:

> var b = new Bar();  // object created by constructor Bar
> b instanceof Bar
true

> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object  // Array is a subconstructor of Object
true

> undefined instanceof Object
false
> null instanceof Object
false

Problem with instanceof

case1 :

function Rabbit() {}
let rabbit = new Rabbit();

// changed the prototype
Rabbit.prototype = {};
rabbit instanceof Rabbit //false

That’s one of the reasons to avoid changing prototype. Just to keep safe.

case 2 :
The problems arise when it comes to scripting in multi-frame DOM environments. In a nutshell, Array objects created within one iframe do not share [[Prototype]]’s with arrays created within another iframe. Their constructors are different objects and so both instanceof and constructor checks fail:

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Boom!
arr instanceof Array; // false

// Boom!
arr.constructor === Array; // false


Object toString for the type
// copy toString method into a variable for convenience


let objectToString = Object.prototype.toString;

// what type is this?
let arr = [];

alert( objectToString.call(arr) ); // [object Array]

Object.prototype.toString.call( [1,2,3] );
Object.prototype.toString.call( null );         // "[object Null]"
Object.prototype.toString.call( undefined );    // "[object Undefined]"

For a number, it will be [object Number]
For a boolean, it will be [object Boolean]
For null: [object Null]
For undefined: [object Undefined]
For arrays: [object Array]
…etc (customizable).

As we can see, {}.toString is technically a “more advanced” typeof.

functions

IIFE

  • Using IIFEs in JavaScript to control variable scope

http://speakingjs.com/es5/ch01.html#basic_prim_vs_obj
http://speakingjs.com/es5/ch16.html#iife

function f() {
    if (condition) {
        var tmp = ...;
        ...
    }
    // tmp still exists here
    // => not what we want
}

If you want to introduce a new scope for the then block, you can define a function and immediately invoke it.
This is a workaround, a simulation of block scoping:

function f() {
    if (condition) {
        (function () {  // open block
            var tmp = ...;
            ...
        }());  // close block
    }
}

IIFE Variation: An IIFE with Parameters
You can use parameters to define variables for the inside of the IIFE:

var x = 23;
(function (twice) {
    console.log(twice);
}(x * 2));
This is similar to:

var x = 23;
(function () {
    var twice = x * 2;
    console.log(twice);
}());

IIFE use case: inadvertent sharing via closures
Closures keep their connections to outer variables, which is sometimes not what you want:

var result = [];
for (var i=0; i < 5; i++) {
    result.push(function () { return i });  // (1)
}
console.log(result[1]()); // 5 (not 1)
console.log(result[3]()); // 5 (not 3)
The value returned in line (1) is always the current value of i, not the value it had when the function was created. After the loop is finished, i has the value 5, which is why all functions in the array return that value. If you want the function in line (1) to receive a snapshot of the current value of i, you can use an IIFE:

for (var i=0; i < 5; i++) {
    (function () {
        var i2 = i; // copy current i
        result.push(function () { return i2 });
    }());
}

How can you correct this function ?


var myAlerts = [];

for (var i = 0; i < 5; i++) {
    myAlerts.push(
        function inner() {
            alert(i);
        }
    );
}

myAlerts[0](); // 5
myAlerts[1](); // 5
myAlerts[2](); // 5
myAlerts[3](); // 5
myAlerts[4](); // 5


Answer :

var myAlerts = [];

for (var i = 0; i < 5; i++) {
    myAlerts.push(
       (function iife(){
         var j = i ;
         return function inner() {
            console.log(j);
          }
       })()

    );
}
myAlerts[1]()

https://content.myemma.com/emmatech/using-iifes-in-javascript-to-control-variable-scope)
https://stackoverflow.com/questions/2421911/what-is-the-purpose-of-wrapping-whole-javascript-files-in-anonymous-functions-li
https://stackoverflow.com/questions/13341698/javascript-plus-sign-in-front-of-function-name
https://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript
https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript

http://speakingjs.com/es5/ch01.html#basic_prim_vs_obj

  • *Too Many or Too Few Arguments*
function f(x, y) {
    console.log(x, y);
    return toArray(arguments);
}
Additional parameters will be ignored (except by arguments):

> f('a', 'b', 'c')
a b
[ 'a', 'b', 'c' ]

  • *Optional Parameters* The following is a common pattern for assigning default values to parameters:
function pair(x, y) {
    x = x || 0;  // (1)
    y = y || 0;
    return [ x, y ];
}
In line (1), the || operator returns x if it is truthy (not null, undefined, etc.). Otherwise, it returns the second operand:

> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]
function pair(x, y) {
    if (arguments.length !== 2) {
        throw new Error('Need exactly 2 arguments');
    }
    ...
}

-Functions Inside a Method


var jane = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    logHiToFriends: function () {
        'use strict';
        this.friends.forEach(function (friend) {
            // `this` is undefined here
            console.log(this.name+' says hi to '+friend);
        });
    }
}
Calling logHiToFriends produces an error: why ?

> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined

Ans :
 jane.logHiToFriends() runs like 

 var callback = function (friend) {
            // `this` is undefined here
            console.log(this.name+' says hi to '+friend);
        }

 var jane = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    logHiToFriends: function () {
        'use strict';
        this.friends.forEach(callback);
    }
}

as callback funs like callback() i.e without any context , this points to global object i.e window

Let’s look at two ways of fixing this. First, we could store this in a different variable:


logHiToFriends: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
        console.log(that.name+' says hi to '+friend);
    });
}
Or, forEach has a second parameter that allows you to provide a value for this:

logHiToFriends: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name+' says hi to '+friend);
    }, this);
}

Call,Apply,Bind

https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/)

https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md)

Call,Apply,Bind - Learn even more

var score = Function.prototype.call.bind(scoreCalculator.getScore); //binding call to scoreCalculator.getScore
score(player1);

is doing this

scoreCalculator.getScore.call(player1)

and that you can borrowing the call method from anywhere, in this case from the Function.prototype, but it doesn’t matter where and binding it to the getScore function.

Call

use of call :

inArray: function( elem, arr, i ) {
        return arr == null ? -1 : indexOf.call( arr, elem, i );
    }

var elems = {
   length: 0,
   add: function(elem){
       Array.prototype.push.call(this, elem);
   },
   gather: function(id){
       this.add(document.getElementById(id));
   }
 };

 elems.gather("first");

 console.log(elems.length == 1 && elems[0].nodeType,
 "Verify that we have an element in our stash");

 elems.gather("second");

 console.log(elems.length == 2 && elems[1].nodeType,
 "Verify the other insertion"); 



Apply


 function smallest(array){
     return Math.min.apply(Math, array);
 }
 function largest(array){
     return Math.max.apply(Math, array);
 }

 assert(smallest([0, 1, 2, 3]) == 0,
 "Located the smallest value.");

 assert(largest([0, 1, 2, 3]) == 3,
 "Located the largest value."); 

Bind

Manually simulating an apply() for constructors
We can simulate apply() in two steps.

Step 1
Pass the arguments to Date via a method call (they are not in an array—yet):

     new (Date.bind(null, 2011, 11, 24))

     or 
     new (Date.bind.call(Date,null, 2011, 11, 24))

The preceding code uses bind() to create a constructor without parameters and invokes it via new.

Step 2
Use apply() to hand an array to bind(). Because bind() is a method call, we can use apply():

new (Function.prototype.bind.apply(
         Date, [null, 2011, 11, 24]))

The preceding array contains null, followed by the elements of arr. We can use concat() to create it by prepending null to arr:

var arr = [2011, 11, 24];
new (Function.prototype.bind.apply(
         Date, [null].concat(arr)))

'use strict';
var jane = {
    name: 'Jane',

    describe: function () {
        return 'Person named '+this.name;
    }
};

We want to extract the method describe from jane, put it into a variable func, and call it. However, that doesn’t work:

> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined
The solution is to use the method bind() that all functions have. It creates a new function whose this always has the given value:

> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'


  • How to delete a function
var animals = [
  { species: 'Lion', name: 'King' },
  { species: 'Whale', name: 'Fail' }
];

for (var i = 0; i < animals.length; i++) {
  (function(i) {
    this.print = function() {
      console.log('#' + i + ' ' + this.species
                  + ': ' + this.name);
    }
    this.print();
    this.print = null ;
    delete this.print ;
  }).call(animals[i], i);
}
  • where instanceof fails

If you have two arbitrary objects, say a and b, and want to find out if the objects are related to each other through a [[Prototype]] chain, instanceof alone can't help.

much cleaner, approach to [[Prototype]] reflection is:


      function Foo() {  }

      Foo.prototype = { 
         c :2

       }; // create a new prototype object

      var a1 = new Foo();

      Foo.prototype.isPrototypeOf( a ); // true

Notice that in this case, we don't really care about (or even need) Foo, we just need an object (in our case, arbitrarily labeled Foo.prototype) to test against another object. The question isPrototypeOf(..) answers is: in the entire [[Prototype]] chain of a, does Foo.prototype ever appear?

https://github.com/getify/You-Dont-Know-JS/blob/6efd08c9db8e9808a9046204c719c99cb4702c18/this%20%26%20object%20prototypes/ch5.md#L487)

let,const arrow function

https://github.com/nzakas/understandinges6/blob/master/manuscript/01-Block-Bindings.md
https://www.w3schools.com/js/js_arrow_function.asp

json.stringify

https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch4.md)

Strict

http://speakingjs.com/es5/ch07.html#strict_mode
https://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it)

This in Object

Chapter 1 :https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch1.md
Chapter 2 : https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md

http://davidshariff.com/blog/javascript-this-keyword/

Effective Javascript : Chapter 4

The scope of this is always determined by its nearest enclosing
function.


function CSVReader(separators) {
    this.separators = separators || [","];
    this.regexp =
    new RegExp(this.separators.map(function(sep) {
      return "\\" + sep[0];
       }).join("|"));
}


CSVReader.prototype.read = function(str) {
    var lines = str.trim().split(/\n/);
    return lines.map(function(line) {
        console.log(this)
       return line.split(this.regexp); // wrong this!
     });
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n");

[
[
"a,b,c"
],
[
"d,e,f"
]
]


function CSVReader(separators) {
    this.separators = separators || [","];
    this.regexp =
    new RegExp(this.separators.map(function(sep) {
      return "\\" + sep[0];
       }).join("|"));
}


CSVReader.prototype.read = function(str) {
    var lines = str.trim().split(/\n/);
    return lines.map(function(line) {
        console.log(this)
       return line.split(this.regexp); // wrong this!
     },this);
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n");

[
[
"a",
"b",
"c"
],
[
"d",
"e",
"f"
]
]

Closures

Note :
scope chain only works for fnctions inside functions and not functions inside object

      var StartStopCounter = {
          counter : 0,
          start : function(){
                StartStopCounter.stopCounter = setInterval(function(){
                    console.log(StartStopCounter.counter);
                    //que : why only counter won't work ?
                    StartStopCounter.counter=StartStopCounter.counter + 1 ;
                },1000);

          },
          stop : function(){
              clearInterval(StartStopCounter.stopCounter);

          }
      }


  • You Don't Know JS: Scope & Closures

https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch1.md#scope
https://github.com/getify/You-Dont-Know-JS/tree/master/scope%20%26%20closures)

http://javascript.info/closure

Sometimes encapsulation is used to restrict the visibility of
certain elements, and this act is known as data hiding. JavaScript’s object system does
not provide a way to hide data directly, so data is hidden using something called closures.

By using functional techniques involving closures, you can achieve data hiding that is as effective
as the same capability offered by most object-oriented languages

https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript

  • Practical use of closure examples

ex1 : Private variables


      function Ninja() {                                            //#1

        var feints = 0;                                             //#2

        this.getFeints = function(){                                //#3
          return feints;                                            //#3
        };                                                          //#3

        this.feint = function(){                                    //#4
          feints++;                                                 //#4
        };                                                          //#4
      }

      var ninja = new Ninja();                                      //#5

      ninja.feint();                                                //#6

      assert(ninja.feints === undefined,                            //#7
          "And the private data is inaccessible to us." );          //#7

      assert(ninja.getFeints() == 1,                                //#8
             "We're able to access the internal feint count." );    //#8

ex2 :


function animateIt(elementId) {

    var elem = document.getElementById(elementId);              //#2
    var tick = 0;                                               //#3

    var timer = setInterval(function(){                         //#4
      if (tick < 100) {
        elem.style.left = elem.style.top = tick + "px";
        tick++;
      }
      else {
        clearInterval(timer);
        assert(tick == 100,                                      //#5
               "Tick accessed via a closure.");
        assert(elem,
               "Element also accessed via a closure.");
        assert(timer,
               "Timer reference also obtained via a closure." );
      }
    }, 10);

  }

  animateIt('box')

ex 3 :

const createStore = (reducer) => {
let state;
let listeners = [];

const getState = () => state;

const dispatch = (action) => {
state = reducer(state, action)
listeners.forEach(listener => listener());
};

const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter(l => l !== listener);
}
};

dispatch({}); // dummy dispatch

return { getState, dispatch, subscribe };

};

Closure use Example : Overloading functions


 var ninjas = {
    values: ["Dean Edwards", "Sam Stephenson", "Alex Russell"]
 };

function addMethod(object, name, fn) {
 var old = object[name];
 object[name] = function(){
   if (fn.length == arguments.length)
      return fn.apply(this, arguments)
   else if (typeof old == 'function')
      return old.apply(this, arguments);
  };
}

 addMethod(ninjas, "find", function(){
          return this.values;
 });

 addMethod(ninjas, "find", function(name){
      var ret = [];
      for (var i = 0; i < this.values.length; i++)
      if (this.values[i].indexOf(name) == 0)
      ret.push(this.values[i]);
      return ret;
 });

 addMethod(ninjas, "find", function(first, last){
      var ret = [];
      for (var i = 0; i < this.values.length; i++)
      if (this.values[i] == (first + " " + last))
      ret.push(this.values[i]);
      return ret;
 });

 assert(ninjas.find().length == 3,
 "Found all ninjas");
 assert(ninjas.find("Sam").length == 1,
 "Found ninja by first name");
 assert(ninjas.find("Dean", "Edwards").length == 1,
 "Found ninja by first and last name");
 assert(ninjas.find("Alex", "Russell", "Jr") == 
 ,
 "Found nothing");

example 2 :
CREATING A SELF-CONTAINED SCOPE

Consider the following snippet:


(function(){
 var numClicks = 0;
 document.addEventListener("click", function(){
 alert( ++numClicks );
 }, false);
})();

/*
Because the immediate function is executed immediately (hence its name), the click
handler is also bound right away. The important thing to note is that a closure is created
for the handler that includes numClicks, allowing the numClicks variable to persist
along with the handler, and be referenceable by the handler but nowhere else.
 This is one of the most common ways in which immediate functions are used: as
simple, self-contained wrappers for functionality. The variables needed for the unit of
functionality are trapped in the closure, but they aren’t visible anywhere else.
*/

object

http://speakingjs.com/es5/ch17.html
https://stackoverflow.com/questions/tagged/javascript+object

Copying an Object
To create an identical copy of an object, you need to get two things right:

The copy must have the same prototype (see Layer 2: The Prototype Relationship Between Objects) as the original.
The copy must have the same properties, with the same attributes as the original
The following function performs such a copy:

function copyObject(orig) {
// 1. copy has same prototype as orig
var copy = Object.create(Object.getPrototypeOf(orig));

// 2. copy has all of orig’s properties
copyOwnPropertiesFrom(copy, orig);

return copy;
}
The properties are copied from orig to copy via this function:

function copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source) // (1)
.forEach(function(propKey) { // (2)
var desc = Object.getOwnPropertyDescriptor(source, propKey); // (3)
Object.defineProperty(target, propKey, desc); // (4)
});
return target;
};
These are the steps involved:

Get an array with the keys of all own properties of source.
Iterate over those keys.
Retrieve a property descriptor.
Use that property descriptor to create an own property in target

https://stackoverflow.com/questions/3390396/how-to-check-for-undefined-in-javascript)

If you delete the property, its key is gone, too:

delete obj.foo
true
Object.keys(obj)
[ 'bar' ]
delete affects only the direct (“own,” noninherited) properties of an object. Its prototypes are not touched

  • If you merely set a property to undefined, the property still exists and the object still contains its key

var obj = { foo: 'a', bar: 'b' };

obj.foo = undefined;
Object.keys(obj)
[ 'foo', 'bar' ]

https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)


      'use strict';

      const anotherObject = {};

      Object.defineProperty(anotherObject, 'a', {
        value: 2,
        writable: false
      });

      var myObject = Object.create( anotherObject );

      myObject.a = 3;

https://medium.freecodecamp.org/lets-explore-objects-in-javascript-4a4ad76af798


function SuperType(name){
 this.name = name;
 this.colors = ["red","green"];
}

SuperType.prototype.sayName = function(){
 console.log(this.name);
};

function SubType(name, age){

 //inherit properties
 SuperType.call(this, name);

 this.age = age;
}

//inherit methods
SubType.prototype = new SuperType();  // problem as this creates color property on prototype 

SubType.prototype.sayAge = function(){
 console.log(this.age);
};

var instance1 = new SubType("Nicholas", 29);


problems with this :

console.log(instance1) > color property on prototype 

SubType {name: "Nicholas", colors: Array(2), age: 29}
    age: 29
    colors: (2) ["red", "green"]
    name: "Nicholas"
    __proto__: SuperType
        colors: (2) ["red", "green"]
        name: undefined
        sayAge: ƒ ()
        __proto__: Object

https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)
https://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript
https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch6.md
https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript
https://stackoverflow.com/questions/4166616/understanding-the-difference-between-object-create-and-new-somefunction
https://stackoverflow.com/questions/4508313/advantages-of-using-prototype-vs-defining-methods-straight-in-the-constructor
https://stackoverflow.com/questions/10430279/extending-an-object-in-javascript
https://stackoverflow.com/questions/3781373/javascript-what-are-extend-and-prototype-used-for
https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice
https://stackoverflow.com/questions/4740806/native-way-to-merge-objects-in-javascript
https://stackoverflow.com/questions/8859828/javascript-what-dangers-are-in-extending-array-prototype

Use hasOwnProperty to Protect Against Prototype Pollution

var dict = {};
"alice" in dict; // false
"bob" in dict; // false
"chris" in dict; // false
"toString" in dict; // true
"valueOf" in dict; // true
Luckily, Object.prototype provides the hasOwnProperty method, which
is just the tool we need to avoid prototype pollution when testing for
dictionary entries:
dict.hasOwnProperty("alice"); // false
dict.hasOwnProperty("toString"); // false
dict.hasOwnProperty("valueOf"); // false

Getting all properties

https://javascript.info/getting-all-properties
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

The Object.values() method returns an array of a given object's own enumerable property values,
in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates
properties in the prototype chain as well).

Object.keys(obj) / Object.values(obj) / Object.entries(obj)
These methods only list enumerable properties, and those that have strings as keys.
1)Object.keys(Object.prototype)

[]
The Object.keys() method returns an array of a given object's own property names,
in the same order as we get with a normal loop.

2)Object.getOwnPropertyNames(Object.prototype)
– returns an array of all own string property names
If we want non-enumerable properties:

(12) ["constructor", "defineGetter", "defineSetter", "hasOwnProperty", "lookupGetter", "lookupSetter", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "proto", "toLocaleString"]

3)Reflect.ownKeys(Object.prototype)
(12) ["constructor", "defineGetter", "defineSetter", "hasOwnProperty", "lookupGetter", "lookupSetter", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "proto", "toLocaleString"]

https://stackoverflow.com/questions/15283720/why-are-for-in-faster-than-for-loops-when-looping-through-an-array
A for loop will search for properties on the [[Prototype]] chain too if they aren't found on the array. E.g. a for loop over [0,,2] will search for 1 all the way to Object.prototype[[Prototype]]

don't use for..in to loop arrays. Not. Ever

Manually simulating an apply() for constructors

1) Pass the arguments to Date via a method call (they are not in an array—yet):

new (Date.bind(null, 2011, 11, 24))

The preceding code uses bind() to create a constructor without parameters and invokes it via new.

2)
Use apply() to hand an array to bind(). Because bind() is a method call, we can use apply():

new (Function.prototype.bind.apply(
Date, [null, 2011, 11, 24]))
The preceding array contains null, followed by the elements of arr. We can use concat() to create it by prepending null to arr:

var arr = [2011, 11, 24];
new (Function.prototype.bind.apply(
Date, [null].concat(arr)))

Effective Javascript - chapter 4

Problem with using default constructor

http://raganwald.com/2014/07/09/javascript-constructor-problem.html

https://javascript.info/function-prototype


function Rabbit() {}

/* default prototype
Rabbit.prototype = { constructor: Rabbit };
*/


function Rabbit() {}
// by default:
// Rabbit.prototype = { constructor: Rabbit }

alert( Rabbit.prototype.constructor == Rabbit ); // true

…JavaScript itself does not ensure the right "constructor" value.

Yes, it exists in the default "prototype" for functions, but that’s all. What happens with it later – is totally on us.

In particular, if we replace the default prototype as a whole, then there will be no "constructor" in it.

For instance:

function Rabbit() {}
Rabbit.prototype = {
  jumps: true
};

let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false

So, to keep the right "constructor" we can choose to add/remove properties to the default "prototype" instead of overwriting it as a whole:

function Rabbit() {}

// Not overwrite Rabbit.prototype totally
// just add to it

Rabbit.prototype.jumps = true

// the default Rabbit.prototype.constructor is preserved
Or, alternatively, recreate the constructor property manually:

Rabbit.prototype = {
  jumps: true,
  constructor: Rabbit
};

// now constructor is also correct, because we added it

    function Person(){

    }

    var friend = new Person();

    Person.prototype = {
     name : "Nicholas",
     age : 29,
     job : "Software Engineer",
     sayName : function () {
        console.log(this.name);
       }
    };


Constructor is Object Constructor
(new Person()).constructor
ƒ Object() { [native code] }

Arrays

https://javascript.info/array-methods
http://speakingjs.com/es5/ch18.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
https://stackoverflow.com/questions/tagged/arrays+javascript

Splice
https://javascript.info/array-methods#splice
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice


array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) //deletecount is no of element to delete

1)
let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]

2)
let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]

3)
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"

https://github.com/deenjohn/Javascript-revision/blob/master/General/arraylike%20vs%20array.md)

what exactly makes an object “array-like”? The basic contract of
an array object amounts to two simple rules.
■ It has an integer length property in the range 0...232 – 1.
■ The length property is greater than the largest index of the object.
An index is an integer in the range 0...232 – 2 whose string representation is the key of a property of the object

This is all the behavior an object needs to implement to be compatible
with any of the methods of Array.prototype. Even a simple object literal can be used to create an array-like object:


var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
var result = Array.prototype.map.call(arrayLike, function(s) {
return s.toUpperCase();
}); // ["A", "B", "C"]


function toArray(arrayLikeObject) {
    return Array.prototype.slice.call(arrayLikeObject);
}

Strings act like immutable arrays, too, since they can be indexed
and their length can be accessed as a length property. So the
Array.prototype methods that do not modify their array work with
strings:

var result = Array.prototype.map.call("abc", function(s) {
return s.toUpperCase();
}); // ["A", "B", "C"]


There is just one Array method that is not fully generic: the array concatenation method concat. This method can be called on any arraylike receiver, but it tests the [[Class]] of its arguments. If an argument
is a true array, its contents are concatenated to the result; otherwise,
the argument is added as a single element. This means, for example,
that we can’t simply concatenate an array with the contents of an
arguments object:


function namesColumn() {
  return ["Names"].concat(arguments);
}
namesColumn("Alice", "Bob", "Chris");
// ["Names", { 0: "Alice", 1: "Bob", 2: "Chris" }]


In order to convince concat to treat an array-like object as a true
array, we have to convert it ourselves. A popular and concise idiom
for doing this conversion is to call the slice method on the array-like
object:


function namesColumn() {
   return ["Names"].concat([].slice.call(arguments));
}
namesColumn("Alice", "Bob", "Chris");
// ["Names", "Alice", "Bob", "Chris"]


https://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript

DOM

Que :http://javascript.info/task/select-diagonal-cells
Ans :


    var tr = Array.from(document.querySelectorAll('tr'));
    for(var i =0 ;i<tr.length ;i++){
       for(var j =0 ;j<tr.length ;j++){
         if(i ==j){
           console.log("i ",i ,j);
           console.log((Array.from(tr[i].querySelectorAll('td'))[i]).style.background ='red');
           console.log('.......')
         }      
       }
    }

    // your code

  • Live collections

All methods "getElementsBy*" return a live collection. Such collections always reflect the current state of the document
and “auto-update” when it changes

http://javascript.info/searching-elements-dom#live-collections

good for quick look at all events in javascript

https://www.w3schools.com/jsref/obj_event.asp

https://www.w3.org/TR/uievents/#widl-MouseEvent-relatedTarget

https://www.w3schools.com/js/js_events.asp)

https://www.w3schools.com/jsref/event_cancelable.asp

https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

https://github.com/krasimir/EventBus
https://stackoverflow.com/questions/2863547/javascript-scroll-event-for-iphone-ipad

http://javascriptkit.com/javatutors/touchevents.shtml

https://stackoverflow.com/questions/31865416/what-is-the-difference-between-event-target-event-toelement-and-event-srcelemen

var pressTimer;
document.getElementById("demo").addEventListener("mousedown", mouseDown);
document.getElementById("demo").addEventListener("mouseup", mouseUp);

function mouseDown() {
pressTimer = window.setTimeout(function() {
document.getElementById("demo").innerHTML = "The mouse button is held down.";
},1000);

}

function mouseUp() {
clearTimeout(pressTimer);
}

https://javascript.info/task/sliding-tree


var el = document.getElementById('tree');
console.log(el);
el.addEventListener("click", handler);

function handler(e){
  if(e.target.children.length == 1){
    e.target.children[0].hidden = !e.target.children[0].hidden;
  }
}

mouseleave vs mouseover
https://codepen.io/deen_john/pen/jONJwJz?editors=0010
https://www.youtube.com/watch?v=pzT4hAY82q4

Safari 4, Android 2.2 WebKit, and Opera Mobile 11 all have the following behavior:

1) preventDefault on the touchstart event prevents scrolling, double-tap zooming, and mouseup/mousedown/click events.

2) preventDefault on the touchmove event prevents scrolling.

3) preventDefault on the touchend event does NOT prevent scrolling or mouse events.

4) None of these will prevent pinch zooming. Safari implements a separate "gesturechange" event that is fired for pinch gestures and can be used to prevent zooming. This event is not implemented by Android or Opera.

Example :


<!DOCTYPE html>
<html>
<body>

<h1>Show checkboxes:</h1>

<form action="/action_page.php">
  <input type="checkbox" name="vehicle1" value="Bike"> I have a bike<br>
  <input type="checkbox" name="vehicle2" value="Car"> I have a car<br>
  <input type="checkbox" name="vehicle3" value="Boat" checked> I have a boat<br><br>
  <input type="submit" value="Submit">
</form>

<script>
var fe = document.querySelector('form');

fe.addEventListener("mousedown", function(e){
  console.log(e);
  e.preventDefault()
});

fe.addEventListener("mouseup", function(e){
e.preventDefault()
  console.log(e)
});

fe.addEventListener("click", function(e){
e.preventDefault()
  console.log(e)
});


</script>
</body>
</html>


<body>

<p>This example uses the addEventListener() method to attach a "mousedown" and "mouseup" event to a p element.</p>

<p id="demo">Click me.</p>

<script>
document.getElementById("demo").addEventListener("mousedown", mouseDown);
document.getElementById("demo").addEventListener("mouseup", mouseUp);

function mouseDown(e) {
e.preventDefault();
//return false ;
 // document.getElementById("demo").innerHTML = "The mouse button is held down.";
}

function mouseUp(e) {
e.preventDefault();
//return false
  //document.getElementById("demo").innerHTML = "You released the mouse button.";
}
</script>

</body>

In above example , events order is mousedown > mouseup > click
preventdefault only works on click

passive handler
https://javascript.info/default-browser-action#the-passive-handler-option

Element.closest()


$(document).on('click', function(event) {
  if (!$(event.target).closest('#menucontainer').length) {
    // Hide the menus.
  }
});

The above handler listens for clicks on the document and checks to see if the event target
is #menucontainer or has #menucontainer as a parent. If it doesn't, you know the click originated
from outside of #menucontainer, and thus you can hide the menus if they're visible.

https://developer.mozilla.org/en-US/docs/Web/API/Element/closest

cancelbubble
if the bubbles attribute is set to false, the bubble phase will be skipped


<body>

<p>Click the button to find out if the onclick event is a bubbling event.</p>

<button id ='button'>Try it</button>

<p id="demo"></p>

<script>

document.addEventListener("click", myFunction1);
button.addEventListener("click", myFunction1);
button.addEventListener("click", myFunction2);

function myFunction1() {
  console.log(event.cancelBubble);
  console.log('event ',  event.currentTarget)
  event.cancelBubble=true;
  document.getElementById("demo").innerHTML = event.cancelBubble;
}

function myFunction2(event) { 

  console.log('event ',  event.currentTarget)
  console.log(event.cancelBubble);

  document.getElementById("demo").innerHTML = event.cancelBubble;
}
</script>

</body>

https://www.html5rocks.com/en/mobile/touchandmouse/
https://www.w3.org/TR/uievents/#events-mouseevent-event-order
https://www.w3.org/TR/uievents

Focus event :
Before Focus event is fired , mousedown event is fired.let
Mousedown > Focus

textContent gets the content of all elements, including and

Posted on Apr 15 '18 by:

deen_john profile

Deen John

@deen_john

A curious reader.FullStack Javascript/Java dev. Good knowledge of MEAN stack. Used to work in Java & its framework like Spring, Hibernate but currently devoted to Javascript. Stay humble,Stay foolish

Discussion

markdown guide