中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

南平網(wǎng)站開發(fā)客戶引流推廣方案

南平網(wǎng)站開發(fā),客戶引流推廣方案,網(wǎng)絡(luò)營銷的營銷方式是什么,做網(wǎng)站 多少錢前言 📫 大家好,我是南木元元,熱愛技術(shù)和分享,歡迎大家交流,一起學習進步! 🍅 個人主頁:南木元元 今天來分享一下10個常見的JavaScript手寫功能。 目錄 1.實現(xiàn)new 2.call、apply、…

前言

?📫 大家好,我是南木元元,熱愛技術(shù)和分享,歡迎大家交流,一起學習進步!

?🍅?個人主頁:南木元元

今天來分享一下10個常見的JavaScript手寫功能。


目錄

1.實現(xiàn)new

2.call、apply、bind

實現(xiàn)call

實現(xiàn)apply

實現(xiàn)bind

3.防抖和節(jié)流

防抖

節(jié)流

4.實現(xiàn)instanceof

5.實現(xiàn)Ajax

6.深拷貝和淺拷貝

淺拷貝

深拷貝

7.函數(shù)柯里化

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

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

8.數(shù)組扁平化

9.數(shù)組去重

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

?結(jié)語


1.實現(xiàn)new

(1)首先創(chuàng)建一個新的空對象。

(2)設(shè)置原型,將對象的原型設(shè)置為函數(shù)的prototype對象。

(3)讓函數(shù)的this指向這個對象,執(zhí)行構(gòu)造函數(shù)的代碼。

(4)判斷函數(shù)的返回值類型,如果是值類型,返回創(chuàng)建的對象。如果是引用類型,就返回這個引用類型的對象。

function myNew(constructor, ...args) {// 如果不是一個函數(shù),就報錯if (typeof constructor !== "function") {throw "myNew function the first param must be a function";}// 基于原型鏈 創(chuàng)建一個新對象,繼承構(gòu)造函數(shù)constructor的原型對象上的屬性let newObj = Object.create(constructor.prototype);// 將newObj作為this,執(zhí)行 constructor ,傳入?yún)?shù)let res = constructor.apply(newObj, args);// 判斷函數(shù)的執(zhí)行結(jié)果是否是對象,typeof null 也是'object'所以要排除nulllet isObject = typeof res === "newObject" && res !== null;// 判斷函數(shù)的執(zhí)行結(jié)果是否是函數(shù)let isFunction = typeof res === "function";// 如果函數(shù)的執(zhí)行結(jié)果是一個對象或函數(shù), 則返回執(zhí)行的結(jié)果, 否則, 返回新創(chuàng)建的對象return isObject || isFunction ? res : newObj;
}// 用法
function Person(name, age) {this.name = name;this.age = age;// 如果構(gòu)造函數(shù)內(nèi)部,return 一個引用類型的對象,則整個構(gòu)造函數(shù)失效,而是返回這個引用類型的對象
}
Person.prototype.say = function() {console.log(this.age);
};
let p1 = myNew(Person, "poety", 18);
console.log(p1.name);	//poety
console.log(p1);	//Person {name: 'poety', age: 18}
p1.say();	//18

測試結(jié)果:?

2.call、apply、bind

實現(xiàn)call

思路:接受傳入的context上下文,如果不傳默認為window,將被調(diào)用的方法設(shè)置為上下文的屬性,使用上下文對象來調(diào)用這個方法,刪除新增屬性,返回結(jié)果。

