1. Write the new keyword by hand

Note: when creating an instance Object, the new keyword must return the type Object. If the value is not an Object, the return is invalid.

/ / native:
function Person(name) {
	this.name = name;
	return 1;
}
const p = new Person("Zhang");
console.log(p); // Person { name: '张三' }

// Write code:
function createObj(. args) {
	const obj = {};
	const Constructor = args.shift();
	obj.__proto__ = Constructor.prototype;
	const ret = Constructor.apply(obj, args);
	return typeof ret === "object" ? ret : obj;
}
Copy the code

2. The handwritten instanceof

function myInstanceof(instance, constructor) {
	let proto = instance.__proto__
	while (proto) { // Terminates with null
		if (proto === constructor.prototype) {
			return true
		} else {
			proto = proto.__proto__
		}
	}
	return false
}
Copy the code

3. Array flattening

Other methods reference

function flat(arr) { 
        return result = arr.flat(Infinity); 
}
Copy the code

4. The throttle

Simple definition: execute a function only once per unit of time. Specifies that a function can fire only once per unit of time. If more than one function is fired in this unit of time, only one function will take effect.

// Time stamp version
function throttle(func, delay) {
	let last = 0;
	return function () {
		const now = Date.now();
		if (now >= last + delay) {
			func.apply(this.arguments);
			last = now;
		} else {
			console.log("Non-execution"); }}; }// Timer version
function throttle2(func, delay) {
	let timer;
	return function () {
		if(! timer) { func.apply(this.arguments);
			timer = setTimeout(() = > {
				timer = null; // Remember to empty
			}, delay);
		} else {
			console.log("Non-execution"); }}; }Copy the code

5. If you

Simple definition: Execute the last function per unit of time. The callback is executed n seconds after the event is triggered, and if it is triggered again within n seconds, the timer is reset. The difference between stabilization and throttling is that the function is called many times over a period of time, making only the last call valid.

function debounce(func, delay) {
	let timer;
	return function () {
		clearTimeout(timer);
		timer = setTimeout(() = > {
			func.apply(this.arguments);
		}, delay);
	};
}
Copy the code

6. Shuffle arrays randomly

// The randomness is not large enough, mainly due to the principle of sort's native function
function shuffle(array) {
    array.sort(() = > { Math.random() - 0.5 }); // sort changes the original array
}
// Feasible random function
function shuffle(array) {
	let m = array.length,
		t,
		i;
	while (m) {
		i = Math.floor(Math.random() * m--);
		t = array[m];
		array[m] = array[i];
		array[i] = t;
	}
	return array;
}
Copy the code

7. Array deduplication

// use traversal +Map
function uniqueArr(arr) {
	const map = {};
	const result = [];
	arr.forEach(el= > map[el] || ((map[el] = true), result.push(el)));
	return result;
}
/ / use the Set
function uniqueArr(array) {
	return [...new Set(array)];
}
Copy the code

8. Coriolization of functions

Definition: Currying is a technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function), and returning a new function that takes the remaining arguments and returns a result.

function add(. args) {
	const _args = Array.prototype.slice.call(args);
	const _adder = function (. args2) { _args.push(... args2);return _adder;
	};
	_adder.toString = function () {
		return _args.reduce(function (a, b) {
			return a + b;
		}, 0);
	};
	return _adder;
}
//test code
add(1.2.3); / / 6
add(1) (2) (3); / / 6

// Parameter multiplexing
function uri_curry(protocol) {
	return function (hostname, pathname) {
		return `${protocol}${hostname}${pathname}`;
	};
}
const uri_base = uri_curry("https://");
const uri_baidu = uri_base("www.baidu.com"."/search");
const uri_ali = uri_base("www.ali.com"."/taobao");
const uri_tencent = uri_base("www.tencent.com"."/qq");

//test code
console.log(uri_baidu); //https://www.baidu.com/search
console.log(uri_ali); //https://www.ali.com/taobao
console.log(uri_tencent); //https://www.tencent.com/qq
Copy the code

Three characteristics of currization of functions

  1. Parameters of reuse
  2. Return early
  3. Delay the

Deferred execution means that when we call the method, we don’t execute it immediately, or we don’t execute what we really want to execute until the parameters are specified. As in add(1)(2)(3), when 1, 2, and 3 are passed in, the function does not add, but pushes the value to the queue, and only executes if no arguments are passed.

8. Iterator

In fact, a data structure is said to be “iterable” whenever the Iterator interface is deployed. ES6 states that the default Iterator interface is deployed in the symbol. Iterator property of data structures, or that a data structure can be considered “iterable” as long as it has the symbol. Iterator property.

function createIterator(items) {
	let index = 0;
	return {
		next: function () {
			let done = index >= items.length;
			letvalue = ! done ? items[index++] :undefined;
			return{ done, value }; }}; }//test code
const arr = ["a"."b"];
for (let val of arr) {
	console.log(val); // Print a b
}
arr[Symbol.iterator] = () = > createIterator([1.2.3]);
for (let val of arr) {
	console.log(val); // Print 1, 2, 3
}
Copy the code

9. Implement LRU cache

LRU (Least Recently Used) is Used to eliminate unpopular data and retain hotspot data.

class LRU {
	constructor(size) {
		this.size = size;
		this.map = new Map(a); }get(key) {
		const val = this.map.get(key);
		if (key === undefined) {
			return -1;
		} else {
			this.map.delete(key);
			this.map.set(key, val); }}put(key, value) {
		const val = this.map.get(key);
		if (val === undefined) {
			this.map.size === this.size && this.map.delete(this.map.keys().next().value);
			this.map.set(key, value);
		} else {
			this.map.delete(key);
			this.map.set(key, value); }}}Copy the code

9.call apply bind

Function.prototype.myCall = function (context, ... args) {
	context = context || window;
	context.fn = this;
	constresult = context.fn(... args);delete context.fn;
	return result;
};
Function.prototype.myApply = function (context, args) {
	context = context || window;
	context.fn = this;
	constresult = context.fn(... args);delete context.fn;
	return result;
};
Function.prototype.myBind = function (context, ... args) {
	context = context || window;
	return () = > {
		this.apply(context, args);
	};
};

const obj = { name: "jr" };
const fn = function (a, b) {
	console.log(this.name, a, b);
};

// test code
fn.myCall(obj, 1.2);
fn.call(obj, 1.2);
fn.myApply(obj, [1.2]);
fn.apply(obj, [1.2]);
fn.myBind(obj, 1.2) (); fn.bind(obj,1.2) ();Copy the code