JS, sprav-info

top
https://habr.com/ru/articles/740934/
ECMAScript 2015, 2016, 2017, 2018, 2019, 2020, 2021

https://habr.com/ru/articles/741372/
Новые возможности ECMAScript 2021-2023

https://www.dev-notes.ru/articles/javascript/five-new-features-ecmascript-2024/
Пять новых возможностей JavaScript в 2024 году

https://rutube.ru/video/28b61af0943e83f522c4525167f0dd3d/
JavaScript объекты — сравнение, копирование, объединение, деструктуризация, остаточные параметры.
Генераторы – новый вид функций в современном JavaScript. 
Они отличаются от обычных тем, что могут приостанавливать своё выполнение, 
возвращать промежуточный результат и далее возобновлять его позже, 
в произвольный момент времени.

https://learn.javascript.ru/generator
------
https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Iterators_and_Generators

http://qaru.site/questions/183/how-do-i-return-the-response-from-an-asynchronous-call
Как вернуть ответ от асинхронного вызова?

https://javascript.ru/forum/misc/69563-asinkhronnyjj-vyzov-v-sinkhronnyjj.html
Асинхронный вызов в синхронный
https://youtu.be/M_pclb-58ZY?list=WL&t=4245

const person = {
	surname: "Ivanov",
	fullname: function( name ){

console.log( "Name:" + name + ", Surname: " + this.surname);

//использование шаблона для строки в апострофах
console.log( `Name: ${name} , Surname: ${this.surname}`);
	}
};
person.fullname( name: "John");

// вызов метода объекта person с контекстом объекта person2
const person2 = {
	surname: "Petrov"
};

person.fullname.call ( person2, "Peter");
person.fullname.apply ( person2, ["Peter"]);

const func = person.fullname.bind ( person2, "Peter");
func();

Object methods

https://learn.javascript.ru/object

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object
Свойства конструктора Object

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf


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/entries
Object.entries()

Object.fromEntries()

Object.create()

создаёт новый объект с указанными объектом прототипа и свойствами.

Object.freeze()

замораживает объект: это значит, что он предотвращает добавление новых свойств к объекту, удаление старых свойств из объекта и изменение существующих свойств или значения их атрибутов перечисляемости, настраиваемости и записываемости. В сущности, объект становится эффективно неизменным. Метод возвращает замороженный объект.

Object.keys()

возвращает массив из собственных перечисляемых свойств переданного объекта, в том же порядке, в котором они бы обходились циклом for...in (разница между циклом и методом в том, что цикл перечисляет свойства и из цепочки прототипов).
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.keys(location)

0: "href"
​1: "origin"
​2: "protocol"
​3: "host"
​4: "hostname"
​5: "port"
​6: "pathname"
​7: "search"
​8: "hash"
​9: "assign"
​10: "replace"
​11: "reload"
​			12: "toString"

​length: 13

Object.getOwnPropertyNames()

возвращает массив со всеми свойствами (независимо от того, перечисляемые они или нет), найденными непосредственно в переданном объекте.
//https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
...
Object.getOwnPropertyNames(localStorage)
...
var props = Object.getOwnPropertyNames( location );
console.log(props);

0: "href"
​1: "origin"
​2: "protocol"
​3: "host"
​4: "hostname"
​5: "port"
​6: "pathname"
​7: "search"
​8: "hash"
​9: "assign"
​10: "replace"
​11: "reload"
​				12: "toString"
				​13: "valueOf"
​
length: 14
​

Object.assign()

var obj1 = {
	"a":{"a1":1}
};
var obj2 = {"b":2};
var obj3= {};

Object.assign(obj3, obj1, obj2);
console.log(obj3);

//----------------------
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

//extend object obj1
var obj1 = {
  "a" : 1,
  "b" : 2,
  "c" : 3
};

var obj2 = {
  "b" : 12,
  "c" : 13,
  "d" : 4
};

//obj1=obj2;//+++++replace obj
for(var key in obj2 ){
   obj1[key] = obj2[key];
}

console.log(obj1);

Array methods