//寫在函數(shù)的原型上
Function.prototype.myCall = function (context) {// 如果要調(diào)用的方法不是一個函數(shù),則報錯if (typeof this !== "function") {throw new Error("Type error");}// 判斷 context 是否傳入,如果沒有傳就設(shè)置為 windowcontext = context || window;// 獲取參數(shù),[...arguments]把類數(shù)組轉(zhuǎn)為數(shù)組let args = [...arguments].slice(1);let result = null;// 將被調(diào)用的方法設(shè)置為context的屬性,this即為要調(diào)用的方法context.fn = this;// 執(zhí)行要被調(diào)用的方法result = context.fn(...args);// 刪除手動增加的屬性方法delete context.fn;// 將執(zhí)行結(jié)果返回return result;
};//測試
function f(a,b){console.log(a+b)console.log(this.name)
}
let obj={name:1
}
f.myCall(obj,1,2) // 3,1

測試結(jié)果:

實現(xiàn)apply

除了傳參方式是數(shù)組,其它與call沒區(qū)別。

Function.prototype.myApply = function (context) {if (typeof this !== "function") {throw new Error("Type error");}let result = null;context = context || window;// 與上面代碼相比,我們使用 Symbol 來保證屬性唯一,也就是保證不會重寫用戶自己原來定義在 context 中的同名屬性const fnSymbol = Symbol();context[fnSymbol] = this;// 執(zhí)行要被調(diào)用的方法,處理參數(shù)和 call 有區(qū)別,判斷是否傳了參數(shù)數(shù)組if (arguments[1]) {//傳了參數(shù)數(shù)組result = context[fnSymbol](...arguments[1]);} else {//沒傳參數(shù)數(shù)組result = context[fnSymbol]();}delete context[fnSymbol];return result;
};//測試
function f(a,b){console.log(a,b)console.log(this.name)
}
let obj={name:'張三'
}
f.myApply(obj,[1,2])	//1 2,張三

測試結(jié)果:

實現(xiàn)bind

bind返回的是一個函數(shù),需要判斷函數(shù)作為構(gòu)造函數(shù)的情況,當作為構(gòu)造函數(shù)時,this 指向?qū)嵗?#xff0c;不會被任何方式改變 this,所以要忽略傳入的context上下文。

bind可以分開傳遞參數(shù),所以需要將參數(shù)拼接。

如果綁定的是構(gòu)造函數(shù),還需要繼承構(gòu)造函數(shù)原型上的屬性和方法,保證不丟失。

