One article helps you solve 90% of JS handwritten questions

Are you still afraid of handwritten questions? This article can help you expand and consolidate your JS foundation, and handle 90% of handwritten questions by the way. In the work, common requirements can also be realized by handwriting, such as deep copy, anti shake and throttling, which can be directly used in future projects to improve project development efficiency. No more nonsense, let's go directly to the code.

1.call implementation

  • When the first parameter is null or undefined, this points to the global object window. If the value is the original value, it points to the automatic wrapping object of the original value, such as String, Number and Boolean

  • In order to avoid the conflict between the function name and the attribute of the context, the Symbol type is used as the unique value

  • Execute the function as an incoming context attribute

  • Delete the property after the function is executed

  • Return execution result

"I am an old programmer who has been engaged in Web front-end development for 6 years. At the beginning of this year, I spent a month sorting out a full set of Web front-end training course (Video + source code + Notes + project practice) which is most suitable for self-study in 2021 Buddy buddy, from the most basic HTML+CSS+JS to mobile HTML5, and various frameworks and new technologies, have been packaged and packaged for every front end partner. This is the front end learning place. Welcome to beginners and advanced partners (all front-end courses are concerned about my WeChat official account: web front end learning circle, and then receive web after receiving the reply).

Function.prototype.myCall = function(context,...args){
    let cxt = context || window;
    //Define the currently called method in CXT Func (in order to bind this as an object call)
    //Create a unique Symbol variable to avoid duplication
    let func = Symbol() 
    cxt[func] = this;
    args = args ? args : []
    //Call func in the form of object call. At this time, this points to cxt#, that is, the incoming this point that needs to be bound
    const res = args.length > 0 ? cxt[func](...args) : cxt[func]();
    //Delete this method, otherwise it will pollute the incoming object (add this method)
    delete cxt[func];
    return res;
}

2. Implementation of apply

  • The first part is the same as call

  • The second parameter can not be passed, but the type must be array or class array

Function.prototype.myApply = function(context,args = []){
    let cxt = context || window;
    //Define the currently called method in CXT Func (in order to bind this as an object call)
    //Create a unique Symbol variable to avoid duplication
    let func = Symbol()
    cxt[func] = this;
    //Call func in the form of object call. At this time, this points to cxt#, that is, the incoming this point that needs to be bound
    const res = args.length > 0 ? cxt[func](...args) : cxt[func]();
    delete cxt[func];
    return res;
}

3. Implementation of bind

Consider:

  • bind() can pass in multiple parameters besides this;

  • The new function created by bind may pass in multiple parameters;

  • The new function may be called as a constructor;

  • Function may have a return value;

Implementation method:

  • The bind method will not be executed immediately and needs to return a function to be executed; (closure)

  • Implement scope binding (apply)

  • Parameter passing (array parameter passing of apply)

  • When used as a constructor, prototype inheritance is performed

Function.prototype.myBind = function (context, ...args) {
    //Create a new variable with the value this, indicating the current function
    const fn = this
    //Judge whether the parameter is passed in. If it is empty, assign []
    args = args ? args : []
    //Returns a newFn function in which fn is called
    return function newFn(...newFnArgs) {
        if (this instanceof newFn) {
            return new fn(...args, ...newFnArgs)
        }
        return fn.apply(context, [...args,...newFnArgs])
    }
}
  • test

let name = 'Xiao Wang',age =17;
let obj = {
    name:'Xiao Zhang',
    age: this.age,
    myFun: function(from,to){
        console.log(this.name + ' Age ' + this.age+'come from '+from+'Go to'+ to)
    }
}
let db = {
    name: 'Dema',
    age: 99
}

//result
obj.myFun.myCall(db,'Chengdu','Shanghai');     //Dema, aged 99, from Chengdu to Shanghai
obj.myFun.myApply(db,['Chengdu','Shanghai']);      //Dema, aged 99, from Chengdu to Shanghai
obj.myFun.myBind(db,'Chengdu','Shanghai')();       //Dema, aged 99, from Chengdu to Shanghai
obj.myFun.myBind(db,['Chengdu','Shanghai'])();   //Dema, aged , 99, from Chengdu, Shanghai to , undefined

4. Parasitic combinatorial inheritance

