手写代码题

重写JavaScript数组方法
重写数组方法
  • push(从数组后面添加一项或多项)
Array.prototype.push = function(){
    for(var i=0,l=arguments,length;i<l;i++>){
        this[this.length-1] = arguments(i);
    }
    return this.length;
}
  • pop(删除最后一项,并返回删除项)
Array.prototype.pop = function(){
    var item = this[this.length-1];
    if(this.length>0){
        this.length = this.length-1;
    }
    return item;
}
  • shift从前面删除一项,返回删除项
Array.prototype.shift = function(){
    var item = this[0]; 
    for(var i=1,l=this.length;i<l;i++>){
        this[i-1] = this[i];
    }
    this.length = this.length-1;
    return item;
}
  • unshift 从前面增加一项或多项
//数组先后移,再插入
Array.prototype.unshift = function(){
    for(var i =0;i<this.length;i++>){
        this[i+arguments.length] = this[i];
    }

    for(var i=0;i<arguments.length;i++){
        this[i] = arguments[i];
    }
    return 

}

  • fitler
Array.prototype.filter = function(handler){
    var newArr = [];
    this.forEach(function(item,index,this){
        if(handler(item,index,this)){
            newArr(newArr.length-1) = item;
        }
    })
    return newArr;
}
深拷贝
  • 简单深拷贝
let newObj = JSON.parse(JSON.stringfy(obj));
//存在问题:不能拷贝原型上属性和方法
  • 递归深拷贝
function deepClone(obj){
 var newObj = Array.isArray(obj)?[]:{};
 if(typeof obj!='object'){
     return obj;
 }
 for(var item in obj){
    if(obj.hasOwnPropty(item)){
        newObj[item] = typeof(obj[item])='object'?arguments.callee(item):obj[item];
    }
 }
 return newObj;

}

函数节流/函数防抖
  • 函数节流

防止重复提交,一段时间内多次触发的事件只执行一次(点击事件)

function throtte(handler,wait){
    let preTime = 0;
    return function(){
    let now = date.now();
        if(now-preTime>wait){
            handler.call(this);
            preTime = now;
        }
    }
}

oBtn.onclick = throtte(function(){
    console.log('1s内只执行一次')
},1000)

  • 函数防抖

延迟执行,连续触发的事件。只执行一次(电梯)

functon debunce(handler,wait){
    var timer = null;
    return function(){
        if(timer){
        clearTimeout(timer);
        }
        timer  =setTimeout(function(){
            handler.call(this);
        },wait)
    }

}
<think>嗯,用户问的是如何在手写代码题中自己实现一个箭头函数。首先,我得理解箭头函数的特点。箭头函数在ES6中引入,主要特点有词法作用域的this、简化的语法、不能作为构造函数,还有没有prototype属性等等。 用户可能是在面试或者笔试中遇到这样的题目,需要手动模拟箭头函数的行为,尤其是在处理this绑定的问题。这时候,我需要回忆普通函数和箭头函数的区别,尤其是this的绑定机制。普通函数的this是在调用时决定的,而箭头函数继承外层作用域的this。 接下来,我应该考虑如何用普通函数来模拟箭头函数的this绑定。这里可能用到闭包或者外层变量来保存this的值。例如,在外层函数中捕获当前的this,然后在内部函数中使用它,这样无论内部函数如何被调用,this都会指向外层的作用域。 然后,可能需要处理参数传递的问题。箭头函数可以接受参数,并且可以有简写的语法,比如省略return。所以在模拟的时候,可能需要使用function表达式,并且显式地返回结果,同时确保参数正确传递。 另外,还需要考虑其他特性,比如不能使用new关键字调用,所以模拟的函数应该在没有prototype属性的情况下,或者在调用时检查是否被用作构造函数,并抛出错误。 可能的实现步骤包括:创建一个外层函数来捕获当前的this,然后返回一个普通函数,该函数内部使用之前捕获的this值。例如,使用闭包保存this,并在返回的函数中使用apply或call来绑定这个this值。 同时,需要测试不同的场景,比如作为对象的方法被调用,或者作为回调函数,确保this指向正确。例如,当模拟的箭头函数作为对象的方法时,this应该指向定义时的上下文,而不是调用时的对象。 还要注意参数的处理,确保传入的参数能够正确传递给内部函数,并且支持rest参数或者默认值等特性,但可能在手写代码题中不需要处理太复杂的情况,保持基本功能即可。 最后,可能需要将实现封装成一个工具函数,类似于bind的作用,但更贴近箭头函数的行为。例如,使用外层函数的this,并通过闭包传递到内部函数,这样无论内部函数如何被调用,this都不会改变。 总结一下,实现的关键点在于正确绑定this,处理参数传递,以及模拟箭头函数无法作为构造函数等特性。可能还需要考虑异常处理,比如当尝试使用new调用时抛出错误,或者确保没有prototype属性。</think>好的,让我们分步骤理解如何手动实现箭头函数的核心特性: --- ### **一、箭头函数的核心特征** 1. **词法作用域 `this`**(继承外层上下文) 2. **没有自己的`arguments`对象** 3. **不能作为构造函数**(无法用 `new` 调用) 4. **没有 `prototype` 属性** --- ### **二、分步骤实现** #### **步骤1:模拟词法作用域的 `this`** 用闭包保存外层 `this`,用普通函数包裹: ```javascript function outer() { const _this = this; // 捕获外层 this // 模拟箭头函数的函数体 const inner = function(...args) { // 使用闭包中的 _this 代替自身的 this console.log("this 指向外层:", _this); return args.join(','); }; return inner; } ``` #### **步骤2:禁用构造函数特性** 通过判断 `new.target` 阻止构造: ```javascript function outer() { const _this = this; const inner = function(...args) { if (new.target) { // 禁止 new 调用 throw new TypeError("箭头函数不能作为构造函数"); } // ...原函数逻辑 }; return inner; } ``` #### **步骤3:删除 prototype 属性** ```javascript inner.prototype = undefined; // 移除原型 ``` --- ### **三、完整实现示例** ```javascript function fakeArrow(fn) { const outerThis = this; // 捕获当前 this function inner(...args) { if (new.target) { throw new TypeError("无法构造箭头函数实例"); } // 将 outerThis 作为 this 传递给原函数 return fn.apply(outerThis, args); } Object.defineProperty(inner, 'prototype', { value: undefined // 清除 prototype }); return inner; } // 使用示例 const obj = { name: "outer", createFn() { return fakeArrow.call(this, function(x) { console.log(this.name); // 正确指向 obj return x * 2; }); } }; const arrowLike = obj.createFn(); arrowLike(2); // 输出 "outer" 并返回 4 ``` --- ### **四、关键原理说明** 1. **`fakeArrow.call(this, ...)`** 通过显式绑定外层 `this` 到闭包 2. **`fn.apply(outerThis, args)`** 强制使用外层 `this` 替代函数自身 `this` 3. **清除 `prototype`** 使 `instanceof` 操作符失效 --- ### **五、与原生的差异** | 特性 | 原生箭头函数 | 手动实现 | |--------------|---------------------|---------------------| | `this` 绑定 | 引擎自动处理 | 需显式闭包捕获 | | 性能 | 引擎优化 | 闭包额外开销 | | `super` 引用 | 支持 | 无法模拟 | 实际开发中应直接使用语言原生特性,此实现仅用于理解原理。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值