arr.indexOf()
arr.findIndex()
arr.includes()
arr.some()
arr.every()
arr.find()
arr.filter()
arr.map()
arr.reduce()
arr.reverse()
arr.sort()


https://rutube.ru/video/369888e58e9edd078806bb922a242af0/?playlist=442452
Методы массивов JavaScript — forEach, map, filter, reduce, some, every, sort, includes, indexOf
	
http://javascript.ru/Array

http://learn.javascript.ru/array
Массивы с числовыми индексами

https://learn.javascript.ru/array-iteration
Массив: перебирающие методы

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

https://zlob.in/2014/06/vsyo-chto-vy-xoteli-znat-o-massivax-v-javascript/

http://javascript.ru/String/indexOf
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

http://javascript.ru/array/concat
https://www.w3schools.com/jsref/jsref_concat_array.asp

$.merge()
http://jquery.page2page.ru/index.php5/%D0%9E%D0%B1%D1%8A%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D0%BE%D0%B2

Array.map()

//http://learn.javascript.ru/array-iteration

//copy all values from arr1 to arr2
var arr1 = [{"key": "value1"}, {"key": "value2"}, {"key": "value3"}];

var arr2 = arr1.map( function( element, index){
console.log(element, index);
  return element["key"];
});

console.log(arr2);
//Array(3) [ "value1", "value2", "value3" ]
		

Array.forEach()

<script>
console.log(typeof Array.prototype.forEach);

var testArr = ["One", "Two", "Three"];
	testArr.forEach(function(el, num){
console.log(el, num);
	});//next
</script>

http://javascript.ru/php/in_array
http://www.w3schools.com/jsref/jsref_indexof_array.asp
https://learn.javascript.ru/array-iteration
		

Array.filter()


var arr = [ 1, 2, 3 ];
var arr2 = arr.filter( function(element, index){
//console.log(arguments);
  if( element === 2){
      return element;
  }
});
console.log(arr2);// arr2 = [2]

=================
var arr = [
  {"a":1},
  {"b":2},
  {"c":3},
];

var arr2 = arr.filter( function(element, index){
//console.log(arguments);
  for( var key in element){
//console.log( key, element[key]);

    if( key === "b"){
        return element;
    }

  }
});
console.log(arr2);// arr2 = [2]
		

Array.slice(),copy array to another....

var arr = [
"DAUGAVPILS",//1
"JELGAVA",//1
"JĒKABPILS",//1
"JŪRMALA",//1
"LIEPĀJA",//1
"RĒZEKNE",//1
"RĪGA",//1
"VALMIERA",//1
"VENTSPILS",//1
"AIZKRAUKLES NOVADS, AIZKRAUKLE",//2
"LĪGATNES NOVADS, LĪGATNE",//2
"VARAKĻĀNU NOVADS, VARAKĻĀNI"//2
];
var arr2 = arr.slice(0, 9);
console.log( arr2 );
		
https://learn.javascript.ru/array-methods
получение уникальных значений

function unique(arr) {
  var obj = {};

  for(var n = 0; n < arr.length; n++){
    var str = arr[n];
    obj[str] = true; // запомнить строку в виде свойства объекта
  }
  return Object.keys(obj);
}

var strings = ["кришна", "кришна", "харе", "харе",
  "харе", "харе", "кришна", "кришна", "8-()"
];

console.log( unique(strings) );
		
//test
var ar1 = [];
var ar2 = [];

var rec1 = {"a" : 1};
var rec2 = {"b" : 2};
var rec3 = {"c" : 3};

ar1.push(rec1);
ar1.push(rec2);
ar1.push(rec3);

var rec11 = {"a" : 11};
var rec12 = {"b" : 12};
var rec13 = {"c" : 13};
var rec4 = {"d" : 4};

//ar2.push(rec11);
ar2.push(rec12);
ar2.push(rec13);
ar2.push(rec4);


ar1=ar2;
console.log(ar1);

Замыкания

