likes
comments
collection
share

手撕js方法的实现

作者站长头像
站长
· 阅读数 40

学的越深入,越对js里面那些封装好的方法充满好奇。实际用的时候,这些原型上的方法也是真的香,帮我们把代码精简了几个档次。比如new,bind,map等。了解掌握这些原理也能帮助自己对js的理解。

1.new

先从简单的来。平时用的new,能帮我们把一个构造函数实例化。先贴代码

// new是个函数, 里面一定有一个对象参数,最后抛出也是一个对象
function myNew(arguments) {
    // 创建一个实例对象
    let obj = {}
    // 取到外部 传进来的构造器
    let Constructor = Array.prototype.shift.call(arguments)
    // 实现继承,要实例可以访问构造器的属性,相当于实例化的隐式原型指向构造函数的显示原型
    obj.__proto__ = Constructor.prototype
    // 调用构造器,改变其this指向到实例
    let ret = Constructor.apply(obj, arguments)
    return typeof ret === 'object' && ret !== null ? ret : obj
 }
// 精简点也方便理解的版本
function myNew(fun) {
    return function () {
        let obj = {
            __proto__: fun.prototype
        }
        fun.call(obj, ...arguments)
        return obj
    }
}

2.object.create

这个应该比new更简单些,只要知道平时这个方法的运用场景就能手写的出来,和上面一样来两种。

function create( object ) {
    if (typeof obj != 'object') { //null 进行typeof 也是 null
        throw TypeError
    }
    // 只要将创建出来的隐式原型指向 参数即可。
    let obj = object
    obj.__proto__ = object
    return obj
}
// 一样是精简点的,但没进行参数判断,不妨碍理解。
function create( object ) {
	return { __proto__: object}
}

3.call

常用的三种改变this作用域的方法,先来个call吧。

Function.prototype.myCall = function (context) {
    // this指向调用call的对象
    if (typeof this !== 'function') {
        // 调用call的不是函数
        throw new TypeError('Error')
    } 
    const fn = Symbol('fn')
    const args = [...arguments].slice[1] 
    context = context || window

    // 将调用call函数的对象添加到context属性中 
    context[fn] = this 
    // 执行该属性
    const result = context[fn](...args)
    // 删除该属性
    delete context[fn] 
    // 返回执行结果
    return result
}
// 精简没其他参数
Function.prototype.myCall = function (obj) {
	//给传入的作用域里添加调用call这个函数,这样函数指向的便是参数里的作用域,然后执行,执行完在删除
	obj.fn = this; // 此时this就是函数fn
    obj.fn(); // 执行fn
    delete obj.fn; //删除fn
};

4.未完待续...

js可以实现的方法有点多,远远没有结束,先码住三个,日后在写。

转载自:https://juejin.cn/post/6889413297720950792
评论
请登录