function Person(obj) {
    this.name = obj.name
    this.age = obj.age
}
Person.prototype.add = function(value){
    console.log(value)
}
var p1 = new Person({name:"tomato", age: 18})

function Person1(obj) {
    Person.call(this, obj)
    this.sex = obj.sex
}
//This step is the key to inheritance
Person1.prototype = Object.create(Person.prototype);
Person1.prototype.constructor = Person1;

Person1.prototype.play = function(value){
    console.log(value)
}
var p2 = new Person1({name:"egg", age: 118, sex: "male"})

5.6 succession

//class is equivalent to the constructor in es5
//When defining methods in class, you cannot add function before and after them. They are all defined in the protocol attribute of class
//All methods defined in class are not enumerable
//class can only define methods, not objects, variables, etc
//Strict mode is the default in class and method
//constructor in es5 is an implicit property
class People{
  constructor(name='wang',age='27'){
    this.name = name;
    this.age = age;
  }
  eat(){
    console.log(`${this.name} ${this.age} eat food`)
  }
}
//Inherit parent class
class Woman extends People{ 
   constructor(name = 'ren',age = '27'){ 
     //Inherit parent class properties
     super(name, age); 
   } 
    eat(){ 
     //Inherit parent method
      super.eat() 
    } 
} 
let wonmanObj=new Woman('xiaoxiami'); 
wonmanObj.eat();

//es5 inheritance first creates the instance object of the subclass, and then adds the method of the parent class to this (Parent.apply(this)).  
//es6 inheritance uses the keyword super to first create the instance object this of the parent class, and then modify this in the child class.

6. Implementation of new

  • One inherited from foo A new object of prototype is created.

  • Call the constructor Foo with the specified parameters and bind this to the newly created object. New Foo is equivalent to new Foo(), that is, Foo is called without any parameters without specifying a parameter list.

  • The object returned by the constructor is the result of the new expression. If the constructor does not explicitly return an object, use the object created in step 1.

  • Generally, the constructor does not return a value, but the user can choose to actively return the object to override the normal object creation steps

function Ctor(){
    ....
}

function myNew(ctor,...args){
    if(typeof ctor !== 'function'){
      throw 'myNew function the first param must be a function';
    }
    var newObj = Object.create(ctor.prototype); //Create one that inherits from ctor New object for prototype
    var ctorReturnResult = ctor.apply(newObj, args); //Bind this of constructor ctor to newObj
    var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
    var isFunction = typeof ctorReturnResult === 'function';
    if(isObject || isFunction){
        return ctorReturnResult;
    }
    return newObj;
}

let c = myNew(Ctor);

7. Implementation of instanceof

  • Instanceof is used to judge whether A is an instance of B. the expression is: A instanceof B. If A is an instance of B, it returns true; otherwise, it returns false.

  • The instanceof operator is used to test whether an object has the prototype attribute of a constructor in its prototype chain.

  • The basic data type cannot be detected. The results on the prototype chain may not be accurate. Null and undefined cannot be detected

  • Implementation: traverse the prototype chain of the variable on the left until the prototype of the variable on the right is found. If it is not found, it returns false

function myInstanceOf(a,b){
    let left = a.__proto__;
    let right = b.prototype;
    while(true){
        if(left == null){
            return false
        }
        if(left == right){
            return true
        }
        left = left.__proto__
    }
}

//The instanceof operator is used to determine whether the prototype attribute of the constructor appears anywhere in the prototype chain of the object.
function myInstanceof(left, right) {
    let proto = Object.getPrototypeOf(left), //Gets the prototype of the object
    prototype = right.prototype; //Gets the {prototype} object of the constructor
    //Judge whether the {prototype} object of the constructor is on the prototype chain of the object
    while (true) {
        if (!proto) return false;
        if (proto === prototype) return true;
        proto = Object.getPrototypeOf(proto);
    }
}

8.Object. Implementation of create()

  • MDN document

  • Object.create() takes the parameter object as the prototype of a newly created empty object and returns the empty object