http://javascript.ru/basic/closure
https://learn.javascript.ru/functions-closures
http://myrusakov.ru/javascript-anonym-and-callback-functions.html
http://www.codehint.ru/articles/2014-07-27_javascript-self-invoking-functions
http://habrahabr.ru/post/117069/

замыкание

// вызов counter(), увеличивается переменная уже отработавшей функции test_closure()
// т.е. через внутреннюю функцию func() остался доступ к currentCount
function test_closure() {
	var currentCount = 1;
	var func = function(){
		return currentCount++;
	}
	return func
}
var counter = test_closure();
console.log ("counter - " + counter() );//1
console.log ("counter - " + counter() );//2
console.log ("counter - " + counter() );//3

--------------
//замыкание2
//Илья Кантор - Современный учебник JavaScript - 2015/1. Язык JavaScript.pdf, c.294
function makeCounter()
{
  var currentCounter = 1;
  return function(){
    return currentCounter++;
  };
}

var counter1 = makeCounter();
console.log( counter1() );
console.log( counter1() );
console.log( counter1() );

--------------
function makeBuffer() {
/*вашкод*/
}

var buffer=makeBuffer();//добавить значения к буферу
buffer('Замыкания');
buffer('Использовать');
buffer('Нужно!');//получить текущее значение
alert(buffer());//Замыкания Использовать Нужно!
//===================================
function makeBuffer() {
	var counter = "";
	return function(v){
		if(typeof v !== "undefined")
		{
			counter += v;
		}
		else
		{
			return counter;
		}
	};
}

var buffer = makeBuffer();
buffer("a"); buffer("b"); buffer("c");
console.log( buffer() );

Область видимости Замыкания

https://docs.google.com/presentation/d/1kiP65zcwktVGPloqLCCS9TEsp94YIVS20600KLSCwv4/edit?usp=sharing

//var num = 0;

function fcount(x){
  return function(){
console.log(x);
   x++;
  }
}

var count = fcount(3);
count();//3
count();//4
count();//5
1.
	for(var n = 0; n<10; n++){

		//closures
		(function(num){
			setTimeout(function(){
				console.log( num );
			}, 1000);
		})(n);//end closure

	}//next
	//0 1 2 3 4 5 6 7 8 9
2.
	function myFunc(num){
		setTimeout(function(){
console.log( num );
			}, 1000);
	}//end myFunc()

	for(var n = 1; n<=5; n++){
		myFunc(n);
	}//next

	//1 2 3 4 5

Конструкторы

function MyConstructor(a,b){
	this.a = a;
	this.b = b;
	this.sum = a + b;

	function private_method()
	{
		return "частный метод, недоступен для вызова в потомках MyConstructor";
	}

	//привилегированный метод (доступен публично и может использовать внутренние св-ва и методы)
	var x = 5;
	var y = 6;
	this.priv_method_get = function(){
		return x + y;
	}
}

obj1 = new MyConstructor(2, 2);
console.log("obj1.sum = ", obj1.sum);
console.log("obj1.constructor = ", obj1.constructor);
console.log( obj1.x );
console.log( obj1.priv_method_get() );

obj2 = new MyConstructor(20, 20);
console.log("obj2.sum = ", obj2.sum);
console.log("obj2.constructor = ", obj2.constructor);


// prototype function (for all children obj)
// объявление функции test_prototype в прототипе объекта MyConstructor
// эта функция будет доступна всем потомкам MyConstructor (obj1, obj2)
MyConstructor.prototype.test_prototype = function()
{
	console.log( "test_prototype say - " +this.sum );
}

obj1.test_prototype();

//===========================================================
function test_constructor()
{
  this.a = "A";
  this.b = 2+3;
  this.c = function myFunc()//привилегированный метод (доступен публично и может использовать внутренние св-ва и методы)
  {
return "function myFunc, " + (this.a+this.b)
  }

}

var test = new test_constructor();

console.log( test.a );
console.log( test.b );
test.c();
//========================================
//Илья Кантор - Современный учебник JavaScript - 2015
//Свойство-константа

"use strict"//!!!!

var user = {};

