// 手写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
// 手写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
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
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>
语法: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>
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);
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);
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);
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);
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);
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);
方法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);
数组合并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);
语法: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));
语法:chunk(array,size)
功能:将数组拆分成多个size长度的区块,每个区块组成小数组,整体组成一个二维数组
如:[1,2,3,4,5,6]调用chunk(arr,4) ===> [[1,2,3,4],[5,6]]
这篇文章简单的分享一套我认为有助于提升开发者工作流的工具集。这套工具集中的大部分你可能见过,也可能没见过,如果有哪个/些让你眼前一亮,那么我的分享就很值了。这个列表包含许多种类的资源,所以这里我将它们分组整理。
今天给大家分享前端程序员最爱用的代码编辑器,来看看你用哪款?包括:Visual Studio Code、Atom、HBuilder、Sublime Text、Dreamweaver、Brackets、Notepad++
Js常用工具方法封装:type 类型判断、Date、Array、String 字符串操作、Number、Http、DOM、Other 其它操作
日常开发中,编写 Node.js 命令行工具来完成一些小任务是很常见的操作。其编写也不难,和日常编写 Node.js 代码并无二致。package.json 中的 bin 字段
做过校验需求的小伙伴们都知道,校验其实是个麻烦事。规则多,需要校验的字段多,都给我们前端带来巨大的工作量。一个不小心,代码里就出现了不少if else等不可维护的代码。因此,我觉得一个团队或者是一个项目
Licia 是一套在开发中实践积累起来的实用 JavaScript 工具库。该库目前拥有超过 300 个模块,同时支持浏览器、node 及小程序运行环境,提供了包括日期格式化、md5、颜色转换等实用模块,可以极大地提高开发效率。
WordGrinder它是一款使用起来很简单,但拥有足够的编写和发布功能的文字编辑器。Proselint:它是一款全能的实时检查工具。GNU Aspell:
工欲善其身必先利器,作为前端行业的你,如果知道一些好用的软件工具可以帮助他们更好的工作。下面,就给大家分享Web前端开发工程师常用的工具。
ES2017+,你不再需要纠结于复杂的构建工具技术选型。也不再需要gulp,grunt,yeoman,metalsmith,fis3。以上的这些构建工具,可以脑海中永远划掉。100行代码,你将透视构建工具的本质。
一旦被那些受利益驱使或有政府背景的黑客团伙盯上,在这场不太公平的攻防博弈中,你会明显感到力不从心。他们有充足的时间,有娴熟的技术和丰富的资源,而且只要在无数次的尝试中成功一次就可以大获全胜
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!