//Abbreviated Edition
function myCreate(obj){
    //New declaration of a function
    function C(){};
    //Point the prototype of the function to obj
    C.prototype = obj;
    //Returns the strength object of this function
    return new C()
}
//Official Polyfill
if (typeof Object.create !== "function") {
    Object.create = function (proto, propertiesObject) {
        if (typeof proto !== 'object' && typeof proto !== 'function') {
            throw new TypeError('Object prototype may only be an Object: ' + proto);
        } else if (proto === null) {
            throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
        }

        if (typeof propertiesObject !== 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");

        function F() {}
        F.prototype = proto;

        return new F();
    };
}

9. Implement object assign

Object.assign2 = function(target, ...source) {
    if (target == null) {
        throw new TypeError('Cannot convert undefined or null to object')
    }
    let ret = Object(target) 
    source.forEach(function(obj) {
        if (obj != null) {
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    ret[key] = obj[key]
                }
            }
        }
    })
    return ret
}

10. Implementation of promise

To realize Promise, you need to fully understand Promise A + specification. However, from the perspective of overall implementation, the following points need to be considered:

  • Promise is essentially a state machine, and the state can only be the following three: Pending, completed and Rejected. The change of state is one-way, and can only be from Pending - > completed or Pending - > Rejected. The change of state is irreversible

  • then needs to support chained calls

class Promise {
    callbacks = [];
    state = 'pending';//Increase status
    value = null;//Save results
    constructor(fn) {
        fn(this._resolve.bind(this), this._reject.bind(this));
    }
    then(onFulfilled, onRejected) {
        return new Promise((resolve, reject) => {
            this._handle({
                onFulfilled: onFulfilled || null,
                onRejected: onRejected || null,
                resolve: resolve,
                reject: reject
            });
        });
    }
    _handle(callback) {
        if (this.state === 'pending') {
            this.callbacks.push(callback);
            return;
        }
 
        let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;
 
        if (!cb) {//If nothing is passed in then
            cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
            cb(this.value);
            return;
        }
 
        let ret = cb(this.value);
        cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
        cb(ret);
    }
    _resolve(value) {
 
        if (value && (typeof value === 'object' || typeof value === 'function')) {
            var then = value.then;
            if (typeof then === 'function') {
                then.call(value, this._resolve.bind(this), this._reject.bind(this));
                return;
            }
        }
 
        this.state = 'fulfilled';//Change state
        this.value = value;//Save results
        this.callbacks.forEach(callback => this._handle(callback));
    }
    _reject(error) {
        this.state = 'rejected';
        this.value = error;
        this.callbacks.forEach(callback => this._handle(callback));
    }
}

Promise.resolve

  • Promsie.resolve(value) can convert any value to value. The status is Promise with full Promise, but if the passed in value itself is Promise, it will be returned as it is.

Promise.resolve(value) {
  if (value && value instanceof Promise) {
    return value;
  } else if (value && typeof value === 'object' && typeof value.then === 'function') {
    let then = value.then;
    return new Promise(resolve => {
      then(resolve);
    });
  } else if (value) {
    return new Promise(resolve => resolve(value));
  } else {
    return new Promise(resolve => resolve());
  }
}

Promise.reject

  • And Promise Resolve() is similar to Promise Reject () instantiates a Promise in the rejected state. But with Promise The difference between resolve () and Promise Reject() passes a Promise object, which will become the value of the new Promise.

Promise.reject = function(reason) {
    return new Promise((resolve, reject) => reject(reason))
}

Promise.all

  • If all incoming promsies are full, a new Promise in the status of full is returned, which is composed of their values;

  • As long as one Promise is rejected, a new Promsie in the rejected state is returned, and its value is the value of the first rejected Promise;

  • As long as one Promise is pending, a new Promise in pending status is returned;

Promise.all = function(promiseArr) {
    let index = 0, result = []
    return new Promise((resolve, reject) => {
        promiseArr.forEach((p, i) => {
            Promise.resolve(p).then(val => {
                index++
                result[i] = val
                if (index === promiseArr.length) {
                    resolve(result)
                }
            }, err => {
                reject(err)
            })
        })
    })
}

Promise.race

  • Promise.race returns a new instance wrapped by the first fully or rejected instance of all iteratable instances.

Promise.race = function(promiseArr) {
    return new Promise((resolve, reject) => {
        promiseArr.forEach(p => {
            Promise.resolve(p).then(val => {
                resolve(val)
            }, err => {
                rejecte(err)
            })
        })
    })
}

11. Implementation of Ajax

