Versions | |
---|---|
1 | es5 |
2 | es6 |
3 | es2015 |
4 | es7 |
5 | es2016 |
6 | es2017 |
7 | es2018 |
8 | es2019 |
9 | esnext |
function getData() {} // Normal Function
(function() {})(); // Immediate call
var b = function() {}; // function expression
var c = function setData() {}; // named function expression
var d = () => {}; // Arrow function
Note : All these functions refer to global object(node) / window object(window)
Note : JavaScript functions are executed using the scope they were defined in.
var b = function() {
return 'Hello';
}();
b(); // Not a Function
b // 'Hello'
Above has its own execution context.
If you want to use another context,
name = 'Hey';
(function(name) {
console.log(name);
}('Hello'));
These both are in different context. Now what if you want to use another.
name = 'Hey';
(function(global, name) {
console.log(name+" "+global);
}(name, 'Hello'));
If you keep the below code, it will throw an error
function () {
return 'Hello';
}
So wrap it in a paranthesis,
(function () {
return 'Hello';
});
If you want to call it, then
(function () {
return 'Hello';
}());
(function () {
return 'Hello';
})();
If you want to change this reference in a function then call the method with call
function or apply
:
function add(c,d) {
return this.a + this.b + c + d;
}
var o = { a: 1, b: 2 };
add.call(o, 2, 4); // 9
add.apply(o, [2,4]); // 9
It creates a clone of the function provided.
Call and Apply functions change this
reference of a function during invocation. What if you want to define while declaration ?
** Bind to the rescue **
function d() {
return this.name;
}
var o = { name : 'Deepen' };
// Create a new method using bind.
// This will copy the function but assigns this to given object reference
var g = d.bind(o);
g(); // Deepen
var dude = function() {
return this.firstname+ " " + this.lastname;
}.bind(a);
Now, you can also provide additional parameters to bind, which will permanently define those arguments to the called function.
var dude = function(txt) {
return txt;
}.bind(window, 'My Text');
dude();
Now, check this example,
var dude = function(a,b) {
return a+b;
}.bind(window, 2);
dude(); // NaN
dude(3); // 5
If you do not provide all arguments to bind, its Okay, however, if pass arguments to calling function, it will apply to next following argument to function parameters.
All objects will have a constructor property. Objects created without the explicit use of a constructor function (i.e. the object and array literals) will have a constructor property that points to the Fundamental Object constructor type for that object.
var o = {};
o.constructor === Object; // true
var o = new Object;
o.constructor === Object; //true
var a = [];
a.constructor === Array; // true
var a = new Array;
a.constructor === Array //true
var n = new Number(3);
n.constructor === Number; // true
If you ned to know exact Class Type of an Object, use constructor property of the object to determine.
This code ensures function to be always called as Constructor :
function Book(name, year) {
if (!(this instanceof Book)) {
return new Book(name, year);
}
this.name = name;
this.year = year;
}
Unlike Other Programming Languages, JavaScript does not depend on classes for inheritance. Rather it follows a prototype architecture inheritance.
So, how does it work? Well, every object has one property named prototype (proto) which links or points to its parent. It may or may not have a value pointing to another object.
So, when you write:
var myObject = {};
has a property named prototype. In this case, as it is an Object, it points to Object.prototype
.
If you want to create an object with no prototype linking to another object (not even Object.prototype) then use following code:
var myObject = Object.create(null);
Object.create() links to another object, in this case, its prototype is set to null (not referencing to anyone).
var d = {}
var e = []
var f = Object.create(null);
console.log(Object.getPrototypeOf(d) === Object.prototype);
console.log(Object.getPrototypeOf(e) === Array.prototype);
console.log(Object.getPrototypeOf(f) === null);
It should not be done, as it may cause performance issues.
var myObject = {}
Object.defineProperty(myObject, 'property1', {
value: 'Deepen',
configurable: true,
writable: true,
enumerable: true
})
console.log(myObject.property1) // Output: Deepen
- Configurable - It cannot be replaced(i.e. its key cannot be replaced) but its value can be edited if false.
- Writable - Its value cannot edited if false.
- Enumerable - It cannot be iterated if false. (for each loop)
We will see each properties in detail, just hang on:
var myObject = []
Object.defineProperty(myObject, 0, {
value: 'a',
configurable: true,
writable: true,
enumerable: true
})
Object.defineProperty(myObject, 1, {
value: 'b',
configurable: true,
writable: true,
enumerable: true
})
Object.defineProperty(myObject, 2, {
value: 'c',
configurable: true,
writable: true,
enumerable: true
})
Now, when yo do:
console.log(myObject); // [ 'a', 'b', 'c' ]
for(var obj in myObject) {
console.log(obj) // 0 1 2
}
However, when you change enumerable property to false (myObject[1]), see what happens:
var myObject = []
Object.defineProperty(myObject, 0, {
value: 'a',
configurable: true,
writable: true,
enumerable: true
})
Object.defineProperty(myObject, 1, {
value: 'b',
configurable: true,
writable: true,
enumerable: false
})
Object.defineProperty(myObject, 2, {
value: 'c',
configurable: true,
writable: true,
enumerable: true
})
Now, when yo do:
console.log(myObject); // [ 'a', [1]: 'b', 'c' ]
for(var obj in myObject) {
console.log(obj) // 0 2
}
It does not allow to enumerate(iterate via for each loop), however you can use for loop and iterate and point to each array index like this:
for(var i=0;i<myObject.length;i++) {
console.log(myObject[i]); // 0 1 2
}
Now, what if you change the key:
var myObject = []
Object.defineProperty(myObject, 0, {
value: 'a',
configurable: true,
writable: true,
enumerable: true
})
Object.defineProperty(myObject, 11, {
value: 'b',
configurable: true,
writable: true,
enumerable: false
})
Object.defineProperty(myObject, 2, {
value: 'c',
configurable: true,
writable: true,
enumerable: true
})
console.log(myObject); // [ 'a', , 'c', , , , , , , , , [11]: 'b' ]
for(var obj in myObject) {
console.log(obj) // 0 2
}
However, you can also add string like this '11' or '2' but you cannot add strings which cannot be converted to number like 'key1' or 'key2'.
myObject[2] = 'Boo'
console.log(myObject[2]) // Output: Boo
Now, this time change value of myObject[2]'s property writable to false.
myObject[2] = 'Boo'
console.log(myObject[2]) // Output: b
Writable false makes it constant.
console.log(delete myObject[0]); // Will Delete Element on index 0
OR
console.log(delete myObject.property1) // Will Delete property1 of the Element
&
Object.defineProperty(myObject, 0, {
value: 'a',
configurable: true,
writable: true,
enumerable: **false**
})
If you redefine same property or index, it will replace old one with new property value of enumerable, writeable or simply pu t it, it will allow to replace and delete the key or index but if you make configurable to false then and you define same property, it wont allow you set.
function A () {}
function B () {}
function C () {}
B.prototype = Object.create(A.prototype);
C.prototype = Object.create(B.prototype);
var c = new C();
console.log(C.prototype.isPrototypeOf(c)); // true
console.log(C.prototype.isPrototypeOf(c)); // true
console.log(c instanceof A); // true
console.log(B.prototype.isPrototypeOf(c)); // true
console.log(A.prototype.isPrototypeOf(c)); // true
console.log(Object.prototype.isPrototypeOf(c)); // true
var d = {}
d.name = 'Deepen'
console.log(d.hasOwnProperty(name))
It will only check in d object and not in its prototype. For checking in prototype as well use in operator:
var e = Object.create(d)
console.log('name' in e)
Suppose we two or more functionalities so we can nest like this,
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>
var counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
})();
console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1
function dude() {
return function(name) {
console.log('name');
}
}
dude()('Deepen');
function setLang(lang) {
return function (name) {
if(lang == 'en') {
return 'Hi, '+name;
} else if(lang == 'it') {
return 'Bonjure, '+name;
} else {
return 'Namaste, '+name;
}
}
}
var sayHi = setLang('en');
sayHi('Deepen');
Constructor in Javascript
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
var person1 = new Person('Deepen', 'Dhamecha');
var person2 = new Person('Dilisha', 'Dhamecha');
Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}
var s = new String('John');
String.prototype.functionName = function() {
return any;
}
person1.getFullName();
person2.getFullName();
var person = {
this.firstname = 'Deepen;
this.lastname = 'Dhamecha';
};
var o = Object.create(person);
Now o
is empty and its prototype(parent) is person
.
Only apply to function
function dude() {
'use strict';
var person = {};
persom.name = 'Deepen';
}
Apply to whole file
'use strict';
var person = {};
persom.name = 'Deepen';
JavaScript is a prototypal language, which means that objects inherit directly from other objects.
Actually, JavaScript is conflicted about its prototypal nature. Instead of having objects inherit directly from other objects, an unnecessary level of indirection is inserted such that objects are produced by constructor functions.
When a function object is created, the Function constructor that produces the function object runs some code like this:
this.prototype = {constructor: this};
The new function object is given a prototype property whose value is an object containing a constructor property whose value is the new function object. Every function gets a prototype object because the language does not provide a way of determining which functions are intended to be used as constructors.
This is using default
x.js
export default function xx() {
return "Hello World!";
}
main.js
import anyName from './x';
console.log(anyName());
When you dont have to use default export, x.js
export function xx() {
return "Hello World!";
}
main.js
import { anyName } from './x';
console.log(anyName);
As if you are importing one by one.
When you have multiple functions to export,
y.js
export function y1() {
return "Y1";
}
export function y2() {
return "Y2";
}
// You can rename anything you would like to rename as the key of this object
export default {
y5: y1,
y6: y2
};
main.js
import obj from './y.js';
console.log(obj.y1());
console.log(obj.y2());
Now using es2015 style using require, z.js
function dude() {
return "Dude";
}
module.exports = dude;
main.js
var d = require('./z');
console.log(d.dude1());
Now using es2015 style using require for multiple modules,
z.js
function dude() {
return "Dude";
}
function dudex() {
return "Yo Dude";
}
module.exports = {
dude1: dude,
dude2: dudex
}
main.js
var d = require('./z');
console.log(d.dude1());
Before ES6
var user = {name: 'Deepen', age: 26};
var name = user.name; // 'Deepen'
var age: user.age; // 26
Using ES6
var { name, age } = {name: 'Deepen', age: 26};
console.log(name); // 'Deepen'
console.log(age); // 26
Before ES6
var user = {name: 'Deepen', age: 26};
var nameX = user.name;
var ageX = user.age;
Using ES6
var user = {name: 'Deepen', age: 26};
var { name:nameX, age:ageX } = user;
If not present then provide default like this:
var user = {name: 'Deepen', age: 26};
var {name:nameX='', age:ageX=1};
var dudes = ['John', 'Smith', 'Deepen'];
var [d1, d2] = dudes;
console.log(d1); // 'John'
console.log(d2); // 'Smith'
Provide default value
var dudes = ['John'];
var [d1="Deepen", d2="Smith"] = dudes;
console.log(d1); // 'John'
console.log(d2); // 'Smith'
Swapping Array Values (Useless)
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
Pick values from array (Yuck, they could have made it better by specifying indexes either)
var dudes = [1,2,3,4,5];
var [,,d1, ,d2] = dudes;
console.log(d1); // 3
console.log(d2); // 5
When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern (In short, pick value and assign rest):
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
var [a, b, ...c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3]
Unpacking values from a regular expression match,
function parseProtocol(url) {
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
if (!parsedURL) {
return false;
}
console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
var [, protocol, fullhost, fullpath] = parsedURL;
return protocol;
}
console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"
var o = {x:1};
var p = {y:2, ...o}; // Output: {x:1, y:2}
var q = {o, ...y:2} // Output: {o: {x:1}, y:2}
{
function foo () { return 1 }
console.log("foo() === 1: ", foo() === 1)
{
function foo () { return 2 }
console.log("foo() === 2: ", foo() === 2);
}
console.log("foo() === 1: ", foo() === 1);
}
Output:
foo() === 1: true
foo() === 2: true
foo() === 1: true
- In arrow functions you cannot bind
this
. By Default it points to itself andthis
cannot be reassigned withcall
norapply
. - Arrow functions does not have
prototype
property.
function fn1() {}
const fn2 = () => {}
console.log(fn1.prototype); // {fn1()}
console.log(fn2.prototype); // undefined
- You cannot call new on Arrow function to create an object.
const UserDetails = (name) => {
this.name = name;
}
const user1 = new UserDetails(); // Uncaught TypeError: UserDetails is not a constructor
function dude(x, y, ...z) {
console.log(x, y, z);
}
dude(1,2,3,4,5)
Output:
1, 2, [3,4,5]
function getName(str) {
console.log(str);
}
getName`Deepen`
However, its value is pretty weird, ["Deepen", raw: ["Deepen", ......]]
But this doesnt work
var first = 'Deepen';
getName`${first}`
This is only acceptable for one string value
In short: waste of time, effort of developing this. Dont know who in the world would use this?
A container for variables and functions.
function greet() {
console.log('Hello');
}
greet.language='english';
console.log('Greet: ', greet);
Functions which can be passed around to a variable and created on the fly.
console.log(function() {return "dude";});
function logit(a) {
return a;
}
console.log(logit(function(){return "dude"}));
var o = {
a: () => {
console.log(this);
var some = () => {
console.log("some: ", this);
}
var someone = function() {
console.log("someone: ", this);
}
function sometwo() {
console.log("sometwo: ", this);
}
some();someone();sometwo();
return () => {console.log("return: ", this);};
},
b: function() {
console.log(this);
}
}
Consider this code.
function dude() {
var x =1;
console.log(dude);
}
dude();
function some(name) {
return () => {console.log(name);}
}
var someOne = some('Deepen');
someOne(); // Output: Deepen
Here Deepen is printed as outer context is destroyed when someOne()
is ran.
Its not only for parameterized variables but also for local variables created inside a function.
function what() {
var x = 'What Function';
return () => {console.log(x)};
}
var whatever = what();
whatever(); // Output: What Function
Lets consider another example:
function buildFunctions() {
var arr = [];
for(var i=0;i<3;i++) {
arr.push(
function() {
console.log(i);
}
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();
/* Output:
3
3
3
*/
To make it 1,2,3
by creating another execution context inside that function.
function buildFunctions() {
let arr = [];
for(var i=0;i<3;i++) {
arr.push(
(function(j) {
return function() {
console.log(j);
}
})(i)
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();
You can also it just with let
. It will create 3 different references in closure.
function buildFunctions() {
var arr = [];
for(let i=0;i<3;i++) {
arr.push(
function() {
console.log(i);
}
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();
/* Output:
1
2
3
*/
Every Object has a property called __proto__
which makes inheritance possible in javascript. Consider following example:
var person = {
firstname: 'Default',
lastname: 'Default',
getFullName: function() {
return this.firstname + ' ' + this.lastname;
}
}
var john = {
firstname: 'John', lastname: 'Doe'
}
// Link to a parent
john.__proto__ = person;
console.log(john.__proto__.firstname) // Default
console.log(john.getFullName()) // John Doe
var jane = {
firstname: 'Jane'
};
jane.__proto__ = person;
console.log(jane.__proto__.firstname) // Default
console.log(jane.getFullName()) // Jane Default
You should access __proto__
directly, rather use this encapsulated way:
Object.getPrototypeOf(john);
Object.getPrototypeOf(jane);
It will return the object which __proto__
is referring to.
On the other hand, prototype
is a property on function object. Consider, prototype
as the blueprint or class of the object, for example.
function Dog() {}
var dog1 = new Dog();
console.log(dog1.prototype); // {Dog()} <-- this points to blueprint or prototype(english) of the object.
var Person = {
firstname: 'Default',
lastname: 'Default',
getFullName() {
return this.firstname+' '+this.lastname
}
};
var fullname = {
firstname: 'Deepen',
middlename: 'Naresh',
lastname: 'Dhamecha'
}
fullname.__proto__ = Person;
for(var key in fullname) {
console.log("Key: ", key);
console.log("Value: ", fullname[key]);
}
It will also print getFullName()
. As it is attached to its prototype. To consider only its own properties.
for(var key in fullname) {
if(fullname.hasOwnProperty(key)) {
console.log("Key: ", key);
console.log("Value: ", fullname[key]);
}
}
function Person() {
this.firstname = 'Deepen';
this.lastname = 'Dhamecha';
}
If you do this, then it will assign properties and methods on global/window and p1
will be undefined
since its just a normal function without returning anything.
var p1 = Person();
But with new
keyword,
var p2 = new Person(); // Output: Person {firstname: 'Deepen', lastname: 'Dhamecha'}
This will create a new empty object and assign those properties and methods to it.
If you want to return new object altogether then return from function.
function Person2() {
this.firstname = 'Deepen';
this.lastname = 'Dhamecha';
return {greetings: 'Hello';}
}
var p3 = new Person2();
console.log(p3);
So you can make it like this,
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
var john = new Person('John', 'Doe');
console.log(john);
var jane = new Person('Jane', 'Doe');
console.log(jane);
When you do new Person()
, it creates a function object.
Consider this example,
function Dog() {}
Dog.prototype.breed = 'BullDog';
var dog1 = new Dog();
console.log(dog1.prototype); // undefined
console.log(Dog.prototype); // {breed: 'BullDog', constructor: f}
prototype
property is bound to functions and not its object. prototype
is used when creating objects.
Above showcases on Dog function object but what about object.
Consider this,
console.log(dog1); // Dog {}
console.log(dog1.__proto__); // {breed: 'BullDog', constructor: f}
console.log(dog1.__proto__.__proto__); // {constructor: f, class: Object}
console.log(dog1.__proto__.__proto__.__proto__); // null
console.log(dog1.hasOwnProperty('breed')); // false
So, if you check dog1
object, then breed
is not on the object itself but rather on its parent object.
So, what prototype
does is, when new
is invoked on a function, it checks for any prototype assigned. If assigned, then
it creates an object of type Dog, assigns prototype attributes to it and links it to __proto__
of the object.
You can write
import { dude } from 'filename';
But for this to work, you need to specify one of the 3 things:
- File extension as
.mjs
. "type":"module"
in package.json at the root.- node --input-type=module
No require, exports, or module.exports In most cases, the ES module import can be used to load CommonJS modules.
If needed, a require function can be constructed within an ES module using module.createRequire().
No __filename or __dirname These CommonJS variables are not available in ES modules.
__filename and __dirname use cases can be replicated via import.meta.url.
No Addon Loading Addons are not currently supported with ES module imports.
They can instead be loaded with module.createRequire() or process.dlopen.
No require.resolve Relative resolution can be handled via new URL('./local', import.meta.url).
For a complete require.resolve replacement, there is a flagged experimental import.meta.resolve API.
Alternatively module.createRequire() can be used.
No NODE_PATH NODE_PATH is not part of resolving import specifiers. Please use symlinks if this behavior is desired.
No require.extensions require.extensions is not used by import. The expectation is that loader hooks can provide this workflow in the future.
No require.cache require.cache is not used by import as the ES module loader has its own separate cache.
Set Unique values
var arr = [1,2,3,4];
let mySet = new Set(arr);
console.log(mySet);
for(let s of mySet) {
console.log(s);
}
Map Key => Value pair
let myMap = new Map([['a1', 'Deepen'], ['a2','Dhamecha']]);
for(let [key, value] of myMap) {
console.log(`key: ${key}, value: ${value}`);
}
WeakSet
and WeakMap
are same except that it cannot be iterated.
Event bubbling is event propogating from child to parent.
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div style="padding: 10px;background-color:red;">
<button>Click me</button>
</div>
<script>
var div = document.querySelector('div');
var btn = document.querySelector('button');
div.addEventListener("click", function() {
console.log('div');
});
btn.addEventListener("click", function() {
console.log('button');
});
</script>
</body>
</html>
Output:
button
div
Event Capturing is very rare where event is propagating from parent to child.
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div style="padding: 10px;background-color:red;">
<button>Click me</button>
</div>
<script>
var div = document.querySelector('div');
var btn = document.querySelector('button');
div.addEventListener("click", function() {
console.log('div');
}, true);
btn.addEventListener("click", function() {
console.log('button');
}, true);
</script>
</body>
</html>
Set true
after listener, which reverses event bubbling.
When you modify the above code
btn.addEventListener("click", function(event) {
console.log('button');
event.stopPropagation();
});
It prints:
Output:
button
stopPropagation()
stops the propagation to its parent. Remember, parent and above and not same sibling or same element.
btn.addEventListener("click", function(event) {
console.log('button');
event.stopPropagation();
});
btn.addEventListener("click", function(event) {
console.log('button 2');
});
Here, button and button2 will be printed.
Function has a length property which has value of number of parameters.
You cannot this attached with bind
to an arrow function.
This is also known as partial application feature.
let sum = (x,y) => x+y;
let succ = sum.bind(null, 1);
console.log(succ(2)); // Output: 3;
function f(y,z) { return this.x + y + z;}
let g = f.bind({x:1}, 2);
console.log(g(3)); // Output: 6
Because functions are objects, there is Function()
constructor that can be used to create new functions:
const f = new Function("x", "y", "return x*y");
This line of code creates a new function that is more or less equivalent to a function defined with familiar syntax:
const f = function(x,y) {return x*y};
There are a few points that are important to understand about the Function() constructor:
- The Function() constructor allows JavaScript functions to be dynamically created and compiled at runtime.
- The Function() constructor parses the function body and creates a new function object each time it is called. If the call to the constructor appears within a loop or within a frequently called function, this process can be inefficient. By contrast, nested functions and function expressions that appear within loops are not recompiled each time they are encountered.
- A last, very important point about the Function() constructor is that the functions it creates do not use lexical scoping; instead, they are always compiled as if they were top level functions, as the following code demonstrates:
let scope = "global";
function constructFunction() {
let scope = "local";
return new Function("return scope"); // Doesn't capture local scope!
}
// This line returns "global" because the function returned by the
// Function() constructor does not use
// the local scope.
constructFunction()() // => "global"
The Function()
constructor is best thought of as a globally scoped
version of eval()
that defines new variables and
functions in its own private scope.
A higher-order function is a function that operates on functions, taking one or more functions as arguments and returning a function. Check below,
function not(f) {
return function(...args) {
const result = f.apply(this, args);
return !result;
}
}
const even = x => x % 2 === 0;
const odd = not(even);
[1,1,3,5,5].every(odd);
This not()
function is a higher-order function because it takes a function argument and returns a new function.
let a = ["1", "1", "2", "3", "3", "1"];
let a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((item, i, ar) => ar.indexOf(item) === i);
console.log(unique);
Consider this object.
const pet = {name: "Kitty", age: 20};
const dog = {name: "Babubhai"};
dog.__proto__ = pet;
console.log(dog.hasOwnProperty('name')); // true
console.log(dog.hasOwnProperty('age')); // false
// But with in operator
console.log('name' in dog); // true
console.log('age' in dog); // true
It checks in parent object as well.
If two objects inherit from the same prototype, this typically (but not necessarily) means that they were created and initialized by the same constructor function or factory function.
JavaScript has always allowed the definition of classes. ES6 introduced a brand-new syntax (including a class keyword) that makes it even easier to create classes.
New Javascript classes work in the same way that old-style classes.