Function.prototype.myBind = function (context) {// 判斷調(diào)用對象是否為函數(shù)if (typeof this !== "function") {throw new Error("Type error");}// 獲取參數(shù)const args = [...arguments].slice(1);const fn = this; // 保存this的值,代表調(diào)用bind的函數(shù)//返回一個函數(shù),此函數(shù)可以被作為構(gòu)造函數(shù)調(diào)用,也可以作為普通函數(shù)調(diào)用const Fn = function () {// 根據(jù)調(diào)用方式,傳入不同綁定值// 當作為構(gòu)造函數(shù)時,this 指向?qū)嵗?#xff0c;不會被任何方式改變 this,要忽略傳入的context上下文return fn.apply(this instanceof Fn ? this : context,// bind可以分開傳遞參數(shù)(如f.bind(obj, 1)(2)),所以需要將參數(shù)拼接,這里使用apply,參數(shù)拼接成一個數(shù)組args.concat(...arguments)//當前的這個 arguments 是指 Fn 的參數(shù),也可以用剩余參數(shù)的方式);};//對于構(gòu)造函數(shù),要保證原函數(shù)的原型對象上的屬性不能丟失Fn.prototype = Object.create(fn.prototype);return Fn;
};// 1.先測試作為構(gòu)造函數(shù)調(diào)用
function Person(name, age) {console.log(name);console.log(age);console.log(this); //構(gòu)造函數(shù)this指向?qū)嵗龑ο?}
// 構(gòu)造函數(shù)原型的方法
Person.prototype.say = function () {console.log("say");
};
var obj = {name: "cc",age: 18,
};
var bindFun = Person.myBind(obj, "cxx");
var a = new bindFun(10);
// cxx
// 10
// Person {}
a.say(); // say// 2.再測試作為普通函數(shù)調(diào)用
function normalFun(name, age) {console.log(name);console.log(age);console.log(this); // 普通函數(shù)this指向綁定bind的第一個參數(shù) 也就是例子中的obj
}
var obj = {name: "aa",age: 18,
};
var bindNormalFun = normalFun.myBind(obj, "cc");
bindNormalFun(12);
// cc
// 12
// { name: 'aa', age: 18 }

測試結(jié)果:?

3.防抖和節(jié)流

防抖

防抖是指在事件被觸發(fā) n 秒后再執(zhí)行回調(diào),如果在這 n 秒內(nèi)事件又被觸發(fā),則重新計時??梢允褂迷谝恍c擊請求的事件上,避免因為用戶的多次點擊向后端發(fā)送多次請求。

//fn是需要防抖的函數(shù),delay是等待時間
function debounce(fn, delay = 500) {let timer = null;// 這里返回的函數(shù)是每次用戶實際調(diào)用的防抖函數(shù)return function(...args) {	//...args是es6的剩余參數(shù)語法,將多余的參數(shù)放入數(shù)組,用來代替arguments對象// 如果已經(jīng)設(shè)定過定時器了就清空上一次的定時器if(timer) {clearTimeout(timer);	}// 開始一個新的定時器,延遲執(zhí)行用戶傳入的方法;注:定時器的返回值是一個數(shù)值,作為定時器的編號,可以傳入clearTimeout來取消定時器timer = setTimeout(() => {  //這里必須是箭頭函數(shù),不然this指向window,要讓this就指向fn的調(diào)用者fn.apply(this, args);   }, delay)	}
}

節(jié)流

節(jié)流就是一定時間內(nèi)只執(zhí)行一次事件,即使重復(fù)觸發(fā),也只有一次生效??梢允褂迷诒O(jiān)聽滾動scroll事件上,通過事件節(jié)流來降低事件調(diào)用的頻率。

  • 定時器版本
function throttle(fn, delay = 500) {let timer = null;return function(...args) {// 當前有任務(wù)了,直接返回if(timer) {return;}timer = setTimeout(() => {fn.apply(this, args);//執(zhí)行完后,需重置定時器,不然timer一直有值,無法開啟下一個定時器timer = null;	}, delay)}
}
  • 時間戳版本
// 節(jié)流
function throttle(fn, delay = 500) {let prev = Date.now();// 上一次執(zhí)行該函數(shù)的時間return function(...args) {let now = Date.now();//返回從UTC到當前時間的毫秒數(shù)// 如果差值大于等于設(shè)置的等待時間就執(zhí)行函數(shù)if (now - prev >= delay) {fn.apply(this, args);prev = Date.now();}};
}

詳細可以去看我的這篇文章——前端性能優(yōu)化之防抖&節(jié)流

4.實現(xiàn)instanceof

instanceof用于檢測構(gòu)造函數(shù)的prototype屬性是否出現(xiàn)在某個實例對象的原型鏈上。

function myInstanceof(instance, constructor) {//如果不是對象,或者是null,直接返回falseif (typeof instance !== "object" || instance === null) {return false;}// 獲取對象的原型let proto = Object.getPrototypeOf(instance);// 獲取構(gòu)造函數(shù)的 prototype 對象let prototype = constructor.prototype;// 判斷構(gòu)造函數(shù)的 prototype對象是否在對象的原型鏈上while (true) {// 到達原型鏈終點null,說明沒找到if (!proto) {return false;}if (proto === prototype) {return true;}// 如果沒有找到,就繼續(xù)從其原型上找proto = Object.getPrototypeOf(proto);}
}//測試
let Fn = function () { }
let p1 = new Fn()
console.log(myInstanceof(p1, Fn));//true
console.log(myInstanceof([], Fn));//false
console.log(myInstanceof([], Array)) // true
console.log(myInstanceof(function(){}, Function)) // true

測試結(jié)果:?

5.實現(xiàn)Ajax

(1)創(chuàng)建一個 XMLHttpRequest 對象。

(2)在這個對象上使用 open 方法創(chuàng)建一個 HTTP 請求(參數(shù)為請求方法、請求地址、是否異步和用戶的認證信息)。

(3)通過send方法來向服務(wù)器發(fā)起請求(post請求可以入?yún)?shù)作為發(fā)送的數(shù)據(jù)體)。

