国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù)

這篇具有很好參考價值的文章主要介紹了5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

淺拷貝與深拷貝

淺拷貝

淺拷貝是創(chuàng)建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。如果屬性是基本類型,拷貝的就是基本類型的值,如果屬性是引用類型,拷貝的就是內(nèi)存地址,所以如果其中一個對象改變了這個地址,就會影響到另一個對象。

//實現(xiàn)淺拷貝
function shallowCopy (obj){
    // 只拷貝對象,基本類型或null直接返回
    if(typeof obj !== 'object' || obj === null) {
    	return obj;
    }
    // 判斷是新建一個數(shù)組還是對象
    let newObj = Array.isArray(obj) ? []: {};
    //for…in會遍歷對象的整個原型鏈,如果只考慮對象本身的屬性,需要搭配hasOwnProperty
    for(let key in obj ){
        //hasOwnProperty判斷是否是對象自身屬性,會忽略從原型鏈上繼承的屬性
        if(obj.hasOwnProperty(key)){
        	newObj[key] = obj[key];//只拷貝對象本身的屬性
        }
    }
    return newObj;
}
 
//測試
var obj ={
    name:'張三',
    age:8,
    pal:['王五','王六','王七']
}
let obj2 = shallowCopy(obj);
obj2.name = '李四'
obj2.pal[0] = '王麻子'
console.log(obj); //{age: 8, name: "張三", pal: ['王麻子', '王六', '王七']}
console.log(obj2); //{age: 8, name: "李四", pal: ['王麻子', '王六', '王七']}

測試結(jié)果:

5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù),前端,javascript,開發(fā)語言

深拷貝

深拷貝是將一個對象從內(nèi)存中完整的拷貝一份出來,從堆內(nèi)存中開辟一個新的區(qū)域存放新對象,且修改新對象不會影響原對象。

function deepCopy (obj, map = new WeakMap()){
    // 基本類型或null直接返回
    if(typeof obj !== 'object' || obj === null) {
    	return obj;
    }
    // 判斷是新建一個數(shù)組還是對象
    let newObj = Array.isArray(obj) ? []: {};
    //利用map解決循環(huán)引用
    if (map.has(obj)) {
        return map.get(obj);
    }
    map.set(obj, newObj);//將當(dāng)前對象作為key,克隆對象作為value
    for(let key in obj ){	
        if(obj.hasOwnProperty(key)){
        	newObj[key] = deepCopy(obj[key], map);	//遞歸
        }
    }
    return newObj
}
 
// 測試
let obj1 = {
    name : 'AK、噠噠噠',
    arr : [1,[2,3],4],
};
let obj2=deepCopy(obj1)
obj2.name = "噠噠噠";
obj2.arr[1] = [5,6,7] ; // 新對象跟原對象不共享內(nèi)存
 
console.log('obj1',obj1) // obj1 { name: 'AK、噠噠噠', arr: [ 1, [ 2, 3 ], 4 ] }
console.log('obj2',obj2) // obj2 { name: '噠噠噠', arr: [ 1, [ 5, 6, 7 ], 4 ] }

測試結(jié)果:

5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù),前端,javascript,開發(fā)語言

函數(shù)柯里化

函數(shù)柯里化指的是一種將使用多個參數(shù)的一個函數(shù)轉(zhuǎn)換成一系列使用一個參數(shù)的函數(shù)的技術(shù)。

作用:可以參數(shù)復(fù)用(公共的參數(shù)已經(jīng)通過柯里化預(yù)置了)和延遲執(zhí)行(柯里化時只是返回一個預(yù)置參數(shù)的新函數(shù),并沒有立刻執(zhí)行,在滿足條件后才會執(zhí)行)。

參數(shù)定長的柯里化

思路:通過函數(shù)的length屬性獲取函數(shù)的形參個數(shù),形參的個數(shù)就是所需參數(shù)的個數(shù)。維護(hù)一個數(shù)組,當(dāng)數(shù)組的長度與函數(shù)接收參數(shù)的個數(shù)一致,再執(zhí)行該函數(shù)。

// 實現(xiàn)函數(shù)柯里化
function curry(fn) {
  // 返回一個新函數(shù)
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args); // 如果參數(shù)夠了,就執(zhí)行原函數(shù),返回結(jié)果
    } else {
      //返回一個新函數(shù),繼續(xù)遞歸去進(jìn)行柯里化,利用閉包,將當(dāng)前已經(jīng)傳入的參數(shù)保存下來
      return function (...args2) {
        //遞歸調(diào)用 curried 函數(shù)
        return curried.apply(this, [...args, ...args2]); //新函數(shù)調(diào)用時會繼續(xù)傳參,拼接參數(shù)
      };
    }
  };
}
 