Object.defineProperty(
	user,
	"name",{
		value:"User Name",
		writable:false,
		configurable:false
	}
);

user.name = "new User Name";//error TypeError: "name" is read-only


//==================================== OOP
function CoffeeMachine( power )
{
alert("Create Coffee Machine with power:" + power +"Vt");

	this.test_waterAmount = 0;//public property
	var waterAmount = 0;//private property

	var WATER_HEAT_CAPACITY = 4200;
	var COFFEE_MACHINE_CAPACITY = 500;
	var WATER_TEMPERATURE = 80;

	var self = this;
	var timer;

	function getBoilTime()
	{
		return self.waterAmount * WATER_HEAT_CAPACITY * WATER_TEMPERATURE;
	}

	function onReady()
	{
		alert("Coffee is ready!");
	}

	this.run = function(){
		timer = setTimeout( onReady, getBoilTime() );
	}

	this.stop = function(){
		clearTimeout( timer );
	}

	//setter method
	this.setWaterAmount = function(amount){
		if( amount < 0 )
		{
			throw new Error("error! value could not be < 0");
		}
		if( amount > COFFEE_MACHINE_CAPACITY )
		{
			throw new Error("error! amount could not be > " + COFFEE_MACHINE_CAPACITY);
		}
		waterAmount = amount;
	}

	//getter method
	this.getWaterAmount = function(){
		return waterAmount;
	}
}

var coffeeMachine = new CoffeeMachine(100);

//cofeeMachine.waterAmount = 200;
cofeeMachine.setWaterAmount = 600;//use setter, method with test on error

cofeeMachine.run();
cofeeMachine.stop();
		

Прототипы

https://learn.javascript.ru/prototypes
https://learn.javascript.ru/prototype-inheritance	
https://learn.javascript.ru/prototype

создание связи объектов (прототипирование), способы

1.Свойство "prototype"

function Foo() { 
	console.log("This is a test function....");
};
var a = new Foo(); // родит. объект обязательно типа function
console.log( Foo.prototype ); 

Foo.prototype.b = 7; // создание св-ва b для всех прототипов
for(var key in a){ 
console.log( key, a[key])
}
//b 7

//---------------
console.log ( a.constructor); // function Foo()
console.log( a instanceof Foo ); //instanceof годится только чтобы узнать связь между объектом и функцией!

2."Object.create"

		
var anotherObject = {
	a: 2
};
var myObject = Object.create( anotherObject );
console.log( myObject.a ); //2

console.log( Object.getPrototypeOf( myObject ) ); 
console.log( myObject.prototype); //undefined
console.log ( myObject.constructor); //undefined

console.log( anotherObject.isPrototypeOf( myObject ) ); //true

3. "setPrototypeOf"

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf


Object.setPrototypeOf(obj, prototype);

var obj1 = {
	a: 1
};
var obj2 = {};
Object.setPrototypeOf( obj2, obj1);

console.log(obj1.isPrototypeOf( obj2 ) );//true

console.log( obj2.a );// 1

obj1.a = 100;
console.log( obj2.a ); //100

4. "__proto__"

https://learn.javascript.ru/prototype

var animal = {
  eats: true
};
var rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

// в rabbit можно найти оба свойства
console.log ( rabbit.jumps ); // true
console.log ( rabbit.eats ); // true

console.log ( Object.getPrototypeOf( rabbit ) ); // Object { eats: true }
-----------
 способ допускается, но так делать не следует. 
 Ссылка __proto__ была документирована только в стандарте ES6, 
 и преимущественно используется только для чтения.
	

затенение свойства

Если a находится выше по цепочке [[Prototype]], но отмечено как только для чтения (writable:false), то установка значения этого существующего свойства, равно как и создание затененного свойства у myObject, запрещены. Если код выполняется в strict mode, то будет выброшена ошибка, если нет, то попытка установить значение свойства будет проигнорирована. В любом случае, затенения не происходит.

var anotherObject = {};
Object.defineProperty(anotherObject, "a", {
	value:2,
	writeble:false
});

