JavaScript手写系列之apply

/**
 * @author      haiyuan.wang
 * @date        2021.04.01
 * @vision      1.0
 * 
 * @description apply                                方法主要的作用是改变函数的执行环境
 * @example     fn.apply(thisArg, [argsArray])
 * @param       {Object}        thisArg              必选的。运行时的 this 值,非严格模式下,null 和 undefined 会自动指向 window
 * @param       {Array}         argsArray            可选的。执行过程中要传入的参数,是一个数组
*/

// 第一个例子, 求一个数组中的最大值
let goods = [1, 2, 3, 7, 6, 5, 4]
const max = Math.max.apply(null, goods)
console.log(‘max :>> ‘, max); // max :>>  7
const min = Math.min.apply(null, goods)
console.log(‘min :>> ‘, min); // min :>>  1

// 写一个自己的 myApply 方法
;(function(window) {
    if(!Function.prototype.myApply) {
        Function.prototype.myApply = function(context, argsArray) {
            let fn = this; // 谁调用 myApply 谁就是 this,在这里原函数就是this
            if(context === null || typeof context === ‘undefined‘) { // 判断是不是 null 或者 undefined
                context = window
            }
            let key = Symbol(‘key‘);    // symbol 是唯一值
            context[key] = fn;  // 将 fn 挂在context上面
            let result = ‘‘;
            if(!argsArray || argsArray?.length === 0) { // 不传第二个参数时,直接执行方法
                result = context[key]()
            } else {    //    传入第二个参数时,将参数展开,当作参数传入,执行函数
                result = context[key](...argsArray)
            }
            delete context[key] // 执行完,删除掉该属性
            return result
        }
    }
})(window)
let test = [1,5,9,12,15,19]
const maxTest = Math.max.myApply(null, test)
console.log(‘maxTest :>> ‘, maxTest); // maxTest :>>  19


// 写一个自己的 _apply 方法
;(function(window) {
    if(!Function.prototype._apply) {
        Function.prototype._apply = function(context, argsArray) {
            let fn = this; // 谁调用 _apply 谁就是 this,在这里原函数就是this
            if(context === null || typeof context === ‘undefined‘) { // 判断是不是 null 或者 undefined
                context = window
            }
            let key = Symbol(‘key‘);    // symbol 是唯一值
            context[key] = fn;  // 将 fn 挂在context上面
            let result = ‘‘;
            if(!argsArray || argsArray?.length === 0) { // 不传第二个参数时,直接执行方法
                result = context[key]()
            } else {    //    传入第二个参数时,将参数展开,当作参数传入,执行函数
                let params = ‘‘
                argsArray.forEach(element => {
                    params += element + ‘,‘
                });
                params = params.slice(0, params.length-1)
                console.log(‘params :>> ‘, params);  // params :>>  1,5,9,12,15,19
                result = context[key](eval(params))
            }
            delete context[key] // 执行完,删除掉该属性
            return result
        }
    }
})(window)
let test1 = [1,5,9,12,15,19]
const maxTest1 = Math.max._apply(null, test1)
console.log(‘maxTest1 :>> ‘, maxTest1); // maxTest1 :>>  19

 

JavaScript手写系列之apply

上一篇:使用Azure API Management, Functions, Power Apps和Logic App构建应用


下一篇:Android基础-Activity生命周期