前端面試手寫題

深拷貝

// 深拷貝
function deepClone(ori) {let tar;if (typeof ori === 'object' && ori !== null) {tar = Array.isArray(ori) ? [] : {}for (let k in ori) {if (ori.hasOwnProperty(k)) {tar[k] = deepClone(ori[k])}}} else {tar = ori}return tar}

繼承

// 圣杯模式實現繼承
function Parent() { }
function Child() { }
function Buffer() { }
Buffer.prototype = Parent.prototype
Child.prototype = new Buffer()
Child.prototype.constructor = Child
Child.prototype.super_class = Parent
// ES6 類的繼承
class Parent { }
class Child extends Parent {constructor() {super()}
}
// 組合繼承
function Child() {Parent.call(this)
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child

Promise

// Promise
const pending = Symbol('pending')
const fulfilled = Symbol('fulfilled')
const rejected = Symbol('rejected')class Promise {constructor(executor) {this.status = 'pending'this.value = undefinedthis.reason = undefinedthis.onFulfilledCbs = []this.onRejectedCbs = []function resolve(value) {if (this.status === 'pending') {this.status = 'fulfilled'this.value = valuethis.onFulfilledCbs.forEach(fn => fn())}}function reject(reason) {if (this.status === 'pending') {this.status = 'rejected'this.reason = reasonthis.onRejectedCbs.forEach(fn => fn())}}try {executor(resolve, reject)} catch (err) {reject(err)}}then(onFulfilled, onRejected) {onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => valueonRejected = typeof onRejected === 'function' ? onRejected : reason => reason// 異步返回promiselet promise = new Promise((resolve, reject) => {if (this.status === 'fulfilled') {setTimeout(() => {try {let x = onFulfilled(this.value)resolvePromise(promise, x, resolve, reject)} catch (e) {reject(e)}});}if (this.status === 'rejected') {setTimeout(() => {try {let x = onRejected(this.reason)resolvePromise(promise, x, resolve, reject)} catch (e) {reject(e)}});}if (this.status === 'pending') {this.onFulfilledCbs.push(() => {setTimeout(() => {try {let x = onFulfilled(this.value)resolvePromise(promise, x, resolve, reject)} catch (e) {reject(e)}});})this.onRejectedCbs.push(() => {setTimeout(() => {try {let x = onRejected(this.reason)resolvePromise(promise, x, resolve, reject)} catch (e) {reject(e)}});})}})return promise}// Promise構造器上方法static resolve(result) {return new Promise((resolve) => {resolve(result)})}static resolve(reason) {return new Promise((resolve, reject) => {reject(reason)})}static all(iterator) {return new Promise((resolve, reject) => {const final = []for (let item of iterator) {Promise.resolve(item).then(result => {final.push(result)if (final.length === iterator.length) {resolve(final)}}, reason => {reject(reason)})}})}static race(iterator) {return new Promise((resolve, reject) => {for (let item of iterator) {Promise.resolve(item).then(resolve, reject)}})}
}
function resolvePromise(promise, x, resolve, reject) {if (x === promise) {return reject(new TypeError('chaining cycle'))}let called;if (x !== null && (typeof x === 'function' || typeof x === 'object')) {try {let then = x.thenif (typeof then === 'function') {then.call(x, y => {if (called) returncalled = trueresolvePromise(promise, y, resolve, reject)}, err => {if (called) returncalled = truereject(err)})} else {if (called) returncalled = trueresolve(x)}} catch (err) {if (called) returncalled = truereject(err)}} else {resolve(x)}
}

防抖節流

// 防抖
function debounce(fn, delay, triggerNow) {let t = null;return function () {let _this = thisif (t) {clearTimeout(t)}if (triggerNow) {let exec = !tt = setTimeout(function () {t = null}, delay);if (exec) {fn.apply(_this, arguments)}} else {t = setTimeout(function () {fn.apply(_this, arguments)}, delay);}}
}
// 節流 不會立即執行
function throttle1(fn, delay) {let t = null, begin = Date.now();return function () {_this = thisclearTimeout(t)const cur = Date.now()if (cur - begin >= delay) {fn.apply(_this, arguments) // 就執行吧begin = cur} else {t = setTimeout(function () {fn.apply(_this, arguments)}, delay);}}
}
// 節流 且會立即執行
function throttle2(fn, delay) {let valid = true // 初始化開著return function () {if (!valid) returnvalid = false // 先關了t = setTimeout(function () {fn.apply(_this, arguments)value = true // 定時器里再開起來}, delay);}
}

call、bind、apply

// call、bind、apply
// fn.call(obj, ...args)
// 第一個參數是this指向
Function.prototype.call = function (context = window, ...args) {// this指向這個函數const fn = Symbol('fn')context[fn] = thiscontext[fn](...args) // 隱式綁定delete context[fn]
}
Function.prototype.apply = function (context = window, argsArr) {// this指向這個函數const fn = Symbol('fn')context[fn] = thiscontext[fn](...argsArr) // 隱式綁定delete context[fn]
}
Function.prototype.bind = function (context = window, ...args) {// this指向這個函數const fn = Symbol('fn')context[fn] = thisreturn function (..._args) {let arr = [...args, ..._args]context[fn](...arr)delete context[fn]}
}

排序算法

// 冒泡排序算法
function bubbleSort(arr) {let len = arr.lengthfor (let i = 0; i < len - 1; i++) {for (let j = 0; j < len - 1 - i; j++) {let a = arr[j],b = arr[j + 1]if (a > b) {[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]}}}return arr
}
console.log(bubbleSort([2, 1, 4, 0, 3]))
// 阮一峰分而治之 快排的思想 但在復雜度上沒有真正的快排好 只能作為輔助理解
function quickSort(arr) {let len = arr.length// 非常重要 否則死循環if (len <= 1) {return arr}let pivotIndex = Math.floor(len / 2)let pivot = arr.splice(pivotIndex, 1)[0]let left = [], right = []for (let item of arr) {if (item < pivot) {left.push(item)} else {right.push(item)}}return [...quickSort(left), pivot, ...quickSort(right)]
}
console.log(quickSort([2, 1, 4, 0, 3]))function quickSort(arr, left, right) {var partitionIndex;if (left < right) {partitionIndex = partition(arr, left, right);quickSort(arr, left, partitionIndex - 1);quickSort(arr, partitionIndex + 1, right);}return arr;
}
// 找基準
function partition(arr, left, right) {var pivotIndex = left,index = pivotIndex + 1;for (var i = index; i <= right; i++) {if (arr[i] < arr[pivotIndex]) {swap(arr, i, index);index++; // index會變}}swap(arr, pivotIndex, index - 1);return index - 1;
}
function swap(arr, i, j) {[arr[i], arr[j]] = [arr[j], arr[i]]
}
console.log(quickSort(test, 0, test.length - 1))

// 斐波那契數列

function* test(n) {let [prev, cur] = [0, 1];for (let i = 0; i < n; i++) {yield prev;[prev, cur] = [cur, prev + cur];}
}
console.log(...test(15))

手寫JSONP JSON with Padding

  • 有src屬性的標簽如script img iframe能跨域
  • 前端在得到了后端返回的內容jsonpCallback({“title”:“title1”}),發現里面是一段執行函數的語句
  • 不能用Symbol,不能轉為字符串
  • 動態添加script,在定義在全局的callback中處理數據,并移除script
; (function (win) {function jsonp(url, params = {}, cb) {const src = Object.entries(params).map(([key, value]) => {return `${key}=${value}`}).join('&')const cbName = 'cb' + Date.now()const s = document.createElement('script')s.setAttribute('src', url + '?' + src + '&callback=' + cbName)document.body.appendChild(s)win[cbName] = function (res) {cb(res)document.body.removeChild(src)}}window.jsonp = jsonp
})(window);

三角形

setTimeout實現setInterval、clearInterval

  • IIFE
  • 全局的定時器id t
let t = null
function mysetInterval(cb, time) {;(function () {cb()t = setTimeout(arguments.callee, time)})();return t
}
t = mysetInterval(() => {console.log(1)
}, 500)
function myClearTnterVal(t) {clearTimeout(t)t = nullconsole.log(t)
}
setTimeout(() => {myClearTnterVal(t)
}, 1500)

lastPromise

編寫一個高階函數,這個高階函數接受一個promise參數,然后返回一個函數。每次調用返回的函數的時候,只會輸出最后一個promsie的結果。就像下面示例一樣。

function lastPromise(promiseFunction) {// TODO
}// 示例
let count = 1;
// 這是一個函數,返回promise
let promiseFunction = () =>new Promise(rs =>setTimeout(() => {rs(count++);}));let lastFn = lastPromise(promiseFunction);lastFn().then(console.log); // 無輸出
lastFn().then(console.log); // 無輸出
lastFn().then(console.log); // 3
let count = 1;
// 這是一個函數,返回promise
let promiseFunction = () =>new Promise(rs =>setTimeout(() => {rs(count++);}));
function lastPromise(promiseFunction) {// 返回函數 函數有一個then方法let mC = 0return function () {mC++function then(cb) {promiseFunction().then(res => {if (mC == res) {cb(res)}})}return { then }}
}
let lastFn = lastPromise(promiseFunction)
lastFn().then(console.log)
lastFn().then(console.log)
lastFn().then(console.log)

animation動畫 transition過渡 transform轉換

畫三角形

  • 沒寬高,看到的是邊
  • 邊有left right top bottom 要分開寫
  • 左邊是左上三角 右邊是右上三角
  • 下邊是一個正三角
  • 上邊是一個倒三角
    在這里插入圖片描述
    在這里插入圖片描述
    在這里插入圖片描述

正方形

  1. vw
  2. 設置寬度,padding-top div里寫字會撐高

單鏈表循環
快速排序
算24點

從左到右動畫

  • 不理解為何定位做不到拋物線效果,沒有過渡
  • 用transform就好,有移動
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<style>div {width: 50px;height: 50px;background: red;border-radius: 50%;position: absolute;animation: mymove 5s infinite;}@keyframes mymove {from {left: 0px;}to {left: 300px;}}
</style>
<body><div></div></div>
</body>
</html>

拋物線/貝塞爾曲線動畫 沒用到定位 用的是transform

  • animation-timing-function控制直線/曲線軌跡
  • linear:對角線運動
  • 我的理解:ease-in緩慢開始 ease-out緩慢結束
  • ease相關:拋物線運動ease-in ease-out (_
  • ease-out ease-in:鉛球 T)
  • 需要2元素-2動畫分別控制水平/豎直方向
  • span和span:after
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>元素弧線運動</title><style>.box{width: 400px;height: 400px;border: 2px solid #ff8800;}span{display: block;width: 40px;height: 40px;border: 1px solid #222;animation: center1 2s linear forwards;}span:after{content: '';display: block;width: 40px;height: 40px;border-radius: 20px;background: greenyellow;animation: center2 2s linear forwards;}@keyframes center1 {to{transform: translateX(360px)}}@keyframes center2 {to{transform: translateY(360px)}}</style>
</head>
<body>
<div class="box"><span></span>
</div>
</body>
</html>

三角形翻轉

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>三角形翻轉</title><style>.box {width: 400px;height: 400px;border: 2px solid #ff8800;}span {display: block;width: 40px;height: 40px;/* border: 1px solid #222; *//* 隱藏了 */animation: center1 2s ease-out forwards;}span:after {content: '';display: block;width: 0;height: 0;border-top: 40px solid transparent;border-right: 40px solid greenyellow;animation: center2 2s ease-in forwards;}@keyframes center1 {to {transform: translateX(360px)}}@keyframes center2 {to {transform: translateY(360px) rotate(360deg)}}</style>
</head><body><div class="box"><span></span></div>
</body></html>

翻牌

  • js實現,因為是點擊事件觸發的
  • 正反面的rotateY都是減小的 正面0 → -180 反面180 → 0
  • 正面一開始層級高 backface-visibility:hidden
  • perspective: 看起來更有動效 2000px離遠一點,太近長度變化太夸張
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>翻牌</title><style>div {position: absolute;width: 200px;height: 350px;line-height: 350px;text-align: center;transition: all 3s;perspective: 3000px;}.front {background: gainsboro;transform: rotateY(0);z-index: 1;backface-visibility: hidden;}.back {background: goldenrod;transform: rotateY(180deg);}</style>
</head><body><div class="box"><div class="front">正面</div><div class="back">反面</div></div><script>const oBox = document.getElementsByClassName('box')[0]console.log('oBox', oBox)oBox.onclick = function(){const oFront = document.getElementsByClassName('front')[0]const oBack = document.getElementsByClassName('back')[0]oFront.style = 'transform:rotateY(-180deg)'oBack.style = 'transform:rotateY(0)'}</script>
</body></html>

用reduce實現map

  • reduce做累加可不能初始傳[]進去,[]的toString為’’,最后reduce的結果會變成字符串join
const arr = [1, 2, 3, 4]
// arr.map(callback) 遍歷每個元素 返回[] cb:item index arr
Array.prototype.myMap = function (cb) {const list = []this.reduce((prev, cur, index) => {const r2 = cb(cur, index, this)list.push(r2)}, [])// reduce初始從[]開始,保證index從0開始return list}
const res = arr.myMap((item, index, list) => {return item * 2
})
console.log(res)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250926.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250926.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250926.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

node --- 使用express.Router與body-parser

express框架提供了一個Router方法,用于監聽路由 // 命令行(windows*64) npm install express --save// router.js const express require("express"); // 定義路由 const router express.Router();// 處理http://host:port/students/ 路由(GET方法) router.get…

python基礎1 第一天

TEST 1 阿斯蒂芬 day1test1 while 1&#xff1a;print&#xff08;333&#xff09; import randomprint轉載于:https://www.cnblogs.com/shuangzhu/p/9243853.html

【數據庫】《SQL必知必會 4th》部分筆記

9.匯總數據 count(*) 包括空 count(name) 不包括空 10.分組數據 group by 分組 having 過濾分組 where 過濾行 11.子查詢 select .. from .. where in (select ...) 由內向外處理 A.子查詢過濾 作為子查詢的語句只能查詢單個列。 B.作為計算字段使用子查詢 select cust_name, …

微軟認知服務應用秘籍 – 漫畫翻譯篇

概述 微軟認知服務包括了影像、語音、語言、搜索、知識五大領域&#xff0c;通過對這些認知服務的獨立或者組合使用&#xff0c;可以解決很多現實世界中的問題。作為AI小白&#xff0c;我們可以選擇艱難地攀登崇山峻嶺&#xff0c;也可以選擇像牛頓一樣站在巨人的肩膀上。本章節…

01 React初步認知、React元素、渲染、工程化

定義 react&#xff1a;用于構建用戶界面的 JavaScript 庫 &#xff08;僅負責View層渲染、應在視圖上體現交互邏輯&#xff09;vue&#xff1a;漸進式JavaScript 框架&#xff08;MVVM&#xff09; 使用 引入CDN腳本添加根容器 div #app創建React組件 ReactDOM.render Re…

node --- 在express中配置使用模板引擎(art-template)

下載依賴: npm install --save art-template express-art-template配置: // app.js const express require("express"); const app express(); app.engine("html", require("express-art-template"));使用: 例如處理瀏覽器GET請求 /students…

PAM認證機制

一、PAM簡介 Sun公司1995年開發的一種與認證相關的通用框架機制&#xff0c;PAM只關注如何為服務驗證用戶的API&#xff0c;通過提供一些動態鏈接庫和一套統一的API&#xff0c;將系統提供的服務和該服務的認證方式分開&#xff1b;PAM只是一個框架而已&#xff0c;自身不做認證…

02 JSX學習

使用vite處理jsx vite引入的腳本必須是ESM的 npm init -y yarn add vite package.json 添加vite命令 index.html引入jsxJSX是什么 一種標簽語法&#xff0c;在JS基礎上進行的語法擴展不是字符串、也不是HTML是描述UI呈現與交互的直觀的表現形式JSX被編譯后會生成React元素 &am…

使用FreeCookies 控制瀏覽器cookies及修改http響應內容

FreeCookies 插件安裝 1&#xff1a;您的計算機需要已經安裝Fiddler &#xff08;如未安裝&#xff0c;請至官網下載安裝 http://docs.telerik.com/fiddler/configure-fiddler/tasks/configurefiddler&#xff09; 2&#xff1a;進入Fiddler安裝目錄下的Scripts目錄下&#xff…

node --- 使用node連接mysql

1.確保下載了mysql,且mysql處于打開狀態. 2.確保下載了node,并成功安裝:https://nodejs.org/en/ (小黑窗 node -v 查看) 3.安裝node操作mysql的依賴包: # 命令行 npm install --save -mysql# 注:如果沒有package.json 建議先使用 npm init -y 初始化正題 // app.js// 1. 引…

03 渲染元素ReactDOM.render

React與ReactDOM是2個不同的庫&#xff0c;根節點內的所有內容&#xff08;和DOM更新、渲染相關&#xff09;由ReactDOM來管理一個React應用只有一個根節點用ReactDOM.render將React元素渲染到根節點 ReactDOM.render 參數1 React元素&#xff08;React.createElement(類組件/…

javascript --- 異步按順序執行

使用promise可以很優雅的封裝一個異步函數,使其按指定順序執行: // 異步讀取文件操作 const fs require("fs"); function promiseReadFile(url) {return new Promise(function (resolve, reject) {fs.readFile(url, function(err, data) {if(err) {reject(err);} e…

web提高:負載均衡

1、集群 1、為什么建議在阿里云購買負載均衡 非常便宜&#xff0c;又好用&#xff0c;有穩定&#xff0c;有簡單。自己搭建不了負載均衡&#xff0c;因為共有云不支持組播跑不了vrp協議。你不會集群的概念&#xff0c;你還是蒙蒙的。2、為什么使用集群&#xff1f; 1、小規模 …

node --- 一個很好用的包json-server

這個第三方包,可以將json文件暴露出來,用http獲取. (data.json如下) 下載依賴: npm install --g json-server查看是否含有json-server json -sever --version啟動json-server 參考:https://www.npmjs.com/package/json-server

04 組件與Props

一些概念 組件&#xff1a;視圖的片段、內部管理數據集合&#xff08;state&#xff09;外部傳入配置結合&#xff08;props&#xff09;包含&#xff1a; 1. 視圖標記&#xff08;React的JSX、Vue的template&#xff09;需要經過轉換而成為真實的DOM 事件 數據 邏輯&#x…

利用ionic3進行上一行和左一行不動,中間移動的功能

首先在html中的寫法是 <ion-header><ion-navbar><ion-title>歷史數據</ion-title></ion-navbar></ion-header><ion-content ><div style"display:flex;width:625px;"><div class"head">地區</di…

05 state與setState、單向數據流

聲明周期與組件卸載 props配置&#xff1a;使用組件時傳入數據state私有數據&#xff1a;組件內部使用的數據 state的使用注意事項 必須使用setState方法來更改state多個setState會合并調用props和state更新數據要謹慎&#xff08;有可能在異步程序中更新&#xff09;setState…

HDU 3342 Legal or Not(拓撲排序)

描述 ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas. When someone…

jquery --- 阻止表單默認的提交行為,標準化表單的數據

表單如下: // .html <form id"topics_new_form" method"post" action"/topics/new"><div class"form-group"><label for"exampleInputEmail1">選擇模塊</label><selecet class"form-contr…

javascript --- spa初體驗

首先使用express創建一個簡單的服務器 創建文件夾 be-project # (確保安裝了node,并配置好了環境) 在be-project目錄下(命令行執行) npm init -y npm install --save express body-parse npm install --global nodemon// app.js const express require("express");…