JavaScript-手写abc函数

简介: JavaScript-手写abc函数

手写abc函数

apply

使用方式:Fn.apply(obj, argArray)

作用:修改函数 this 指向

函数执行时 this 指向:谁调用指向谁,直接调用指向全局对象(window / global

应用场景:当我们想把另一个对象的值应用在当前函数中,但又不想让函数成为另一个对象的属性

如下代码:

function Fn() {
    console.log(this.name);
    console.log(arguments);
}
var name = "Lily";
Fn(1, 2, 3); // output Lily
let obj = {
    name: "Jack"
};
Fn.apply(obj, [1, 2, 3]); // output Jack

手写实现:

Function.prototype.myApply = function(obj, argArray) {
    if (!obj || typeof obj === 'number') {
        return;
    }
    if (typeof obj === "string") {
        obj = new String(obj);
    }
    if (argArray){
        if(!Array.isArray(argArray)){
            throw Error(`The second arg need array, but ${typeof argArray} given`);
        }
    }
    const fn = Symbol('fn');
    obj[fn] = this;
    const res = obj[fn](...argArray);
    delete obj[fn];
    return res;
}
// 测试代码
function Fn() {
    console.log(this.name);
    console.log(arguments);
}
var name = "Lily";
Fn(1, 2, 3); // output Lily
let obj = {
    name: "Jack"
};
Fn.apply(obj, [1, 2, 3]); // output Jack
Fn.myApply(obj, [1, 2, 3]); // output Jack

bind

applycall 不同,它返回的是一个函数,与 call 类似,可以传入多个参数,并且支持返回的函数传参

这就需要考虑:this指向、两个函数的 arguments ,内部实现则可以直接调用已经实现的 apply 函数

使用方式:Fn.bind(obj, args1, args2, .....)(args3, args4, ......)

如下代码:

function Fn(a, b, c, d) {
    console.log(this.name);
    console.log(a, b, c, d);
}
var name = "Jack";
let obj = {
    name: "Lily"
};
Fn(1, 2, 3, 4); // output Jack 1, 2, 3, 4

Fn.bind(obj, 1, 2)(3, 4); // output Lily 1, 2, 3, 4

手写实现

Function.prototype.myBind = function(obj) {
    if(!obj || typeof obj === "number") {
        return;
    }
    if(typeof obj === "string") {
        obj = new String(obj);
    }
    // es5 写法
    let _this = this, inArgs = Array.prototype.slice.call(arguments, 1), outArgs = null;
    return function() {
        // this != _this 这个函数的this是全局对象,没有对象调用它
        outArgs = Array.prototype.slice.call(arguments);
        _this.apply(obj, inArgs.concat(outArgs));
    }
    // // es6 箭头函数写法
    // let inArgs = Array.prototype.slice.call(arguments, 1);
    // return (...args) => {
    //     this.apply(obj, [...inArgs, ...args]);
    // }
}


function Fn(a, b, c, d) {
    console.log(this.name);
    console.log(a, b, c, d);
}

var name = "Jack";

let obj = {
    name: "Lily"
};

Fn(1, 2, 3, 4); // output Jack 1, 2, 3, 4

Fn.bind(obj, 1, 2)(3, 4); // output Lily 1, 2, 3, 4

Fn.myBind(obj, 1, 2)(3, 4);

call

apply 相似,apply第二个参数为参数数组,call为多个参数

使用方式:Fn.call(obj, arg1, arg2, arg3, ......);

如下代码

var name = "Jack";
function Fn() {
    console.log(this.name);
}
Fn(); // output Jack
var obj = {
    name: "Lily"
};
Fn.call(obj); // output Lily

手动实现

// obj:需要修改的指向,args:将多个参数合并成
Function.prototype.myCall = function(obj, ...args) {
    if (!obj || typeof obj === 'number') {
        return;
    }
    if (typeof obj === "string") {
        obj = new String(obj);
    }
    // 防止覆盖原obj中的fn属性
    const fn = Symbol('fn');
    // 为传入的对象增加一个fn的属性,指向this(this指调用myCall函数的函数)
    obj[fn] = this;
    // args:展开传入的多个参数
    let res = obj[fn](...args); // 获取函数执行结果
    // 传入的obj是引用,不应该修改对象的属性
    delete obj[fn];
    return res;
}

// 测试代码
let obj = {
    name: 'lily'
};
var name = 'jack';

function Fn() {
    console.log(this.name);
    if(arguments.length > 0){
        console.log('arguments', arguments);
    }
}

Fn();
Fn.call(obj, 1, 2, 3, 4)
Fn.myCall(obj, 1, 2, 3, 4);
目录
相关文章
|
2天前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
8 2
|
4天前
|
前端开发 JavaScript 数据处理
在JavaScript中,异步函数是指什么
【5月更文挑战第9天】JavaScript中的异步函数用于处理非立即完成的操作,如定时器、网络请求等。它们可通过回调函数、Promise或async/await来实现。示例展示了如何使用async/await模拟网络请求:定义异步函数fetchData返回Promise,在另一异步函数processData中使用await等待结果并处理。当fetchData的Promise解析时,data变量接收结果并继续执行后续代码。注意,调用异步函数不会阻塞执行,而是会在适当时间点继续。
10 0
|
4天前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
10 1
|
4天前
|
JavaScript 前端开发 网络架构
JavaScript中的箭头函数是一种新的函数表达形式
【5月更文挑战第9天】JavaScript的箭头函数以简洁语法简化函数定义,其特性包括:1) 不绑定自身this,继承上下文的this,适合回调和事件处理;2) 没有arguments对象,需用剩余参数语法访问参数;3) 不能用作构造函数,无new调用;4) 没有prototype属性,不支持基于原型的继承。箭头函数在特定场景下优化了this处理,但使用时要注意与普通函数的差异。
8 2
|
7天前
|
JavaScript 前端开发
js的一些内置函数
js的一些内置函数
7 1
|
7天前
|
JavaScript 前端开发 索引
js的includes函数
js的includes函数
12 1
|
7天前
|
JavaScript 安全 前端开发
js的map函数
js的map函数
7 0
|
7天前
|
JavaScript 前端开发
js的filter函数
js的filter函数
9 1
|
7天前
|
JavaScript 前端开发
js的函数
js的函数
7 0
|
7天前
|
JavaScript 前端开发
js的join函数
js的join函数
8 1