当前位置:网站首页>Fashion cloud interview questions series - JS high-frequency handwritten code questions
Fashion cloud interview questions series - JS high-frequency handwritten code questions
2022-07-03 22:43:00 【Fashion cloud network】
Catalog
Shallow copy 、 The implementation of deep copy
Implementation of an anti shake function
Implement a throttling function
The realization of the curried function
Object.create Basic realization principle of
Implement a two-way data binding
Handwritten implementation AJAX
Implementation of array map Method
Realization Promise
// No other boundary conditions such as asynchronous processing are added
// ① Execute functions automatically ,② Three states ,③then
class Promise {
constructor (fn) {
// Three states
this.state = 'pending'
this.value = undefined
this.reason = undefined
let resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
}
}
let reject = value => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = value
}
}
// Execute functions automatically
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
}
// then
then(onFulfilled, onRejected) {
switch (this.state) {
case 'fulfilled':
onFulfilled(this.value)
break
case 'rejected':
onRejected(this.reason)
break
default:
}
}
}
Achieve one call function
// Ideas : It's going to change this The directed method hangs to the target this Execute on and return to
Function.prototype.mycall = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let arg = [...arguments].slice(1)
let result = context.fn(...arg)
delete context.fn
return result
}
Achieve one apply function
// Ideas : It's going to change this The directed method hangs to the target this Execute on and return to
Function.prototype.myapply = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
Achieve one bind function
// Ideas : similar call, But the function returned is
Function.prototype.mybind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
let _this = this
let arg = [...arguments].slice(1)
return function F() {
// Processing functions use new The situation of
if (this instanceof F) {
return new _this(...arg, ...arguments)
} else {
return _this.apply(context, arg.concat(...arguments))
}
}
}
Shallow copy 、 The implementation of deep copy
Shallow copy :
// 1. ... Realization
let copy1 = {...{x:1}}
// 2. Object.assign Realization
let copy2 = Object.assign({}, {x:1})
Deep copy :
// 1. JOSN.stringify()/JSON.parse()
// shortcoming : The copy object contains Regular expressions , function , perhaps undefined Equivalence will fail
let obj = {a: 1, b: {x: 3}}
JSON.parse(JSON.stringify(obj))
// 2. recursive copying
function deepClone(obj) {
let copy = obj instanceof Array ? [] : {}
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
copy[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
}
}
return copy
}
Implementation of an anti shake function
// Ideas : The second time... Is not triggered within the specified time , execute
function debounce (fn, delay) {
// Use closures to save timers
let timer = null
return function () {
let context = this
let arg = arguments
// If it is triggered again within the specified time, the timer will be cleared before resetting
clearTimeout(timer)
timer = setTimeout(function () {
fn.apply(context, arg)
}, delay)
}
}
function fn () {
console.log(' Shake proof ')
}
addEventListener('scroll', debounce(fn, 1000))
Implement a throttling function
// Basic Edition 1: Time stamp ( The first trigger will execute , But it does not rule out the possibility of not executing , Please think about it )
function throttle(fn, delay) {
var prev = Date.now()
return function(...args) {
var dist = Date.now() - prev
if (dist >= delay) {
fn.apply(this, args)
prev = Date.now()
}
}
}
// Basic Edition 2: Timer ( The last time it will be executed )
function throttle(fn, delay) {
var timer = null
return function(...args) {
var that = this
if(!timer) {
timer = setTimeout(function() {
fn.apply(this, args)
timer = null
}, delay)
}
}
}
// premium : Start execution 、 End to perform
function throttle(fn, delay) {
var timer = null
var prev = Date.now()
return function(...args) {
var that = this
var remaining = delay - (Date.now() - prev) // The rest of the time
if (remaining <= 0) { // The first 1 Trigger
fn.apply(that, args)
prev = Date.now()
} else { // The first 1 Trigger after times
timer && clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(that, args)
}, remaining)
}
}
}
function fn () {
console.log(' throttle ')
}
addEventListener('scroll', throttle(fn, 1000))
The realization of the curried function
Definition of Coriolis function : Convert a multi parameter function into a single parameter form .
Principle of realization of Coriolis function : Using the closure principle, a scope without destruction can be formed during execution , Then store all the content that needs to be preprocessed in this non destruction scope , And return a function with the least parameters .
The first one is : Fixed incoming parameters , Execute when the parameters are enough
/**
* To achieve the point : After the Coriolis function receives enough parameters , Will execute the original function , So how do we decide when to reach enough parameters ?
* The Coriolis function needs to remember that you have given him parameters , If not , It defaults to an empty array .
* Next, every time you call , You need to check whether the parameters are given enough , If that's enough , execute fn, If not, a new curry function , Give him the existing parameters .
*
*/
// Functions to be coriolised
let sum = (a, b, c, d) => {
return a + b + c + d
}
// Coriolis function , Returns a processed function
let curry = (fn, ...arr) => { // arr Record existing parameters
return (...args) => { // args Receive new parameters
if (fn.length <= (...arr,...args)) { // Parameter enough time , Trigger execution
return fn(...arr, ...args)
} else { // Continue adding parameters
return curry(fn, [...arr, ...args])
}
}
}
var sumPlus = curry(sum)
sumPlus(1)(2)(3)(4)
sumPlus(1, 2)(3)(4)
sumPlus(1, 2, 3)(4)
The second kind : Incoming parameters are not fixed , At any time
/**
* Yes, of course , The main function of Coriolis function is to delay execution , The trigger condition for execution is not necessarily equal to the number of parameters , It can also be other conditions .
* For example, the parameter is 0 The situation of , So we need to be on top curry The function is slightly modified
*/
// Functions to be coriolised
let sum = arr => {
return arr.reduce((a, b) => {
return a + b
})
}
let curry = (fn, ...arr) => { // arr Record existing parameters
return (...args) => { // args Receive new parameters
if (args.length === 0) { // When the parameter is empty , Trigger execution
return fn(...arr, ...args)
} else { // Continue adding parameters
return curry(fn, ...arr, ...args)
}
}
}
var sumPlus = curry(sum)
sumPlus(1)(2)(3)(4)()
sumPlus(1, 2)(3)(4)()
sumPlus(1, 2, 3)(4)()
Object.create Basic realization principle of
// Ideas : Take the incoming object as a prototype
function create(obj) {
function F() {}
F.prototype = obj
return new F()
}
Implement a two-way data binding
let obj = {}
let input = document.getElementById('input')
let span = document.getElementById('span')
// The data was hijacked
Object.defineProperty(obj, 'text', {
configurable: true,
enumerable: true,
get() {
console.log(' Got the data ')
},
set(newVal) {
console.log(' Data updated ')
input.value = newVal
span.innerHTML = newVal
}
})
// input monitoring
input.addEventListener('keyup', function(e) {
obj.text = e.target.value
})
Implement a simple route
// hash route
class Route{
constructor(){
// Route storage objects
this.routes = {}
// At present hash
this.currentHash = ''
// binding this, Avoid monitoring this Point to change
this.freshRoute = this.freshRoute.bind(this)
// monitor
window.addEventListener('load', this.freshRoute, false)
window.addEventListener('hashchange', this.freshRoute, false)
}
// Storage
storeRoute (path, cb) {
this.routes[path] = cb || function () {}
}
// to update
freshRoute () {
this.currentHash = location.hash.slice(1) || '/'
this.routes[this.currentHash]()
}
}
Implement lazy loading
<ul>
<li><img src="./imgs/default.png" data="./imgs/1.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/2.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/3.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/4.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/5.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/6.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/7.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/8.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/9.png" alt=""></li>
<li><img src="./imgs/default.png" data="./imgs/10.png" alt=""></li>
</ul>
let imgs = document.querySelectorAll('img')
// Height of visual area
let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
function lazyLoad () {
// The height of the roll
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
for (let i = 0; i < imgs.length; i ++) {
// The height of the image in the visible area
let x = clientHeight + scrollTop - imgs[i].offsetTop
// The picture is in the visual area
if (x > 0 && x < clientHeight+imgs[i].height) {
imgs[i].src = imgs[i].getAttribute('data')
}
}
}
// addEventListener('scroll', lazyLoad) or setInterval(lazyLoad, 1000)
rem Basic settings
// Advance execution , initialization resize The event will not execute
setRem()
// The original configuration
function setRem () {
let doc = document.documentElement
let width = doc.getBoundingClientRect().width
let rem = width / 75
doc.style.fontSize = rem + 'px'
}
// Monitor window changes
addEventListener("resize", setRem)
Handwritten implementation AJAX
// 1. Simple process
// Instantiation
let xhr = new XMLHttpRequest()
// initialization
xhr.open(method, url, async)
// Send a request
xhr.send(data)
// Set the status change callback to process the request result
xhr.onreadystatechange = () => {
if (xhr.readyStatus === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
// 2. be based on promise Realization
function ajax (options) {
// Request address
const url = options.url
// Request method
const method = options.method.toLocaleLowerCase() || 'get'
// The default is asynchronous true
const async = options.async
// Request parameters
const data = options.data
// Instantiation
const xhr = new XMLHttpRequest()
// request timeout
if (options.timeout && options.timeout > 0) {
xhr.timeout = options.timeout
}
// Return to one Promise example
return new Promise ((resolve, reject) => {
xhr.ontimeout = () => reject && reject(' request timeout ')
// Monitor status change callback
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
// 200-300 Indicates that the request is successful ,304 Resources remain unchanged , Fetch cache
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
resolve && resolve(xhr.responseText)
} else {
reject && reject()
}
}
}
// Wrong callback
xhr.onerror = err => reject && reject(err)
let paramArr = []
let encodeData
// Processing request parameters
if (data instanceof Object) {
for (let key in data) {
// Parameter splicing needs to pass encodeURIComponent Encoding
paramArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
}
encodeData = paramArr.join('&')
}
// get Request splicing parameters
if (method === 'get') {
// testing url Is there already ? And its location
const index = url.indexOf('?')
if (index === -1) url += '?'
else if (index !== url.length -1) url += '&'
// Splicing url
url += encodeData
}
// initialization
xhr.open(method, url, async)
// Send a request
if (method === 'get') xhr.send(null)
else {
// post Method needs to set request header
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8')
xhr.send(encodeData)
}
})
}
Handwriting jsonp
$.ajax({
url: 'xxxxx', // A cross domain url
type: 'get',
dataType: 'jsonp', // Set the data type returned by the server
jsonp: 'onJsonPLoad', // This value is used to configure the previously mentioned callback, It will be spliced to url Behind
jsonpCallback: 'handleRes', // Used to set the callback function name
success: function (res){ // there success Callback is equivalent to the previously written handleRes Method .
console.log(res);
}
})
Implementation of array map Method
Array.prototype.myMap = function(fn, thisValue) {
let res = []
thisValue = thisValue||[]
let arr = this
for(let i in arr) {
res.push(fn(arr[i]))
}
return res
}
边栏推荐
- How to restore the factory settings of HP computer
- Mindmanager2022 serial number key decompression installer tutorial
- How can enterprises and developers take advantage of the explosion of cloud native landing?
- webAssembly
- Shiftvit uses the precision of swing transformer to outperform the speed of RESNET, and discusses that the success of Vit does not lie in attention!
- Plug - in Oil Monkey
- [template summary] - binary search tree BST - Basics
- pycuda._ driver. LogicError: explicit_ context_ dependent failed: invalid device context - no currently
- [automation operation and maintenance novice village] flask-2 certification
- How to connect a laptop to a projector
猜你喜欢
QGIS grid processing DEM data reclassification
IPhone development swift foundation 09 assets
[actual combat record] record the whole process of the server being attacked (redis vulnerability)
Blue Bridge Cup Guoxin Changtian MCU -- program download (III)
The 2022 global software R & D technology conference was released, and world-class masters such as Turing prize winners attended
Mysql database - Advanced SQL statement (I)
Format cluster and start cluster
Correlation
3 environment construction -standalone
How can enterprises and developers take advantage of the explosion of cloud native landing?
随机推荐
File copy method
Ansible common usage scenarios
string
How to solve the problem of computer networking but showing no Internet connection
Teach you how to run two or more MySQL databases at the same time in one system
Go Technology Daily (2022-02-13) - Summary of experience in database storage selection
How the computer flushes the local DNS cache
Covariance
MLX90614 driver, function introduction and PEC verification
The reason why the computer runs slowly and how to solve it
pycuda._ driver. LogicError: explicit_ context_ dependent failed: invalid device context - no currently
STM32 multi serial port implementation of printf -- Based on cubemx
Overview of Yunxi database executor
Shiftvit uses the precision of swing transformer to outperform the speed of RESNET, and discusses that the success of Vit does not lie in attention!
Why should enterprises do more application activities?
Yyds dry goods inventory hands-on teach you to create a jigsaw puzzle using the canvasapi
Blue Bridge Cup Guoxin Changtian MCU -- program download (III)
BUUCTF,Misc:LSB
Some 5000+ likes, the development notes of a director of cosmic factory, leaked
[dynamic programming] Ji Suan Ke: Suan tou Jun breaks through the barrier (variant of the longest increasing subsequence)