(4)監(jiān)聽請求成功后的狀態(tài)變化:根據(jù)狀態(tài)碼進行相應(yīng)的處理。onreadystatechange設(shè)置監(jiān)聽函數(shù),當對象的readyState變?yōu)?的時候,代表服務(wù)器返回的數(shù)據(jù)接收完成,這個時候可以通過判斷請求的狀態(tài),如果狀態(tài)是200則代表成功,404或500代表失敗。

function ajax(url) {//1.創(chuàng)建XMLHttpRequest對象const xhr = new XMLHttpRequest();//2.使用open方法創(chuàng)建一個GET請求xhr.open('GET',url);//xhr.open('GET',url,true);//true代表異步,已完成事務(wù)的通知可供事件監(jiān)聽器使用;如果為false,send() 方法直到收到答復(fù)前不會返回//3.發(fā)送請求xhr.send(); //4.監(jiān)聽請求成功后的狀態(tài)變化(readyState改變時觸發(fā)):根據(jù)狀態(tài)碼(0~5)進行相應(yīng)的處理xhr.onreadystatechange = function () {//readyState為4代表服務(wù)器返回的數(shù)據(jù)接收完成if (xhr.readyState == 4) { //請求的狀態(tài)為200或304代表成功if(xhr.status == 200 || xhr.status == 304) {//this.response代表返回的數(shù)據(jù)handle(this.response);} else {//this.statusText代表返回的文本信息console.error(this.statusText);}}};
}

使用Promise封裝AJAX:

function ajax(url) {return new Promise((resolve, reject) => {let xhr = new XMLHttpRequest()xhr.open('get', url)xhr.send()  xhr.onreadystatechange = () => {if (xhr.readyState == 4) {if (xhr.status == 200 || xhr.status == 304) {resolve(this.response)} else {reject(new Error(this.statusText));}}}})
}
//使用
let url = '/data.json'
ajax(url).then(res => console.log(res)).catch(reason => console.log(reason))

6.深拷貝和淺拷貝

淺拷貝

淺拷貝是創(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會遍歷對象的整個原型鏈,如果只考慮對象本身的屬性,需要搭配hasOwnPropertyfor(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é)果:?

深拷貝

深拷貝是將一個對象從內(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);//將當前對象作為key,克隆對象作為valuefor(let key in obj ){	if(obj.hasOwnProperty(key)){newObj[key] = deepCopy(obj[key], map);	//遞歸}}return newObj
}// 測試
let obj1 = {name : '南木元元',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: '南木元元', arr: [ 1, [ 2, 3 ], 4 ] }
console.log('obj2',obj2) // obj2 { name: '阿元', arr: [ 1, [ 5, 6, 7 ], 4 ] }

測試結(jié)果:

7.函數(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ù)。維護一個數(shù)組,當數(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ī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é)果:

參數(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é)尾,于是再改進為隱式轉(zhuǎn)換.toString寫法,原理:當用 Function的值做計算的時候,會調(diào)用toString做隱式轉(zhuǎn)換。注意一些舊版本的瀏覽器隱式轉(zhuǎ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é)果:

8.數(shù)組扁平化

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

(1)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]

(2)遞歸

let arr = [1, [2, [3, 4]]];
function flatten(arr) {let result = [];for (let i = 0; i < arr.length; i++) {//如果當前元素還是一個數(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]

(3)reduce函數(shù)迭代

從上面普通的遞歸函數(shù)中可以看出,其實就是對數(shù)組的每一項進行處理,那么其實也可以用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]

(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 ]

9.數(shù)組去重

(1)利用Set。new一個Set,參數(shù)為需要去重的數(shù)組,Set 會自動刪除重復(fù)的元素,再Array.from將 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 ]

