<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] 1\. 數組扁平化 2\. 數組去重 3\. 類數組轉化為數組 (類數組是具有 length 屬性,但不具有數組原型上的方法) 4\. array.prototype.filter() 5\. Array.prototype.map() 6\. Array.prototype.forEach() 7\. Array.prototype.reduce() 8\. Apple() (function.prototype.apple()) 9\. call 10\. Bind() 11\. Debounce () 防抖 (頻率高頻時間后 n 秒內函數只會執行一次,如果 n 秒內高頻時間再次觸發,則重新計算時間) 12\. throttle 節流 () 13\. 函數珂里化 14\. 模擬 new 操作 15\. Instanceof 運算符用于檢測構造函數的 prototype 屬性是否出現在某一個實例對象的原型鏈上 16\. 原型繼承 17\. Object.is 18\. Object.assign () 方法用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象 (它返回目標對象 這個操作是淺拷貝) 19\. 深拷貝 20\. promise 21\. Promise.all 22\. Promise.race 23\. Promise 并行限制 24\. JSONP 25\. AJAX 26\. event 模塊 實現 node 中回調函數的機制,node 中回調函數其實是內部使用了觀察者模式 27\. 圖片懶加載 28\. 滾動加載 29\. 渲染幾萬條數據不卡住頁面 (渲染大數據時,合理利用 createDocumentFragment 和 requestAnimationFrame,將操作切分為一小段一小段執行) 30\. 打印出當前頁面使用了多少種 HTML 元素 31\. 將 virtualDom 轉化為真實 DOM 結構 32\. 字符串解析問題 () # 深拷貝 簡單版: ``` function deepCopy(obj){ var cloneObj; // 當輸入數據為簡單數據類型時直接復制 if (obj && typeof obj!=='object'){ return obj;} // 當輸入數據為對象或數組時 else if (obj && typeof obj==='object'){ // 檢測輸入數據是數組還是對象 cloneObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)){ if(obj[key]&&typeof obj[key] === 'object') { // 若當前元素類型為對象時,遞歸調用 cloneObj[key] = deepCopy(obj[key]); } // 若當前元素類型為基本數據類型 else{ cloneObj[key] = obj[key]; } } } } return cloneObj; } ``` 第二種: ~~~js /** * Get the first item that pass the test * by second argument function * * @param {Array} list * @param {Function} f * @return {*} */ export function find (list, f) { return list.filter(f)[0] } /** * Deep copy the given object considering circular structure. * This function caches all nested objects and its copies. * If it detects circular structure, use cached copy to avoid infinite loop. * * @param {*} obj * @param {Array<Object>} cache * @return {*} */ export function deepCopy (obj, cache = []) { // just return if obj is immutable value if (obj === null || typeof obj !== 'object') { return obj } // if obj is hit, it is in circular structure const hit = find(cache, c => c.original === obj) if (hit) { return hit.copy } const copy = Array.isArray(obj) ? [] : {} // put the copy into cache at first // because we want to refer it in recursive deepCopy cache.push({ original: obj, copy }) Object.keys(obj).forEach(key => { copy[key] = deepCopy(obj[key], cache) }) return copy } ~~~ # 自定義柯里化函數: 實現 1: ``` function curry(func) { return function curried(...args) { console.log(args); if (args.length >= func.length) { return func.apply(this, args); } else { console.log('calling else'); return function(...args2) { return curried.apply(this, args.concat(args2)); } } }; } // 測試 function multiply(a, b, c) { return a * b * c; } let curried = curry(multiply); console.log(curried(1, 2, 3)); console.log(curried(1)(2, 3)); console.log(curried(1)(2)(3)); ``` 實現 2: ``` const curry = fn => (judge = (...args) => args.length === fn.length ? fn(...args) : (...arg) => judge(...args, ...arg)); // 測試 const sum = (a, b, c, d) => a + b + c + d; const currySum = curry(sum); currySum(1)(2)(3)(4); // 10 currySum(1, 2)(3)(4); // 10 currySum(1)(2, 3)(4); // 10 ``` > http://zetcode.com/javascript/currying/ # call 實現 原理:在方法調用模式下,`this`總是指向調用它所在方法的對象,`this`的指向與所在方法的調用位置有關,而與方法的聲明位置無關(箭頭函數特殊)。 ``` const foo = { name: 'foo' }; foo.fn = function() { // 這里的 this 指向了 foo // 因為 foo 調用了 fn, // fn 的 this 就指向了調用它所在方法的對象 foo 上 console.log(this.name); // foo }; ``` 實現: ```js Function.prototype.mycall = function(thisArg) { // this指向調用call的對象 if (typeof this !== 'function') { // 調用call的若不是函數則報錯 throw new TypeError('Error'); } const args = [...arguments].slice(1); thisArg = thisArg || window; // 將調用call函數的對象添加到 thisArg 的屬性中 thisArg.fn = this; // 執行該屬性 const result = thisArg.fn(...arg); // 刪除該屬性 delete thisArg.fn; // 返回函數執行結果 return result; }; ``` # 實現 new 方法 ``` function myNew(){ var obj = {} var Constructor = Array.prototype.shift.call(arguments) obj.__proto__ = Constructor.prototype // 把實例與構造函數它們的關系建立起來 var res = Constructor.apply(obj, arguments) return typeof res === 'object' ? res : obj; } ``` # 數組扁平化 ``` // 方案 1 function recursionFlat(ary = []) { const res = [] ary.forEach(item => { if (Array.isArray(item)) { res.push(...recursionFlat(item)) } else { res.push(item) } }) return res } // 方案 2 function reduceFlat(ary = []) { return ary.reduce((res, item) => res.concat(Array.isArray(item) ? reduceFlat(item) : item), []) } // 測試 const source = [1, 2, [3, 4, [5, 6]], '7'] console.log(recursionFlat(source)) console.log(reduceFlat(source)) ``` # 對象扁平化 ``` function objectFlat(obj = {}) { const res = {} function flat(item, preKey = '') { Object.entries(item).forEach(([key, val]) => { const newKey = preKey ? `${preKey}.${key}` : key if (val && typeof val === 'object') { flat(val, newKey) } else { res[newKey] = val } }) } flat(obj) return res } // 測試 const source = { a: { b: { c: 1, d: 2 }, e: 3 }, f: { g: 2 } } console.log(objectFlat(source)); ``` # ES 5、ES 6繼承 主要使用 ES 5 跟 ES 6 對比看下`class`繼承的原理 使用`es6`語法 ~~~ class B { constructor(opt) { this.BName = opt.name; } } class A extends B { constructor () { // 向父類傳參 super({ name: 'B' }); // this 必須在 super() 下面使用 console.log(this); } } ~~~ 使用`es5`語法 使用寄生組合繼承的方式 1. 原型鏈繼承,使子類可以調用父類原型上的方法和屬性 2. 借用構造函數繼承,可以實現向父類傳參 3. 寄生繼承,創造干凈的沒有構造方法的函數,用來寄生父類的 prototype ~~~ // 實現繼承,通過繼承父類 prototype function __extends(child, parent) { // 修改對象原型 Object.setPrototypeOf(child, parent); // 寄生繼承,創建一個干凈的構造函數,用于繼承父類的 prototype // 這樣做的好處是,修改子類的 prototype 不會影響父類的 prototype function __() { // 修正 constructor 指向子類 this.constructor = child; } // 原型繼承,繼承父類原型屬性,但是無法向父類構造函數傳參 child.prototype = parent === null ? Object.create(parent) : ((__.prototype = parent.prototype), new __()); } var B = (function() { function B(opt) { this.name = opt.name; } return B; })(); var A = (function(_super) { __extends(A, _super); function A() { // 借用繼承,可以實現向父類傳參, 使用 super 可以向父類傳參 return (_super !== null && _super.apply( this, { name: 'B' })) || this; } return A; })(B); ~~~ 測試 class ~~~ const a = new A(); console.log(a.BName, a.constructor); // B ,? A() {} ~~~ # Object.create 的實現 ~~~ function create(obj) { function F() {} F.prototype = obj; return new F(); } ~~~ # 參考 [JS 基礎手寫代碼](https://hub.fastgit.org/Godiswill/blog/issues/20) [前端面試中常見的手寫功能](https://www.h5w3.com/44219.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看