手写32javascript巩固一下子JS基础
Posted Hole
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写32javascript巩固一下子JS基础相关的知识,希望对你有一定的参考价值。
一。数组扁平化
概念:是指将一个多维数组变为一个一维数组。
var arr=[1,[2,[3,[4,5]]],6];
==>[1, 2, 3, 4, 5, 6]
方法一:arr.flat(Infinity);
方法二:JSON.parse("["+JSON.stringify(arr).replace(/\\[|]/g,"")+"]")
方法三: const arrCon=[];
const fn=arr=>{
for(let i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
fn(arr[i]);
}
else{
arrCon.push(arr[i]);
};
};
fn(arr);
有不懂flat()小伙伴们可以点击flat()
二。数组去重
var arr=[1,1,2,2,4,4,null,null];
==>[1,2,4,null]
方法一:Arry.from(new Set(arr));
方法二:双层for循环
function FFOR(arr){
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]===arr[j]){
arr.splice(j,1)
j--
}
}
}
return arr;
};
方法三:filter()+indexOf()
function ffor(arr){
return arr.filter(item,index,arr){
return arr.indexOf(item,0)===index;
}
};
方法四:indexOf
function FFOR(arr){
const arrCon=[];
for(let i=0;i<arr.length;i++){
if(arrCon.indexOf(arr[i])===-1){
arrCon.push(arr[i])
}
}
return arrCon
}
方法五:include()
function FFOR(arr){
const res=[];
for(let i=0;i<arr.lenght;i++){
if(!res.include(arr[i])){
res.push(arr[i])
}
}
return res
}
方法六:map()
function FFOR(arr){
const map =new Map();
const res=[];
for(let i=0;i<arr.length;i++){
if (!map.has(arr[i])) {
map.set(arr[i],true)
res.push(arr[i])
}
}
return res
}
三。类数组转为数组
概念:什么叫类数组,类数组具有length属性,但是没有数组原型上的一些方法,常见的类数组像arguments,Dom操作方法返回的结果。
方法一:Array.from
Array.from(document.querySelectorAll(\'div\'));
方法二:Array.prototype.slice.call
Array.prototype.slice.call(document.querySelectorAll(\'div\'));
方法三:扩展运算符
[...document.querySelectorAll("div")]
方法四:使用concat
Array.prototype.concat.apply([],document.querySelectorAll(\'div\'))
四。Array.prototype.filter()
filter() 方法创建一个新的数组,新数组中的元素是原数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
语法:array.filter(function(currentValue,index,arr), thisValue)
五。Array.prototype.map()
var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
return num * 2;
});
/* map()返回值是一个新数组 */
/* map()不会改变原始数组 */
六。Array.prototype.forEach()
const items = [\'item1\', \'item2\', \'item3\'];
const copy = [];
items.forEach(function(item){
copy.push(item)
});
七。 Array.prototype.reduce()
reduce()接受一个函数作为累加器,数组中的每个值开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
八。Function.prototype.apply()
apply()方法调用一个具有给定`this`值的函数,
以及以一个数组(或[类数组对象]的形式提供的参数。
九。Function.prototype.call()
call()方法使用一个指定的 `this` 值和单独给出的一个或多个参数来调用一个函数。
十。Function.prototype.bind()
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的 `this` 被指定为 `bind()` 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
call(),apply(),bind()的区别:
不同点:
参数类型:
call()方法接收的是参数列表,而apply()方法接 收的是参数数组。
参数个数:
call方法的参数可以无限个;
而apply方法的参数最多只能有两个。
bind()方法是创建一个新函数,与被调函数有相同的函数体
相同点:
call、 bind、 apply 这三个函数的第一个参数都是this的指向对象
十一。防抖
防抖是指在一段时间内,函数被触发多次,但是只执行一次,当在过一定的时间间隔就会再次执行一次。
使用场景:例如,在进行搜索的时候,当用户停止输入后调用方法,节约请求资源。
function debounce(fn, delay) {
let timeout = null;
return function () {
if (timeout) {
clearTimeout(timeout)
}
timeout=setTimeout(()=>{
fn.apply(this,arguments)
},delay)
};
}
十二。节流
节流是会有规律的每隔时间n就执行一次函数。节流常用于鼠标点击和监听滚动事件。
function throttle(fn,cycle){
let start=Date.now();
let now;
let timer;
return function(){
now=Date.now();
clearTimerout(timer);
if(now - start >=cycle){
fn.apply(this,arguments);
start=now;
}else{
timer = setTimerout(() = > {
fn.apply(this,arguments);
},cycle);
}
}
}
十三。函数柯里化。
指的是将一个接受多个参数的函数变为接受一个参数返回一个函数的固定形式,这样便于再次调用。
经典面试题:实现add(1)(2)(3)(4)=10
function add(){
const _args = [...arguments]
function fn(){
_args.push(...arguments);
return fn;
}
fn.toString = function(){
return _args.reduce(
(sum,cur) = > sum + cur
)
}
return fn;
}
模拟new操作
function newOperator(ctor,...args){
if (typeof ctor !== \'function\') {
throw new TypeError(\'Type Error\');
}
const obj=Object.create(ctor.prototype);
const res=ctor.apply(obj,args);
const isObject = typeof res === \'object\' && res !==null;
const isFunction = typeof res === \'function\';
return isObject || isFunction ? res : obj;
}
instanceof
instanceof用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。
const myInstacnceof = (left,right) =>{
/* 基本数据类型返回false */
if (typeof left !== \'object\' || left === null) {
return false;
}
let proto=Object.getPrototypeOf(left);
while (true){
if (proto === true) {
return false
}
if ( proto === right.prototype) {
return true
}
proto = Object.getPrototypeOf(proto);
}
}
原型链继承
function Parent(){
this.name = \'parent\';
}
function Child(){
Parent.call(this);
this.type = \'children\';
}
Child.prototype = Object.create (Parent.prototype);
Child.prototype.constructor = Child;
Object.is
Object.is主要解决这两个问题
+0 === -0
NaN === NaN
const is=(x,y)=>{
if(x===y){
return x !==0 || y!==0 || 1/x === 1/y;
}else{
return x !==x && y!==y;
}
}
Object.assign()
Object.assign()用于将所有可枚举属性的指从一个或者多个源对象复制到目标对象,它将返回目标对象。
注意:此方法是浅拷贝方法
深拷贝
Promise()
以上是关于手写32javascript巩固一下子JS基础的主要内容,如果未能解决你的问题,请参考以下文章