function ajax(url,method,body,headers){
    return new Promise((resolve,reject)=>{
        let req = new XMLHttpRequest();
        req.open(methods,url);
        for(let key in headers){
            req.setRequestHeader(key,headers[key])
        }
        req.onreadystatechange(()=>{
            if(req.readystate == 4){
                if(req.status >= '200' && req.status <= 300){
                    resolve(req.responeText)
                }else{
                    reject(req)
                }
            }
        })
        req.send(body)
    })
}

12. Implement anti shake function (debounce)

  • Continuously trigger the method at the last execution, scene: input box matching

let debounce = (fn,time = 1000) => {
    let timeLock = null

    return function (...args){
        clearTimeout(timeLock)
        timeLock = setTimeout(()=>{
            fn(...args)
        },time)
    }
}

13. Implement the throttle function

  • Trigger only once in a certain period of time. Scenario: long list scrolling throttling

let throttle = (fn,time = 1000) => {
    let flag = true;

    return function (...args){
        if(flag){
            flag = false;
            setTimeout(()=>{
                flag = true;
                fn(...args)
            },time)
        }
    }
}

14. Deep clone

  • Judge the type, regular and date, and return the new object directly

  • Null or non object type, return the original value directly

  • Consider the circular reference, and judge if the hash contains the value directly returned from the hash

  • Create a new obj Add hash to constructor

  • Traversal object recursion (normal key and key are symbol)

function deepClone(obj,hash = new WeakMap()){
    if(obj instanceof RegExp) return new RegExp(obj);
    if(obj instanceof Date) return new Date(obj);
    if(obj === null || typeof obj !== 'object') return obj;
    //Circular reference
    if(hash.has(obj)){
        return hash.get(obj)
    }
    //new , a corresponding object
    //obj is Array, which is equivalent to new Array()
    //obj is Object, which is equivalent to new Object()
    let constr = new obj.constructor();
    hash.set(obj,constr);
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            constr[key] = deepClone(obj[key],hash)
        }
    }
    //Consider the case of symbol
    let symbolObj = Object.getOwnPropertySymbols(obj)
    for(let i=0;i<symbolObj.length;i++){
        if(obj.hasOwnProperty(symbolObj[i])){
            constr[symbolObj[i]] = deepClone(obj[symbolObj[i]],hash)
        }
    }
    return constr
}

15. Implementation of array flattening (flat)

let arr = [1,2,[3,4,[5,[6]]]]
console.log(arr.flat(Infinity))//The flat parameter specifies the structure depth of the nested array to be extracted. The default value is 1
//Implement with reduce
function fn(arr){
   return arr.reduce((prev,cur)=>{
      return prev.concat(Array.isArray(cur)?fn(cur):cur)
   },[])
}

16. Function coritization

function sumFn(a,b,c){return a+ b + c};
let sum = curry(sumFn);
sum(2)(3)(5)//10
sum(2,3)(5)//10
function curry(fn,...args){
  let fnLen = fn.length,
      argsLen = args.length;
  //Compare the parameters of the function with the current passed in parameters
  //If the parameters are not enough, continue to recursively return curry
  //If the parameters are enough, call the function to return the corresponding value
  if(fnLen > argsLen){
    return function(...arg2s){
      return curry(fn,...args,...arg2s)
    }
  }else{
    return fn(...args)
  }
}

17. Use closures to print 1,2,3,4 every second

for (var i=1; i<=5; i++) {
  (function (i) {
    setTimeout(() => console.log(i), 1000*i)
  })(i)
}

18. Write a jsonp

const jsonp = function (url, data) {
    return new Promise((resolve, reject) => {
        //Initialize url
        let dataString = url.indexOf('?') === -1 ? '?' : ''
        let callbackName = `jsonpCB_${Date.now()}`
        url += `${dataString}callback=${callbackName}`
        if (data) {
            //There are request parameters, which are added to the url in turn
            for (let k in data) {
                url += `${k}=${data[k]}`
            }
        }
        let jsNode = document.createElement('script')
        jsNode.src = url
        //Trigger a callback. After triggering, delete the js tag and the callback bound to the window
        window[callbackName] = result => {
            delete window[callbackName]
            document.body.removeChild(jsNode)
            if (result) {
                resolve(result)
            } else {
                reject('No data returned')
            }
        }
        //js loading exception
        jsNode.addEventListener('error', () => {
            delete window[callbackName]
            document.body.removeChild(jsNode)
            reject('JavaScript Resource loading failed')
        }, false)
        //When adding a js node to the document, start the request
        document.body.appendChild(jsNode)
    })
}
jsonp('http://192.168.0.103:8081/jsonp', {
    a: 1,
    b: 'heiheihei'
})
.then(result => {
    console.log(result)
})
.catch(err => {
    console.error(err)
})