var myObject = Object.create(anotherObject);
myObject.a = 4; // создание св-ва невозможно, т.к. у родителя одноименное св-во readonly !!!!!!!!!

console.log( anotherObject.a ); //2
console.log( myObject.a ); // 2 значение получено из свойства родителя - anotherObject.a !!!!!

console.log(anotherObject.hasOwnProperty("a"));
console.log(myObject.hasOwnProperty("a"));
-- Свойства [[Prototype]], [[Get]], [[Put]]
-- "Классы", "конструкторы", "наследование", 
-- Проверка экземпляров класса"
-- Создание прототипной связи между двумя объектами
-- Классы ES6

паттерны делегирование и стратегию на чистых прототипах

Доклад: https://docs.google.com/presentation/d/1-Wg8Zu4rz1oMqgyzlOrIUNeIrOOIedL3Y3qCDhmSTmM/edit?usp=sharing

тест по прототипам https://docs.google.com/forms/d/e/1FAIpQLSfFpdGga0vgtYRHzEEYnJ8UQXb9zIeRR--R9FyZfMg10sl9Sg/viewform

Classes

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes

https://learn.javascript.ru/classes

https://rutube.ru/video/3a94ebab1346048749ff2501a9035544/
Классы в JavaScript — объявление, конструктор, наследование, экземпляр, геттеры и сеттеры

class declaration

class Class1{
  constructor(name){
console.log("...create object of Class1...");
    this.name = name;
  }
  
  method1(){
console.log("method1, name:", this.name);
  }//
  
}//end class
let firstObj = new Class1("test");
firstObj.method1();

class expression

var Class1 = class {
  constructor(name){
console.log("...create object of Class1...");
    this.name = name;
  }
  
  method1(){
console.log("method1, name:", this.name);
  }//
  
}//end class
let firstObj = new Class1("test");
firstObj.method1();

Prototype variant

function Class1(name){
    this.name = name;
}
  
Class1.prototype.method1 = function(){
console.log("method1, name:", this.name);
}//
  
let firstObj = new Class1("test");
firstObj.method1();

setter / getter

class Class1{

	//replace standart setter
	set oneProp (value){
		this._oneProp = value.toUpperCase();
	}

	//replace standart getter
	get oneProp(){
		return this._oneProp;
	}
	
}//end class

let firstObj = new Class1();

firstObj.oneProp = "some value";
console.log( firstObj.oneProp );

extends, children class

class Class1{
  constructor(name){
console.log("...constructor Class1...");
    this.name = name;
  }
  
  method1(){
console.log("method1");
  }//
	
}//end class

class Class2 extends Class1 {
  constructor(){
	super();
console.log("...constructor Class2...");
  }
  method2(){
	super.method1();
console.log("method2");
  }//

}
let secondObj = new Class2();
secondObj.method2();

public / private

class Class1 {
	publicProp = null;
	#privateProp = null;

	constructor(){
		this.#privateMethod()
	}//
  
	publicMethod(){
		this.publicProp = "123";
		this.#privateProp = "456";
console.log("use privateProp:", this.#privateProp);
	}//
	
	#privateMethod(){
console.log("...this is privateMethod()");
	}//
	
}//end class

let firstObj = new Class1();
firstObj.publicMethod();

console.log(firstObj.publicProp);

//console.log(firstObj.#privateProp);
//Uncaught SyntaxError: reference to undeclared private field or method #privateProp

//firstObj.#privateMethod();
//Uncaught SyntaxError: reference to undeclared private field or method #privateMethod

static properties and methods

class Class1 {
	prop1 = "abc";
	static prop2 = "def";
	
	method1(){
console.log("...this is method1()");
	}//
	
	static method2(){
console.log("...this is method2()");
	}//
	
}//end class

//Class1.method1();//Uncaught TypeError: Class1.method1 is not a function
Class1.method2();//ok

console.log(Class1.prop1);//undefined
console.log(Class1.prop2);//ok

Promise, async/await

Promise info

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://learn.javascript.ru/promise
https://www.sitepoint.com/overview-javascript-promises/