// 測試
function sum(a, b, c) {
  return a + b + c;
}
var curried = curry(sum);
console.log(curried(1, 2, 3)); //6
console.log(curried(1, 2)(3)); //6
console.log(curried(1)(2, 3)); //6
console.log(curried(1)(2)(3)); //6

測試結(jié)果:

5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù),前端,javascript,開發(fā)語言

參數(shù)不定長的柯里化

題目:如何實現(xiàn)一個方法,使計算結(jié)果能夠滿足如下預(yù)期。

add(1, 2, 3) // 6
add(1) // 1
add(1)(2) // 3
add(1, 2)(3) // 6
add(1)(2)(3) // 6
add(1)(2)(3)(4) // 10

思路:利用閉包和遞歸,如果參數(shù)為空,則判斷遞歸結(jié)束,求和,返回結(jié)果。


function addCurry() {
    // 利用閉包的特性收集所有參數(shù)值
    let arr = [...arguments]	
    //返回函數(shù)
    return function fn() {
        // 如果參數(shù)為空,則判斷遞歸結(jié)束,即傳入一個()執(zhí)行函數(shù)
        if(arguments.length === 0) {	
	    	return arr.reduce((a, b) => a + b)	// 求和
        } else {
            arr.push(...arguments)
            return fn	//遞歸
        }
    }
}
 
// 測試
console.log(addCurry(1)());	//1
console.log(addCurry(1)(2)());	//3
console.log(addCurry(1)(2)(3)());	//6
console.log(addCurry(1, 2)(3)());	//6
console.log(addCurry(1, 2, 3)());	//6

上述寫法,總是要以空括號()結(jié)尾,于是再改進(jìn)為隱式轉(zhuǎn)換.toString寫法,原理:當(dāng)用 Function的值做計算的時候,會調(diào)用toString做隱式轉(zhuǎn)換。注意一些舊版本的瀏覽器隱式轉(zhuǎn)換會默認(rèn)執(zhí)行,新版本不行了??梢岳秒[式轉(zhuǎn)換或者alert。

function addCurry() {
    let arr = [...arguments]
    // 利用閉包的特性收集所有參數(shù)值
    var fn = function() {
        arr.push(...arguments);
        return fn;//遞歸
    };
    // 利用 toString 隱式轉(zhuǎn)換,轉(zhuǎn)換的時候再返回結(jié)果
    fn.toString = function () {
        return arr.reduce(function (a, b) {
            return a + b;
        });
    }
    return fn;
}
 
//測試
console.log(addCurry(1)(2) == 3) //true 利用隱式轉(zhuǎn)換,自動調(diào)用toString方法得到柯里化的結(jié)果
//alert(addCurry(1)(2)(3))//6 alert參數(shù)只能是字符串,如果其他類型的值,會轉(zhuǎn)換成字符串,會調(diào)用toString方法
console.log(addCurry(1).toString());//1 手動調(diào)用toString
console.log(addCurry(1, 2)(3).toString());//6 
console.log(addCurry(1, 2)(3)(4)(5).toString());//15 

測試結(jié)果:

5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù),前端,javascript,開發(fā)語言

數(shù)組扁平化

數(shù)組扁平化其實就是將多維數(shù)組轉(zhuǎn)為一維數(shù)組。

ES6中的flat

const arr = [1,[2,[3,[4,5]]],6]
//  arr.flat([depth]) flat的參數(shù)代表的是需要展開幾層,如果是Infinity的話,就是不管嵌套幾層,全部都展開
console.log(arr.flat(Infinity)) //[1,2,3,4,5,6]

遞歸

let arr = [1, [2, [3, 4]]];
function flatten(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    //如果當(dāng)前元素還是一個數(shù)組
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]));//遞歸拼接
    } else {
      result.push(arr[i]);
    }
  }
  return result;
}
console.log(flatten(arr)); //  [1, 2, 3, 4]

reduce函數(shù)迭代

從上面普通的遞歸函數(shù)中可以看出,其實就是對數(shù)組的每一項進(jìn)行處理,那么其實也可以用reduce來實現(xiàn)數(shù)組的拼接,從而簡化第一種方法的代碼。

let arr = [1, [2, [3, 4]]];
function flatten(arr) {
  return arr.reduce((total, cur) => {
    return total.concat(Array.isArray(cur) ? flatten(cur) : cur);
  }, []); //傳遞初始值空數(shù)組[],就會從數(shù)組索引為 0 的元素開始執(zhí)行
}
console.log(flatten(arr)); //  [1, 2, 3, 4]

split和toString

數(shù)組的toString方法可以把數(shù)組直接轉(zhuǎn)換成逗號分隔的字符串。如[1, [2, [3, 4]]] => “1,2,3,4”

