前端 P5 最基本應該掌握的程式碼實現
前景
疫情無情人有情,在去年經歷網際網路一系列的風波之後,我相信大家有很多的小夥伴想在今年金三銀四的面試季中為自己的未來找一個好一點的公司。那麼今天我們來講解一下身為 P5 工程師需要知道的一些原理及其如何親自手寫出它的實現過程,有可能我們日常開發業務的時候用不上這些自己寫的方法,但是我們我們對原理一無所知,那麼在面試的時候一旦被深挖那麼可能離自己心念的公司就會又遠一步。
模式 call
- 第一個引數為 null或者 undefined 時,this 指向全域性物件 window,值為原始值的指向改原始值的自動包裝物件,如 String、number、boolean
- 為了避免函式名與上下問(context)的屬性發生衝突,使用 Symbol 型別作為唯一值
- 將函式作為傳入的上下文(context)屬性執行
- 函式執行完後刪除改屬性
- 返回執行結果
Function.prototype.myCall = function(context,...args){
context = (context ?? window) || new Object(context);
const key = Symbol();
context[key] = this;
const result = context[key](...args);
delete context[key];
return result;
}
模式 apply
- 前部分與call一樣
- 第二個引數可以不傳,但型別必須為陣列或者類陣列
Function.prototype.myApply = function(context) {
context = (context ?? window) || new Object(context)
const key = Symbol()
const args = arguments[1]
context[key] = this
let result
if(args) {
result = context[key](...args)
} else {
result = context[key]
}
delete context[key]
return result
}
模式 bind
- 使用 call / apply 指定 this
- 返回一個繫結函式
- 當返回的繫結函式作為建構函式被new呼叫,繫結的上下文指向例項物件
- 設定繫結函式的prototype 為原函式的prototype
Function.prototype.myBind = function(context, ...args) {
const fn = this
const bindFn = function (...newFnArgs) {
fn.call(
this instanceof bindFn ? this : context,
...args, ...newFnArgs
)
}
bindFn.prototype = Object.create(fn.prototype)
return bindFn
}
深複製
- 判斷型別是否為原始型別,如果是,無需複製直接返回
- 為避免出現迴圈引用,複製物件時先判斷儲存空間中是否存在當前物件,如果有就直接返回
- 開闢一個儲存空間,來儲存當前物件和複製物件的對應關係
- 對引用型別遞迴複製直到屬性為原始型別
const deepClone = (target, cache = new WeakMap()) => {
if(target === null || typeof target !== 'object') {
return target
}
if(cache.get(target)) {
return target
}
const copy = Array.isArray(target) ? [] : {}
cache.set(target, copy)
Object.keys(target).forEach(key => copy[key] = deepClone(obj[key], cache))
return copy
}
函式防抖
- this繼承自父級上下文,指向觸發事件的目標元素
- 事件被觸發時,傳入event物件
- 傳入leading引數,判斷是否可以立即執行回撥函式,不必要等到事件停止觸發後才開始執行
- 回撥函式可以有返回值,需要返回執行結果
const debounce = (fn, wait = 300, leading = true) => {
let timerId, result
return function(...args) {
timerId && clearTimeout(timerId)
if (leading) {
if (!timerId) result = fn.apply(this, args)
timerId = setTimeout(() => timerId = null, wait)
} else {
timerId = setTimeout(() => result = fn.apply(this, args), wait)
}
return result
}
}
函式節流(定時器)
函式停止觸發後 n妙後開始執行,停止觸發後繼續執行一次事件
const throttle = (fn, wait = 300) => {
let timerId
return function(...args) {
if(!timerId) {
timerId = setTimeout(() => {
timerId = null
return result = fn.apply(this, ...args)
}, wait)
}
}
}
函式節流(時間戳)
函式觸發後立刻執行,停止觸發後不在執行事件
const throttle = (fn, wait = 300) => {
let prev = 0
let result
return function(...args) {
let now = +new Date()
if(now - prev > wait) {
prev = now
return result = fn.apply(this, ...args)
}
}
}
ES6版繼承
ES5的繼承,實質是先創造子類的例項物件,然後將再將父類的方法新增到this上。ES6的繼承,先創造父類的例項物件(所以必須先呼叫super方法,然後再用子類的建構函式修改this。
class Super { constructor(foo) { this.foo = foo } printFoo() { console.log(this.foo) } } class Sub extends Super { constructor(foo, bar) { super(foo) this.bar = bar } }js
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2824845/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前端應該掌握的nginx知識前端Nginx
- 前端css實現最基本的時間軸前端CSS
- 一個自信的前端應該掌握的CDN操作前端
- 前端都應該要掌握的防抖和節流前端
- 我們應該如何編寫高質量的前端程式碼前端
- Java之列舉, 程式設計師應該掌握的開發技巧“簡潔易懂又安全的程式碼”Java程式設計師
- 一名合格的前端開發工程師應該掌握的8個技能前端工程師
- Android開發應該掌握的Proguard技巧Android
- Android 開發應該掌握的 Proguard 技巧Android
- 前端應該知道的GraphQL前端
- web前端換行程式碼的幾種實現方式!Web前端行程
- 一行程式碼實現微前端行程前端
- 前端應該瞭解的PWA前端
- 結合自己經歷聊聊注重實效的程式設計師應該掌握的幾個原則程式設計師
- 寫程式碼之前應該做的幾件事
- ORACLE DBA應該掌握的9個免費工具Oracle
- 後端開發應該掌握的Redis基礎後端Redis
- 雷達學習者應該掌握的MATLAB ToolboxMatlab
- 簡單實現幾種常見的前端效果,附程式碼!前端
- 中級JAVA程式設計師應該掌握的資料結構知識Java程式設計師資料結構
- 你應該知道的前端——快取前端快取
- 前端應該知道的web登入前端Web
- 你應該知道的前端--儲存前端
- 你應該知道的前端--渲染原理前端
- 白碼低程式碼平臺探索:10分鐘實現一個表單應用(包含前端)前端
- 熱門盤點:企業該如何對待低程式碼?應不應該選擇低程式碼?
- 使阿里oss實現前端程式碼自動上傳阿里前端
- 低程式碼平臺探索:10分鐘實現一個表單應用(包含前端)前端
- 遊戲陪玩原始碼的移動端適配,應該如何實現?遊戲原始碼
- 前端沙箱利用這些特性實現程式碼的隔離和限制前端
- 棧的應用場景思路分析和程式碼實現
- 好程式設計師web前端分享應該怎樣學好web前端?程式設計師Web前端
- 那些前端應該知道的HTTP知識前端HTTP
- 前端基礎入門五(掌握jQuery的常用api,實現動態效果)前端jQueryAPI
- Go程式崩潰現場應該如何保留?Go
- 窺探原理:實現一個簡單的前端程式碼打包器 Roid前端
- 前端程式設計師必須掌握之三角函式在前端動畫中的應用前端程式設計師函式動畫
- web前端入門到實戰:30行前端程式碼實現任意文字轉粒子Web前端