https://rutube.ru/video/e2045bd9d66876ee02a2867f550cf732/?playlist=442452
JavaScript событийный цикл Event Loop, асинхронный код, промисы (Promise), async / await

https://habrahabr.ru/post/193598/
Ещё раз о Deferred/Promise

https://www.npmjs.com/package/promise-polyfill
Promise Polyfill

npm install promise-polyfill --save-exact
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>
		
function asyncFunc(){
	return new Promise(function(resolve, reject){//executor function
		setTimeout(function(){
			var num = Math.random();
			if(num > 0.5){
				resolve(num);
			} else {
				reject(num);
			}
		}, 3000);
console.log("set promise asyncFunc()...");
	});//end promise
}

function onFulFilled(res){
console.log( "-- THEN, promise resolve, res: "+ res );
}

function onRejected(res){
console.log( "-- THEN, promise reject, reason: "+res+" < 0.5..."  );
}

asyncFunc().then(onFulFilled, onRejected);
2.Chaining

function asyncFunc1(){
	return new Promise(function(resolve, reject){
		setTimeout(function(){
			var num = Math.random();
			if(num > 0.5){
				resolve(1);
			} else {
				reject(num);
			}			
		}, 3000);
	});//end promise
}

function asyncFunc2(){
	return new Promise(function(resolve, reject){
		setTimeout(function(){
			var num = Math.random();
			if(num > 0.5){
				resolve(2);
			} else {
				reject(num);
			}			
		}, 3000);
	});//end promise
}

asyncFunc1()
.then(function(res){
		return res
	})
.then(function(res){
console.log( res );
		return asyncFunc2();
	})
.then(function(res){
console.log( res );
	})
.catch(function(res){
console.log( "-- CATCH, promise reject, res: "+res);
})
.finally(function(){
console.log( "-- FINALLY, end promise chain.", arguments);
});
3.

function makeRequest(url){
	return new Promise(function(resolve, reject){
		const xhr = new XMLHttpRequest();
		
		xhr.open("GET", url);
		xhr.onload = function(e){
			resolve(xhr.responseText);
		};
		xhr.onerror = function(e){
			reject(xhr.statusText);
		};
		xhr.send();
		
	});//end promise
}// end makeRequest()


var url = "https://api.github.com/users/romanlaptev";
//https://jsonplaceholder.typicode.com/photos/
//https://jsonplaceholder.typicode.com/todos/
//https://catfact.ninja/fact
//https://catfact.ninja/facts
//https://catfact.ninja/breeds

makeRequest(url)
.then(
	function(res){
		console.log( "-- THEN, promise resolve, res: ", res );
	}, 
	function(res){
console.log( "-- THEN, promise reject, res: ",res);
	});

Async info

Node.js >= 7.6
https://caniuse.com/#feat=async-functions

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/await

https://habrahabr.ru/company/ruvds/blog/326074/
Async/await: 6 причин забыть о промисах

https://medium.com/@derzunov/%D0%B7%D0%B0%D1%87%D0%B5%D0%BC-%D0%BC%D0%BD%D0%B5-async-await-%D0%B2-javascript-fb0eadf46f35
Зачем мне async/await в JavaScript?
		

Fetch info

https://developer.mozilla.org/ru/docs/Web/API/Fetch_API
https://developer.mozilla.org/ru/docs/Web/API/Response
https://learn.javascript.ru/fetch
https://learn.javascript.ru/fetch-api

https://habr.com/ru/post/252941/
Введение в fetch

https://github.com/github/fetch
window.fetch polyfill
		
		
function sendForm(n) {
	let obj = Object.fromEntries(calculatorMap);

	fetch("/calculator/mail.php", {
		method: 'post',
		body: JSON.stringify({ items: obj, name: n.name.value, phone: n.phone.value, code: n.code.value }),
		headers: {
			'Content-Type': 'application/json'
		}
	}).then(function (response) {
		return response.text();
	}).then(function (text) {
		if (text === 'ok') {
			ym(51755942, 'reachGoal', 'calculator');
			alert('Спасибо! Ваша заявка получена, мы свяжемся с Вами в ближайшее время.');
			n.classList.remove('codesent');
			n.reset();

		} else {
			alert(text);
		}
	}).catch(function (error) {
		log('Request failed', error)
	});
}		

