资讯专栏INFORMATION COLUMN

new运算符、bind、Object.create实现原理探讨

waruqi / 2160人阅读

摘要:如何手写运算符方法一运算符首先我们自己写运算符,无法写成这种方法,因为不识别呀,所以只能将第一个参数看做构造函数,剩余是其它传参,例如等同于中的然后就开始吧获取参数构造函数传入的参数继承的属性继承构造函数中的属性测试一下,并和原生的对比一下

如何手写new运算符、bind方法、Object.create
一、new 运算符

首先我们自己写new运算符,无法写成 NEW F()这种方法,因为js不识别呀,所以只能将第一个参数看做构造函数,剩余是其它传参,例如

let m = NEW(M,"lihaixing",30);
// 等同于js中的
let m = new M("lihaixing",30);

然后就开始吧!

function NEW(){
    // 获取参数
    let func = arguments[0]; // 构造函数
    let paras = [].slice.call(arguments,1); // 传入的参数
    // 继承func.prototype的属性
    let o = Object.create(func.prototype);
    // 继承构造函数中的属性
    func.call(o,..paras);
    return o;
}

测试一下,并和js原生的new对比一下

function M (name, age) {
    this.name = name;
    this.age = age;
}

M.prototype.sayYear = () => {
    console.log("2018");
}

let m = NEW(M, "haixing", 30); 
let mm = new M("haixing", 30);

在控制台中依次输入m, mm, m.sayYear, mm.sayYear调用,结果如下

一某一样有没有,那就进入下一个环节吧!

二、bind方法手写

bind方法其实和call非常一样,唯一的区别就是,call会将函数绑到对象中,并且调用;而bind只是将函数绑到对象中,并不调用,也就是:

f.call(obj)
// 等同于
f.bind(obj)();

那么该怎么写呢?我们知道bind方法是在绑在函数上的,而在js中,每个函数都是一个new Function(), 也就是和实例对象差不多了,所以我们要想使每个函数都能调用bind方法,就应该把它放在Function.prototype中,这样就是把bind方法写到了每个函数的原型中。那就开始写吧!

Function.prototype.BIND = function () {
    // this指向的就是我们的函数哦
    let self = this;
    // 获取参数,由于return中的函数也有arguments, 这里需重新赋值一下
    let paras = arguments;
    return function () {
        self.call(...paras); // 不要忘记解构
    }
}

然后就测试一下吧, 这里M还是上一节中的M构造函数

let c = {};
let cc = {};
M.BIND(c, "haixing", 31)();
M.bind(cc, "haixing", 31)();

结果如下

好像也没啥问题,但是c和cc是一个字面量对象, 那如果c和cc是构造函数生成的实例对象,那会如何呢?继续上代码:

function A (name, age) {
    this.name = name;
    this.age = age;
}

let d = new A("haixi", 22);
let dd = new A("haixi", 22);
M.BIND(d, "haixing", 31)();
M.bind(dd, "haixing", 31)();

还是没问题哈,constructor也是对的, 那我就放心,进入下一环节吧

三、Object.create怎么写?
// 这个要简单一些,就直接写了
Object.CREATE= function (obj, properties) {
    function F () {}
    F.prototype = obj;
    let o = new F();
    // 注意Object.create可以传入第二个参数,是一个对象,但格式必须是Object.defineProperties()方法一样
    if (typeof properties === "object") {
        Object.defineProperties(o, properties);
    }
    return o;
}

let e = Object.create(d, {year: {value: 2019}});
let ee = Object.CREATE(d, {year: {value: 2019}});

上图看执行结果

唉? 奇怪哈,为什么一个显示A一个显示F呢,但两个都是A的实例啊?哪位知道,欢迎留言啊

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108498.html

相关文章

  • JavaScript 进阶之深入理解数据双向绑定

    摘要:当我们的视图和数据任何一方发生变化的时候,我们希望能够通知对方也更新,这就是所谓的数据双向绑定。返回值返回传入函数的对象,即第一个参数该方法重点是描述,对象里目前存在的属性描述符有两种主要形式数据描述符和存取描述符。 前言 谈起当前前端最热门的 js 框架,必少不了 Vue、React、Angular,对于大多数人来说,我们更多的是在使用框架,对于框架解决痛点背后使用的基本原理往往关注...

    sarva 评论0 收藏0
  • 前端面试之Js篇

    摘要:作为构造函数使用,绑定到新创建的对象。内部实现类和类的继承构造函数构造函数调用父类构造函数参考请尽可能详尽的解释的工作原理的原理简单来说通过对象来向服务器发异步请求,从服务器获得数据,然后用来操作而更新页面。 1 . 请解释事件代理 (event delegation) 当需要对很多元素添加事件的时,可以通过将事件添加到它们的父节点通过委托来触发处理函数。其中利用到了浏览器的事件冒泡机...

    anyway 评论0 收藏0
  • 日积跬步,apply/call/bind 自我实现

    摘要:日常编码中被开发者用来实现对象冒充,也即显示绑定。面试题源码实现,事实上是对基础知识的一个综合考核。原型链终端指向,不会有构造函数,也不会有等属性,这些属性来自。 call/apply/bind 日常编码中被开发者用来实现 对象冒充,也即 显示绑定 this。 面试题:call/apply/bind源码实现,事实上是对 JavaScript 基础知识的一个综合考核。 相关知识点: 作...

    denson 评论0 收藏0
  • 一些搞死人的基础题 --- (不定时更新)

    摘要:检查当前上下文中的参数,建立该对象下的属性与属性值。检查当前上下文的函数声明,也就是使用关键字声明的函数。数据类型跟布尔值比较回顾下前面说的要点然后有几个应该要知道的隐形转换和不能转换成其他任何值。 前言 2018/04/27 新增六,讲解浅拷贝和深拷贝的区别并简单实现, 七,原生JS操作DOM?2018/04/30 新增八,解决计算精度问题,例如0.1+0.2?2018/05/0...

    Forest10 评论0 收藏0
  • 一些搞死人的基础题 --- (不定时更新)

    摘要:检查当前上下文中的参数,建立该对象下的属性与属性值。检查当前上下文的函数声明,也就是使用关键字声明的函数。数据类型跟布尔值比较回顾下前面说的要点然后有几个应该要知道的隐形转换和不能转换成其他任何值。 前言 2018/04/27 新增六,讲解浅拷贝和深拷贝的区别并简单实现, 七,原生JS操作DOM?2018/04/30 新增八,解决计算精度问题,例如0.1+0.2?2018/05/0...

    idisfkj 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<