19. Handwriting an observer mode

class Subject{
  constructor(name){
    this.name = name
    this.observers = []
    this.state = 'XXXX'
  }
  //The observer should provide a way to accept the observer
  attach(observer){
    this.observers.push(observer)
  }

  //Change the state of being observed
  setState(newState){
    this.state = newState
    this.observers.forEach(o=>{
      o.update(newState)
    })
  }
}

class Observer{
  constructor(name){
    this.name = name
  }

  update(newState){
    console.log(`${this.name}say:${newState}`)
  }
}

//Observer light
let sub = new Subject('lamp')
let mm = new Observer('Xiao Ming')
let jj = new Observer('Xiao Jian')
 
//Subscribe to # observers
sub.attach(mm)
sub.attach(jj)
 
sub.setState('The light is on. There's a call')

20.EventEmitter implementation

class EventEmitter {
    constructor() {
        this.events = {};
    }
    on(event, callback) {
        let callbacks = this.events[event] || [];
        callbacks.push(callback);
        this.events[event] = callbacks;
        return this;
    }
    off(event, callback) {
        let callbacks = this.events[event];
        this.events[event] = callbacks && callbacks.filter(fn => fn !== callback);
        return this;
    }
    emit(event, ...args) {
        let callbacks = this.events[event];
        callbacks.forEach(fn => {
            fn(...args);
        });
        return this;
    }
    once(event, callback) {
        let wrapFun = function (...args) {
            callback(...args);
            this.off(event, wrapFun);
        };
        this.on(event, wrapFun);
        return this;
    }
}

21. Various methods of generating random numbers?

function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min)) + min   
}

22. How to realize random sorting of arrays?

let arr = [2,3,454,34,324,32]
arr.sort(randomSort)
function randomSort(a, b) {
  return Math.random() > 0.5 ? -1 : 1;
}

23. Write a general event listener function.

const EventUtils = {
  //The visual ability uses dom0 | dom2 | ie to bind events respectively
  //Add event
  addEvent: function(element, type, handler) {
    if (element.addEventListener) {
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
      element.attachEvent("on" + type, handler);
    } else {
      element["on" + type] = handler;
    }
  },
  //Remove event
  removeEvent: function(element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
      element.detachEvent("on" + type, handler);
    } else {
      element["on" + type] = null;
    }
  },
 //Get event target
  getTarget: function(event) {
    return event.target || event.srcElement;
  },
  //Get the reference of the event object, get all the information of the event, and ensure that the event can be used at any time
  getEvent: function(event) {
    return event || window.event;
  },
 //Block events (mainly event bubbling, because IE} does not support event capture)
  stopPropagation: function(event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
  },
  //Cancels the default behavior for events
  preventDefault: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  }
};

24. Implement the flatten function in an iterative manner.

var arr = [1, 2, 3, [4, 5], [6, [7, [8]]]]
/** * Use recursion to handle * wrap # internal protection
 Save the result, * ret * returns a recursive function**/
function wrap() {
    var ret = [];
    return function flat(a) {
        for (var item of
            a) {
                if (item.constructor === Array) {
                    ret.concat(flat(item))
                } else {
                    ret.push(item)
                }
        }
        return ret
    }
} 
console.log(wrap()(arr));

25. How to implement a sleep

  • The sleep function is used to make the thread sleep and wake up again at a specified time.

function sleep(delay) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime() - start < delay) {
    continue;
  }
}

function test() {
  console.log('111');
  sleep(2000);
  console.log('222');
}

test()

26. Realize regular segmentation of the thousandth (10000 = > 10000)

//No decimal point
let num1 = '1321434322222'
num1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')
//There is a decimal point
let num2 = '342243242322.3432423'
num2.replace(/(\d)(?=(\d{3})+\.)/g,'$1,')

27. Object array de duplication