Modules

info

https://learn.javascript.ru/modules-intro			

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/import
https://learn.javascript.ru/modules

			
https://rutube.ru/video/061214c1fcc37f92e078b1f9b198c170/?playlist=442452
Модули в JavaScript, import и export, декомпозиция кода

http://largescalejs.ru/

Модули не работают локально. Только через HTTP(s) !!!!!!!!
		
Шаблон Модуль
---------------

var test_module = function(){
  var version = "1.0";

  function _get_version(){
    return "Module version is " + version;
  }
  
  return {
    get_version : function(){
      return _get_version();
    }
  };
  
}();
test_module.get_version();

=========================================
(function(){
    function my_module(){
  console.log("my_module");
    }
    window.m = my_module();
  }()
);

m;
var config;
var MyModule = {
	settings: {
		num: 10,
		title: "My Module",
		description: "this is a test"
	},
	init: function() {
		config = this.settings;
	}
	
};

(function(){
	MyModule.init();
console.log(config);		
})();
(function(){
	var ZList = ZList || function(options){

		//обязательный элемент здесь будет автоматически хранится версия
		// из version control
		var _repositoryRevision = "$Rev$"; 

		// private variables and functions
		var _init = function(){
		};

		
		var _build = function(target){
			var html = "Table " + target + " is building....";
			return html;
		};
		
		// public interfaces
		return{
			revision:_repositoryRevision,
			build:	function(target){ 
				return _build(target); 
			}
		};
	};
	window.ZList = ZList;
})();


var table = ZList();
var html = table.build( "table1" );
//$("#insert_data").html( html );

