只能靠工匠手工打磨,央視解密神舟十二號的火箭“心臟輸血管”
1、call函式封裝實現
// 手寫call函式
function call(Fn,obj,...arg){
// 如果obj為null或者undefined,則指向window
if(obj === undefined || obj === null){
// globalThis是ES11的新特性,指向全域性
obj = globalThis
}
//為obj新增臨時方法
obj.temp = Fn
// 呼叫 temp 方法
let result = obj.temp(...arg)
// 刪除obj 的 temp
delete obj.temp
return result
}
function add(a,b){
console.log(this);
return a + b + this.c
}
let obj = {
c:521
}
globalThis.c = 1314
console.log(call(add,obj,10,20)); //551
console.log(call(add,null,10,20)); //1344
// 手寫call函式
Function.prototype.call = function(obj,...arg){
// 如果obj為null或者undefined,則指向window
if(obj === undefined || obj === null){
// globalThis是ES11的新特性,指向全域性
obj = globalThis
}
//為obj新增臨時方法
obj.temp = this
// 呼叫 temp 方法
let result = obj.temp(...arg)
// 刪除obj 的 temp
delete obj.temp
return result
}
function add(a,b){
console.log(this);
return a + b + this.c
}
let obj = {
c:521
}
globalThis.c = 1314
console.log(add.call(obj,10,20)); //551
console.log(add.call(null,10,20)); //1344
2、apply函式封裝實現
// 手寫apply函式
Function.prototype.apply = function(obj,arg){
if(obj === null || obj === undefined){
obj = globalThis
}
obj.temp = this
let result = obj.temp(...arg)
delete obj.temp
return result
}
function add(a,b){
console.log(a+b+this.c);
}
let obj = {
c:1314
}
globalThis.c = 520
add.apply(obj,[10,20]) //1344
add.apply(null,[10,20]) //550
3、bind函式封裝實現(bind不會立刻執行)
function bind(Fn,obj,...args){
if(obj === null || obj === undefined){
obj = globalThis
}
//bind返回一個函式,呼叫的時候執行方法
return function(...args2){
// 呼叫call方法
obj.temp = Fn
let result = obj.temp(...args,...args2)
delete obj.temp
return result
}
}
function add(a,b){
console.log(arguments);
console.log(a+b+this.c);
}
let obj = {
c:1314
}
globalThis.c = 520
bind(add,obj,10,20)() //1344
bind(add,null,10,20)(30,40) //550
4、函式節流
throttle節流
語法:throttle(callback,wait)
功能:建立一個節流函式,在wait毫秒內最多執行callback一次
理解:在函式需要頻繁觸發時:函式執行一次後,只有大於設定的執行週期後才會執行第二次,適合多次事件按時間做平均分配觸發
場景:視窗調整(resize)、頁面滾動(scroll)、DOM元素的拖拽功能實現(mousemove)、搶購瘋狂點選(click)
<script>
window.addEventListener(‘scroll‘,throttle(function(){
console.log(Date.now());
},500))
function throttle(callback,wait){
// 定義開始時間
let start = 0
// 返回結果是一個函式
return function(e){
let now = Date.now()
if(now - start > wait){
callback.call(this,e)
start = now
}
}
}
</script>
5、函式防抖
語法:debounce(callback,wait)
功能:建立一個防抖動函式,該函式會從上一次被呼叫後,延遲wait毫秒後呼叫callback
理解:觸發了一次函式會在延遲wait毫秒後呼叫callback,但再次點選,會清空掉再次計算
場景:input框輸入時
<body>
<input type="text">
<script>
let input = document.querySelector(‘input‘)
// input.onkeydown = function(e){
// console.log(e.keyCode);
// }
input.onkeydown = debounce(function(e){
console.log(e.keyCode);
},1000)
function debounce(callback,time){
//定時器變數
let timeId = null
// 返回值一定是個函式,否則無法觸發回撥
return function(e){
//timeId !== null 證明已經有一個timeif在跑,先清除掉再繼續跑
if(timeId !== null){
clearTimeout(timeId)
}
//啟動定時器
timeId = setTimeout(()=>{
callback.call(this,e)
// 重置定時器變數
timeId = null
},time)
}
}
</script>
</body>
6、陣列函式map封裝實現
map()方法建立一個新陣列,其結果是該陣列中的每個元素是呼叫一次提供的函式後的返回值
const arr = [1,2,3,4,5]
Array.prototype.map = function (callback) {
let result = []
for(let i = 0;i<this.length;i++){
result.push(callback(this[i],i))
}
return result
}
let arr2 = arr.map((item,index) => {
return item *10
})
console.log(arr2);
7、陣列函式reduce封裝實現
reduce():從左到右為每個陣列元素執行一次回撥函式,並把上次回撥函式的返回值放在一個暫存器中傳給下次回撥函式,並返回最後一次回撥函式的返回值
const arr = [1,2,3,4,5]
// 示例
let result = arr.reduce((res,value)=>{
return res + value
},0) //0為res初始值,value為arr的值
console.log(result); //15
Array.prototype.reduce = function(callback,value){
let result = value
for(let i = 0;i<this.length;i++){
result = callback(result,this[i])
}
return result
}
// 演示
let arr2 = arr.reduce((res,value)=>{
return res + value
},5)
console.log(arr2);
8、陣列函式filter封裝實現
filter():將所有在過濾函式中返回true的陣列元素放進一個新陣列中並且返回
const arr = [1,2,3,4,5]
Array.prototype.filter2 = function(callback){
let arr = []
for(let i = 0;i<this.length;i++){
if(callback(this[i],i)){
arr.push(this[i])
}
}
return arr
}
let res = arr.filter2((item=>{
return item > 2
}))
console.log(res);
8、陣列函式find封裝實現
find():找到第一個滿足測試函式的元素並返回那個元素的值,如果找不到,則返回undefined
const arr = [1,2,3,2005,4,1001]
// find()
Array.prototype.find = function(callback){
for(let i = 0;i<this.length;i++){
if(callback(this[i],i)){
return this[i]
}
}
return undefined
}
let res = arr.find((item=>{
return item > 3000
}))
console.log(res);
9、陣列函式findIndex封裝實現
findIndex():找到第一個滿足測試函式的元素並返回那個元素的索引,如果找不到,則返回-1
// findIndex()
Array.prototype.findIndex2 = function(callback){
for(let i = 0;i<this.length;i++){
if(callback(this[i],i)){
return i
}
}
return -1
}
let res = arr.findIndex2((item=>{
return item > 1000
}))
console.log(res);
10、陣列函式every封裝實現
every():如果陣列中的每個元素都滿足測試函式,則返回true,否則返回false
const arr = [1,2,3,4,5]
Array.prototype.every2 = function(callback){
for(let i = 0;i<this.length;i++){
let result = callback(this[i],i)
if(!result){
return false;
}
}
return true
}
const result = arr.every2(item=>{
return item > 0
})
console.log(result);
11、陣列函式some封裝實現
some():如果陣列中至少有一個元素滿足測試函式,則返回true,否則返回false
Array.prototype.some2 = function(callback){
for(let i = 0;i<this.length;i++){
let result = callback(this[i],i)
if(result){
return true
}
}
return false;
}
const result = arr.some2(item=>{
return item > 6
})
console.log(result);
12、陣列去重
方法1:利用foreach()和indexOf()
方法2:利用froecah() + 物件容器
方法3:利用ES6語法:from + Set 或者 ... + Set
const arr = [1,2,3,4,5,2,4]
// 方法1 :forEach + indexOf
function unique(arr){
if(!Array.isArray(arr)){
return
}
let result = []
arr.forEach(item=>{
if(result.indexOf(item) === -1){
result.push(item)
}
})
return result
}
let result = unique(arr)
console.log(result);
// 方法2 forEach() + 物件容器
function unique2(arr){
let result = []
//宣告空物件
const obj = {}
arr.forEach(item => {
if(obj[item] === undefined){
obj[item] = true
result.push(item)
}
})
console.log(obj);
return result
}
let result2 = unique2(arr)
console.log(result2);
//方法3:利用ES6語法:from + Set 或者 ... + Set
function unique3(arr){
return [...new Set(arr)]
// let result = Array.from(new Set(arr))
// return result
}
let result3 = unique3(arr)
console.log(result2);
13、數組合並和切片
數組合並concat()
let arr = [1,2,3]
Array.prototype.concat2 = function(...args){
let result = [...this,...args]
return result
}
const result = arr.concat2([4,5,6],7,8)
console.log(result);
陣列切片slice()
Array.prototype.slice2 = function(begin,end){
if(this.length === 0){
return [];
}
//判斷begin
begin = begin || 0
if(begin >= this.length){
return [];
}
//判斷end
end = end || this.length
if(end <begin){
end = this.length
}
let result = []
this.forEach((item,index)=>{
if(index >= begin && index < end){
result.push(item)
}
})
return result
}
let sliceResult = arr.slice2(1,6)
console.log(sliceResult);
http://www.ssnd.com.cn 化妝品OEM代加工
14、陣列扁平化
語法:flatten(array)
取出巢狀陣列(多維)中的所有元素放到一個新陣列(一維)中
例如:[ 1,[ 3,[ 2,4 ]]] -> [1,2,3,4]
方法1: 遞迴 + reduce() + concat()
方法2: ,,, + some() + concat()
let arr = [1,2,[3,4,[5,6]],7]
// 方法1
function falttenl(arr){
let result = []
arr.forEach(item => {
if(Array.isArray(item)){
result = result.concat(falttenl(item))
}else{
result = result.concat(item)
}
});
return result
}
console.log(falttenl(arr));
// 方法2
function flatten2(arr){
let result = [...arr]
while(result.some(item => Array.isArray(item))){
result = [].concat(...result)
}
return result
}
console.log(flatten2(arr));
15、陣列分塊
語法:chunk(array,size)
功能:將陣列拆分成多個size長度的區塊,每個區塊組成小陣列,整體組成一個二維陣列
如:[1,2,3,4,5,6]呼叫chunk(arr,4) ===> [[1,2,3,4],[5,6]]