input:
[{a:1,b:2,c:3},{b:2,c:3,a:1},{d:2,c:2}]
output:
[{a:1,b:2,c:3},{d:2,c:2}]
  • First, write a function to sort the key s in the object, and then turn them into strings

  • Traversing the array, use Set to de duplicate the object converted into a string

function objSort(obj){
    let newObj = {}
    //Traverse the object and sort the key s
    Object.keys(obj).sort().map(key => {
        newObj[key] = obj[key]
    })
    //Convert the sorted array to a string
    return JSON.stringify(newObj)
}

function unique(arr){
    let set = new Set();
    for(let i=0;i<arr.length;i++){
        let str = objSort(arr[i])
        set.add(str)
    }
    //Returns a string from an array to an object
    arr = [...set].map(item => {
        return JSON.parse(item)
    })
    return arr
}

28. Resolve URL Params as object

let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)
/* result
{ user: 'anonymous',
  id: [ 123, 456 ], // The repeated {key s} should be assembled into an array, and those that can be converted into numbers will be converted into number types
  city: 'Beijing ', / / Chinese needs decoding
  enabled: true, // The value of {key} is not specified, and the Convention is} true
}
*/
function parseParam(url) {
  const paramsStr = /.+\?(.+)$/.exec(url)[1]; //Will? Take out the following string
  const paramsArr = paramsStr.split('&'); //Split the string with & and save it in the array
  let paramsObj = {};
  //Save params to object
  paramsArr.forEach(param => {
    if (/=/.test(param)) { //Handle parameters with {value}
      let [key, val] = param.split('='); //Split # key # and # value
      val = decodeURIComponent(val); //Decode
      val = /^\d+$/.test(val) ? parseFloat(val) : val; //Determine whether to convert to number

      if (paramsObj.hasOwnProperty(key)) { //If the object has a key, add a value
        paramsObj[key] = [].concat(paramsObj[key], val);
      } else { //If the object does not have this key, create a key and set the value
        paramsObj[key] = val;
      }
    } else { //Processing parameters without {value}
      paramsObj[param] = true;
    }
  })

  return paramsObj;
}

29. Implementation of template engine

let template = 'I am{{name}},Age{{age}},Gender{{sex}}';
let data = {
  name: 'full name',
  age: 18
}
render(template, data); //My name is, age 18, gender undefined
function render(template, data) {
  const reg = /\{\{(\w+)\}\}/; //Template string regular
  if (reg.test(template)) { //Determine whether there is a template string in the template
    const name = reg.exec(template)[1]; //Find the field of the first template string in the current template
    template = template.replace(reg, data[name]); //Render the first template string
    return render(template, data); //Render recursively and return the rendered structure
  }
  return template; //If the template has no template string, it is returned directly
}

30. Convert to hump naming

var s1 = "get-element-by-id"
//Convert to getElementById
var f = function(s) {
    return s.replace(/-\w/g, function(x) {
        return x.slice(1).toUpperCase();
    })
}

31. Find the most characters and number in the string

  • Example: abbcccddddd - > d has the largest number of characters and appears 5 times

let str = "abcabcabcbbccccc";
let num = 0;
let char = '';

 //Arrange them in a certain order
str = str.split('').sort().join('');
// "aaabbbbbcccccccc"

//Define regular expressions
let re = /(\w)\1+/g;
str.replace(re,($0,$1) => {
    if(num < $0.length){
        num = $0.length;
        char = $1;        
    }
});
console.log(`The largest number of characters is ${char},There it is ${num}second`);

32. Picture loading

let imgList = [...document.querySelectorAll('img')]
let length = imgList.length

const imgLazyLoad = function() {
    let count = 0
    return (function() {
        let deleteIndexList = []
        imgList.forEach((img, index) => {
            let rect = img.getBoundingClientRect()
            if (rect.top < window.innerHeight) {
                img.src = img.dataset.src
                deleteIndexList.push(index)
                count++
                if (count === length) {
                    document.removeEventListener('scroll', imgLazyLoad)
                }
            }
        })
        imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
    })()
}

//It's best to add anti shake treatment here
document.addEventListener('scroll', imgLazyLoad)

Keywords: Javascript React Vue.js html css

Added by dude81 on Mon, 24 Jan 2022 12:21:38 +0200