window.onload = function(){
	document.getElementById("insert_data").innerHTML = "

Test module: " + html +"

"; }
<script src="js/numbers.js" type="module"></script>

-------- main.js
//import {one, two} from "./numbers";
//console.log( one, two );	

import {one as item1, two as item2} from "./numbers";
console.log( item1, item2 );	

import { sayHi as _func1} from "./numbers";
console.log( _func1 );

import * as module1 from "./numbers";
console.log( module1 );

------ numbers.js
export let one = 1;
export let two = 2;

export function sayHi() {
  alert("Hello!");
};
<!-- test export default, export consructor from module_user.js -->
<script src="login.js" type="module"></script>

<script type="module">
import { _user as newUser } from "./login"
console.log( "Login new user with name: " + newUser.name );

</script>

------ login.js
import User from './module_user';

var _user = new User("Vasya");
//console.log(_user);

export {_user};

------ module_user.js
export default class User {
  constructor(name) {
    this.name = name;
  }
};

// Пример jQuery плагина	
(function( $ ){

	$.fn.maxHeight = function(){
		var max = 0;
		this.each(function(){
			max = Math.max ( max, $(this).height() );
		});
		return max;
	};
	
})(jQuery);

$().ready(function(){
	$("#info").html("Test jQuery plugin: max height = " + $(".test").maxHeight() );
	
});

Code

Module template

	var sharedFunc =  sharedFunc || function(){
	
		// private variables and functions
		var _vars = {
			"logOrderBy": "DESC", //"ASC"
			"displayLog": true,
			"support": _testSupport()//,
		};//end _vars

		// private methods
		function _getById(id){
....
			return false;
		}//end _getById()


		// public interfaces
		return{
			vars : _vars,
			getById: _getById,
			init: function(){
				return _init();
			}
....
		};

	};//end sharedFunc

	//window.func = sharedFunc;
//})();
		
/*
use module:
//console.log("module sharedFunc:", typeof sharedFunc, sharedFunc);

	var func = sharedFunc();
//console.log("func:", func);

	func.vars["logOrderBy"] = "DESC";

	func.sortRecords({
		"records" : terminNodes,
		"sortOrder": "asc", //desc
		"sortByKey": "author"
	});
*/
		

переназначение функции по условию

var filelist_url;
function test( test_param )
{
	if ( test_param == "php")
	{
		var get_filelist = get_filelist_php;
	}

	if ( test_param == "aspx")
	{
		var get_filelist = get_filelist_aspx;
	}

	return get_filelist();
}

var get_filelist_php = function(){
	filelist_url = "include/filelist.php";
	return filelist_url;
}

var get_filelist_aspx = function(){
	filelist_url = "include/aspx/filelist.aspx";
	return filelist_url;
}

//console.log( test("php") );
console.log( test("aspx") );
		

Самовызывающиеся функции

	var my_func = (
		function( name ){
console.log("Hello " + name + " world!");
		}
	)("js");

	(function() {
console.log("Init !");
		}()
	);

	(function(){
console.log("Init 2");
	})();

//------------------------------
var a=1;

(function(){
var a = "i am self-invoke function";
console.log(a);
}())

var f1 = function(){
  var a = 3;
  console.log(a);
}
f1();

var f2 = function(){
  var a = 4;
  console.log(a);
}();

console.log(a);
		

Функции обратного вызова

	var test = function( callback ){
		var name = "Roman";
		callback (name);
	}

	test( function(n) {
console.log("Hello " + n);
	});

//"Стоян Стефанов. JavaScript. Шаблоны , c.96"
var setup = function(){
console.log( 1 );
	return function(){
		console.log( 2 );
	}
}

var f1 = setup();//1
f1();//2

		
//-------------------------
function _createRequestObject() {
	var request = false;

	if (window.XMLHttpRequest) { // Mozilla, Safari, Opera ...
//console.log("try use XMLHttpRequest");
		request = new XMLHttpRequest();
	}

	if(!request){ // IE
//console.log("try use Microsoft.XMLHTTP");
		request = new ActiveXObject("Microsoft.XMLHTTP");
	}

	if(!request){
//console.log("try use Msxml2.XMLHTTP");
		request=new ActiveXObject('Msxml2.XMLHTTP');
	}

	return request;
}//end _createRequestObject()

//**************************************
//  создать объект XMLHttpRequest
//**************************************
function getXMLDocument(url)  {  
	var xml;  
	if(window.XMLHttpRequest) {  
		xml=new window.XMLHttpRequest();  
		xml.open("GET", url, false);  
		xml.send("");  
		//alert (xml.responseText);
		return xml.responseXML;  
	}  else  {
		if(window.ActiveXObject) {  
			xml=new ActiveXObject("Microsoft.XMLDOM");  
			xml.async=false;  
			xml.load(url);  
			return xml;  
		}  else  {  
			alert("XML download is not supported in this browser");  
			return null;  
		}  
	}
}//end getXMLDocument

//============ create xmlhttprequest
var request = false;
try {
	request = new XMLHttpRequest();
} catch (trymicrosoft) {
	try {
   		request = new ActiveXObject("Msxml2.XMLHTTP");
 	} catch (othermicrosoft) {
   		try {
     		request = new ActiveXObject("Microsoft.XMLHTTP");
   		} catch (failed) {
    		request = false;
   		}  
 	}
}
return request;

is Array, is Object

var data = {key1:"a", key2:"b"}

>data instanceof Object
true

>data instanceof Array
false

if( data instanceof Object ){
	if( !(data instanceof Array) ){
console.log("data type is Object");
	}	
}
	
-------
var data = [1,2,3]
>data instanceof Array
true

>data instanceof Object
true

1.
if( data instanceof Object ){
	if( data instanceof Array ){
console.log("data type is Array");
	}	
}

2.
if( data instanceof Array ){
	if( data.lenght > 0 ){
console.log("data type is non-empty Array");
	}
}

//https://forms.amocrm.ru/forms/assets/js/moment/moment.js
function isArray(input) {
    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
}

function isObject(input) {
    // IE8 will treat undefined and null as object if it wasn't for
    // input != null
    return input != null && Object.prototype.toString.call(input) === '[object Object]';
}