let arr = [1, [2, [3, 4]]];
function flatten(arr) {
  //先把數(shù)組直接轉(zhuǎn)換成逗號分隔的字符串,然后再用 split 方法把字符串重新轉(zhuǎn)換為數(shù)組
  return arr.toString().split(",").map(Number); 
}
console.log(flatten(arr)); //  [ 1, 2, 3, 4 ]

數(shù)組去重

利用Set。new一個Set,參數(shù)為需要去重的數(shù)組,Set會自動刪除重復(fù)的元素,在Array.form將Set轉(zhuǎn)為數(shù)組返回

const arr = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
console.log([...new Set(arr)]); //[ 1, 2, 3, 5, 9, 8 ]
console.log(Array.from(new Set(arr))); //[ 1, 2, 3, 5, 9, 8 ]

利用數(shù)組的filter()+indexOf去重。利用filter方法,返回arr.indexOf(num)等于index的值。原理就是indexOf會返回先找到的數(shù)字的索引。


function unique(arr) {
  return arr.filter((item, index, array) => {
    return array.indexOf(item) === index;
  });
}
const arr = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
console.log(unique(arr)); // [1, 2, 3, 5, 9, 8]

利用Map。新建一個數(shù)組和map,如果當(dāng)前值在map中沒有出現(xiàn)過,就加入數(shù)組,最后返回數(shù)組

const unique = (arr) => {
    const map = new Map();
    const res = [];
    for (let item of arr) {
        if (!map.has(item)) {
            map.set(item, true);
            res.push(item);
        }
    }
    return res;
}
const arr = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
console.log(unique(arr)); // [1, 2, 3, 5, 9, 8]

手寫類型判斷函數(shù)

思路:如果是null,直接返回String(null);基本類型和函數(shù),直接使用typeof;其它引用類型,使用Object.prototype.toString.call。

function getType(value) {
  // 判斷數(shù)據(jù)是 null 的情況
  let type;
  if (value === null) {
    return String(value);
  }
  // 判斷數(shù)據(jù)是基本數(shù)據(jù)類型的情況和函數(shù)的情況,使用typeof
  if (typeof value !== "object") {
    return typeof value;
  } else {
    // 判斷數(shù)據(jù)是引用類型的情況,設(shè)當(dāng)前類型為date
    let valueClass = Object.prototype.toString.call(value); //"[object Date]"
    type = valueClass.split(" ")[1].split(""); //[ 'D', 'a', 't', 'e', ']' ] 截取類型并轉(zhuǎn)換為數(shù)組
    type.pop(); //[ 'D', 'a', 't', 'e' ],去掉數(shù)組最后的右括號"]"
    return type.join("").toLowerCase(); //[ 'D', 'a', 't', 'e' ] => "Date" => "date" 數(shù)組轉(zhuǎn)小寫字符串
  }
}

// 測試
console.info(getType(null)); // null
console.info(getType(undefined)); // undefined
console.info(getType(100)); // number
console.info(getType("abc")); // string
console.info(getType(true)); // boolean
console.info(getType(Symbol())); // symbol
console.info(getType({})); // object
console.info(getType([])); // array
console.info(getType(() => {})); // function
console.info(getType(new Date())); // date
console.info(getType(new RegExp(""))); // regexp
console.info(getType(new Map())); // map
console.info(getType(new Set())); // set
console.info(getType(new WeakMap())); // weakmap
console.info(getType(new WeakSet())); // weakset
console.info(getType(new Error())); // error
console.info(getType(new Promise(() => {}))); // promise

測試結(jié)果:
5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù),前端,javascript,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-858820.html

