• 手写代码


    1.new的实现

    a.能够访问构造函数的属性

    b.能访问函数函数的原型的属性

    function Person(name) {
        this.name = name
    }
    Person.prototype.eat = function () {
        console.log('Eatting')
    }
    function create() {
        // 1. 获取构造函数,并且删除 arguments 中的第一项
        var con=[].shift.call(arguments);
        // 2. 创建一个空的对象并链接到构造函数的原型,使它能访问原型中的属性
        var obj=Object.create(con.prototype)
        // 3. 使用apply改变构造函数中this的指向实现继承,使obj能访问到构造函数中的属性
        var ret=con.apply(obj,arguments)
        // 4. 优先返回构造函数返回的对象,判断构造函数有没有返回值,是不是函数
        return typeof ret === 'object'?ret:obj;    
    }
    var lindaidai = create(Person, 'LinDaiDai')
    console.log(lindaidai) // Person{ name: 'LinDaiDai' }
    lindaidai.eat() // 'Eatting'

    2.call的实现

    Function.prototype.call2 = function (context) {
        var context = context||window;
        context.fn=this;
        var args=[];
        for(var i=1;i<arguments.length;i++){
            args.push(`arguments[${i}]`);
        }
        var result = eval(`context.fn(${args})`)
        delete context.fn;
        return result
    }
    
    var foo = {
        value: 1
    };
    
    function bar(name, age) {
        console.log(name)
        console.log(age)
        console.log(this.value);
    }
    
    bar.call2(foo, 'kevin', 18);
    // kevin
    // 18
    // 1

    3.apply的实现

    Function.prototype.apply2 = function (context,arr) {
        var context = context||window;
        context.fn=this;
        var args=[];
        var result;
        if(arr){
            for (var i = 0; i < arr.length; i++) {
                args.push(`arr[${i}]`);
            }
            result = eval(`context.fn(${args})`)
        }else{
            result = context.fn();
        }
        delete context.fn;
        return result
        
    }
    
    // 测试一下
    var foo = {
        value: 1
    };
    
    function bar(name, age) {
        console.log(name)
        console.log(age)
        console.log(this.value);
    }
    
    bar.apply2(foo, ["kevin","18"]);
    // kevin
    // 18
    // 1

    4.bind的实现

    简单的实现:

    // 第一版
    Function.prototype.bind2 = function (context) {
        var self=this;
        var args=[].slice.call(arguments,1);
        return function(){
            var bindArgs = [].slice.call(arguments);
            return self.apply(context,args.concat(bindArgs));
        }
    }
    
    var value = 2;
    
    var foo = {
        value: 1
    };
    
    function bar(name, age) {
        this.habit = 'shopping';
        console.log(this.value);
        console.log(name);
        console.log(age);
    }
    
    var bindFoo = bar.bind2(foo, 'daisy');
    bindFoo('10');
    // 1
    // daisy
    // 10

    复杂的,包含new,this指向失效

    var value = 2;
    
    var foo = {
        value: 1
    };
    
    function bar(name, age) {
        this.habit = 'shopping';
        console.log(this.value);
        console.log(name);
        console.log(age);
    }
    
    bar.prototype.friend = 'kevin';
    
    var bindFoo = bar.bind2(foo, 'daisy');
    
    var obj = new bindFoo('18');
    // undefined
    // daisy
    // 18
    console.log(obj.habit);
    console.log(obj.friend);
    // shopping
    // kevin
    
    Function.prototype.bind2 = function (context) {
    
        var self = this;
        var args = Array.prototype.slice.call(arguments, 1);
    
        var fNOP = function () {};
    
        var fBound = function () {
            var bindArgs = Array.prototype.slice.call(arguments);
            return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
        }
    
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();
        return fBound;
    }

    5.防抖

    /**
     * @description 防抖
     * @param {object} fn 执行函数
     * @param {number} wait 延迟时间
     * @return {void} 返回无
     * 使用列子(不要事件里面的function):
     * $(".supplierUser").click(
     *  debounce(move, 2000)
     * )
     */
    function debounce(fn, wait = 200) {
        var timeout = null;
        return function () {
            if (timeout !== null) clearTimeout(timeout);
            timeout = setTimeout(fn, wait);
        }
    }

    6.节流

    /**
     * @description 节流
     * @param {object} fn 执行函数
     * @param {number} wait 延迟时间
     * @return {void} 返回无
     * 使用列子(不要事件里面的function):
     * $(".supplierUser").click(
     *  throttle(move, 2000)
     * )
     */
    function throttle(fn, wait) {
        var _this, args;
        var last = 0;
        return function () {
            var now = +new Date();
            _this = this;
            args = arguments;
            if (now - last > wait) {
                fn.apply(_this, args);
                last = now;
            }
        };
    }

    7.数组扁平化,去重,排序

    var a1 = [4,1,1,2, [2], [[3]]];
    var newA = Array.from(new Set(a1.flat(Infinity))).sort(function(a,b){return a-b;});//[1,2,3,4]
  • 相关阅读:
    HTML中使用Vue+Dhtmlxgantt制作任务进度图
    Vue中使用js-xlsx导出Data数据到Excel
    Vue生命周期
    ajax调用免费的天气API
    maven无法自动下载依赖包settings.xml文件配置
    idea打开项目没有src目录
    java jdk idea maven安装及配置
    CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://conda.anaconda.org/pytorch
    The procedure entry point OPENSSL_sk_new_reserve could not be located in the dynamic link library
    Nuget打包没有注释显示
  • 原文地址:https://www.cnblogs.com/ssszjh/p/14308920.html
Copyright © 2020-2023  润新知