(2)利用數(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]

(3)利用map。新建一個數(shù)組和map,如果當前值在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]

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

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

function getType(value) {// 判斷數(shù)據(jù)是 null 的情況if (value === null) {return String(value);}// 判斷數(shù)據(jù)是基本數(shù)據(jù)類型的情況和函數(shù)的情況,使用typeofif (typeof value !== "object") {return typeof value;} else {// 判斷數(shù)據(jù)是引用類型的情況,設(shè)當前類型為datelet 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é)果:

結(jié)語

本文總結(jié)了前端常見的一些手寫功能,你是不是全都掌握了呢,歡迎在評論區(qū)交流。

🔥如果此文對你有幫助的話,歡迎💗關(guān)注、👍點贊、?收藏??評論支持一下博主~?????

http://www.risenshineclean.com/news/30287.html

相關(guān)文章:

  • 網(wǎng)站的二級頁面怎么做代碼全網(wǎng)關(guān)鍵詞搜索排行
  • 專門做電容的網(wǎng)站有哪些實用的網(wǎng)絡(luò)推廣方法
  • 網(wǎng)站后臺用什么語言合適國外網(wǎng)站搭建
  • 免費自己做網(wǎng)站手機圖片外鏈在線生成
  • 河南政法委原書記受審seo關(guān)鍵詞首頁排名
  • 做公司網(wǎng)站的服務(wù)費入什么費用seo搜論壇
  • 通州微平臺網(wǎng)站建設(shè)網(wǎng)站開發(fā)的步驟
  • 哈爾濱快速建站專業(yè)定制桔子seo網(wǎng)
  • 無極游戲網(wǎng)廈門seo排名收費
  • 朔州網(wǎng)站建設(shè)四川seo哪里有
  • 佛山網(wǎng)站建設(shè)的首選免費網(wǎng)站外鏈推廣
  • 崇信門戶網(wǎng)個人留言seo技術(shù)交流
  • ui培訓(xùn)班哪里有谷歌seo招聘
  • 服裝印花圖案網(wǎng)站seo與sem的區(qū)別
  • dw做網(wǎng)站一般設(shè)為什么樣南安網(wǎng)站建設(shè)
  • 網(wǎng)站維護和制作怎么做會計分錄免費搜索引擎入口
  • 深圳做小程序網(wǎng)站開發(fā)百度seo公司興田德潤
  • 淄博網(wǎng)站備案網(wǎng)絡(luò)服務(wù)提供者收集和使用個人信息應(yīng)當符合的條件有
  • 天津正規(guī)網(wǎng)站建設(shè)調(diào)試公司霸屏seo服務(wù)
  • 廊坊網(wǎng)站建設(shè)解決方案域名注冊查詢官網(wǎng)
  • 響應(yīng)設(shè)網(wǎng)站多少錢可以做百度推廣賬號注冊
  • 重慶網(wǎng)站快速排名優(yōu)化百度市場應(yīng)用官方app
  • 做網(wǎng)站的技術(shù)關(guān)鍵佛山網(wǎng)絡(luò)推廣培訓(xùn)
  • 品古典家具網(wǎng)站模板2023疫情最新消息今天
  • 百度關(guān)鍵詞優(yōu)化師有實力的網(wǎng)站排名優(yōu)化軟件
  • 做網(wǎng)站開發(fā)要學什么軟件杭州網(wǎng)站建設(shè)書生商友
  • 簡潔大氣公司網(wǎng)站西安百度關(guān)鍵詞排名服務(wù)
  • 西安網(wǎng)站制作公司排給公司做網(wǎng)站的公司
  • 免費建站abc怎樣做好網(wǎng)絡(luò)營銷推廣
  • 做網(wǎng)站花都區(qū)百度推廣客戶端