到了這里,關(guān)于5個常見的前端手寫功能:淺拷貝與深拷貝、函數(shù)柯里化、數(shù)組扁平化、數(shù)組去重、手寫類型判斷函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • python-淺拷貝(copy)與深拷貝(deepcopy)

    python-淺拷貝(copy)與深拷貝(deepcopy)

    目錄 一、前言: 二、深拷貝與淺拷貝的異同: ? ? ? ? 1.相同點:? ? ? ? ????????2.不同點: ????????3.形象說明: ? ? ? ? 注意: 三、淺拷貝: ?3.1.1淺拷貝示意圖: 3.1.2示意圖說明 ? ? ? ? 1.對象與子對象(元素)的關(guān)系: ????????2.對象: ????????3.元

    2024年02月11日
    瀏覽(16)
  • 詳解js中的淺拷貝與深拷貝

    詳解js中的淺拷貝與深拷貝

    1.1 棧(stack)和堆(heap) 棧(stack):由操作系統(tǒng)自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧; 堆(heap):一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收,分配方式倒是類似于鏈表 1.2 基本數(shù)據(jù)類型和引用數(shù)據(jù)類

    2024年02月08日
    瀏覽(19)
  • Pandas數(shù)據(jù)中的淺拷貝與深拷貝

    Pandas數(shù)據(jù)中的淺拷貝與深拷貝

    pandas庫主要有兩種數(shù)據(jù)結(jié)構(gòu)DataFrames和Series。這些數(shù)據(jù)結(jié)構(gòu)在內(nèi)部用索引數(shù)組和數(shù)據(jù)數(shù)組表示,索引數(shù)組標(biāo)記數(shù)據(jù),數(shù)據(jù)數(shù)組包含實際數(shù)據(jù)?,F(xiàn)在,當(dāng)我們試圖復(fù)制這些數(shù)據(jù)結(jié)構(gòu)(DataFrames和Series)時,我們實際上是復(fù)制對象的索引和數(shù)據(jù),有兩種方法可以做到這一點,即淺復(fù)

    2024年02月09日
    瀏覽(17)
  • 前端常見面試題之js基礎(chǔ)(手寫深拷貝、原型和原型鏈、作用域和閉包)

    值類型包括 :字符串(string)、數(shù)字(number)、布爾值(boolean)、undefined。 引用類型包括 :對象(object)、數(shù)組(array)、函數(shù)(function)和null。 二者的區(qū)別 當(dāng)你將一個值類型賦給另一個變量時,會復(fù)制該值的副本。而當(dāng)你將一個引用類型賦給另一個變量時,只會復(fù)制對

    2024年01月22日
    瀏覽(26)
  • [開發(fā)語言][c++][python]:C++與Python中的賦值、淺拷貝與深拷貝

    [開發(fā)語言][c++][python]:C++與Python中的賦值、淺拷貝與深拷貝

    寫在前面 :Python和C++中的賦值與深淺拷貝,由于其各自語言特性的問題,在概念和實現(xiàn)上稍微有點差異,本文將這C++和Python中的拷貝與賦值放到一起,希望通過對比學(xué)習(xí)兩語言實現(xiàn)上的異同點,加深對概念的理解。 C++中所謂的 淺拷貝 就是由(系統(tǒng)默認(rèn)的) 拷貝構(gòu)造函數(shù)對

    2024年02月02日
    瀏覽(27)
  • 高階函數(shù)和函數(shù)柯里化

    ????????高階函數(shù)是指可以接受一個或多個函數(shù)作為參數(shù),并且/或者返回一個新函數(shù)的函數(shù)。換句話說,它可以操作其他函數(shù),使得代碼更加抽象和靈活。高階函數(shù)的存在使得函數(shù)可以作為一等公民在代碼中傳遞和使用。 ? ? ? ? 如下的函數(shù)就是一個高階函數(shù),他可以傳

    2024年02月13日
    瀏覽(27)
  • JS之函數(shù)柯里化

    維基百科中對柯里化 (Currying) 的定義為: In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. 翻譯成中文: 在數(shù)學(xué)和計算機(jī)科學(xué)中,柯里化是一種將使

    2024年01月17日
    瀏覽(15)
  • 【學(xué)姐面試寶典】前端基礎(chǔ)篇Ⅴ——JS深淺拷貝、箭頭函數(shù)、事件監(jiān)聽等

    【學(xué)姐面試寶典】前端基礎(chǔ)篇Ⅴ——JS深淺拷貝、箭頭函數(shù)、事件監(jiān)聽等

    前言 博主主頁????蠟筆雛田學(xué)代碼 專欄鏈接????【前端面試專欄】 今天繼續(xù)學(xué)習(xí)前端面試題相關(guān)的知識! 感興趣的小伙伴一起來看看吧~?? addEventListener()方法,用于向指定元素添加事件句柄,它可以更簡單的控制事件。語 法為: 第一個參數(shù)是 事件的類型 (如 “click”

    2024年01月19日
    瀏覽(54)
  • 【es6】函數(shù)柯里化(Currying)

    【es6】函數(shù)柯里化(Currying)

    柯里化(Currying):把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)且返回結(jié)果的新函數(shù)。 柯里化由 Christopher Strachey 以邏輯學(xué)家 Haskell Curry 命名的,它是 Moses Schnfinkel 和 Gottlob Frege 發(fā)明的。 柯里化的應(yīng)用最為切底是純

    2024年02月12日
    瀏覽(27)
  • 【JavaScript】面試手撕柯里化函數(shù)

    【JavaScript】面試手撕柯里化函數(shù)

    ??個人主頁: 鑫寶Code ??熱門專欄: 閑話雜談| 炫酷HTML | JavaScript基礎(chǔ) ? ??個人格言: \\\"如無必要,勿增實體\\\" 上周我一個學(xué)弟,去字節(jié)面試實習(xí)生。面試官問他有沒有用過柯里化,他搖了搖頭。 有一說一,確實柯里化在現(xiàn)實中的項目還是用的比較少的。?? 面試官繼續(xù)問他是

    2024年03月15日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包