资讯专栏INFORMATION COLUMN

(详解)你应该知道的new操作符

y1chuan / 2113人阅读

摘要:使用指定的参数调用构造函数,并将绑定到新创建的对象。等同于,也就是没有指定参数列表,不带任何参数调用的情况。由构造函数返回的对象就是表达式的结果。

new

作为大家天天使用的操作符,想必大家都不陌生

创建一个对象的通用语法

let obj = new Object();

那么在创建对象的过程中,new 到底做了什么?

MDN

当代码 new Foo(...) 执行时,会发生以下事情:(MDN地址)

一个继承自 Foo.prototype 的新对象被创建。

使用指定的参数调用构造函数 Foo ,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。

由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

按照这个过程,我们可以大概的模拟一个new的实现

function _new(Super) {
    //返回一个function
    return (props)=> {
        let obj = {}; //创建一个新对象
        obj.__proto__ = Super.prototype;//继承父类的属性
        let result = Super.apply(obj,props);//调用Super的构造函数
        return typeof result === "object"? result : obj;; //判断Super构造器总返回一个Object
    }
}

var a = _new(Super)(["z"])
a;//{name: "z"}
ECMA-262

再次阅读Ecma262
其过程较MDN多了一些判断,如:

new Object ( [ value ] )
当以一个参数 value 或者无参数调用 Object 构造器,采用如下步骤:

如果提供了 value, 则
a.如果 Type(value) 是 Object, 则

  (1)如果 value 是个原生 ECMAScript 对象 , 不创建新对象,简单的返回 
  value.
  (2)如果 value 是宿主对象 , 则采取动作和返回依赖实现的结果的方式可以使 
  依赖于宿主对象的 .

b.如果 Type(value) 是 String, 返回 ToObject(value).
c.如果 Type(value) 是 Boolean, 返回 ToObject(value).
d.如果 Type(value) 是 Number, 返回 ToObject(value).

断言 : 未提供参数 value 或其类型是 Null 或 Undefined.

令 obj为一个新创建的原生 ECMAScript 对象 .

设定 obj 的 [[Prototype]] 内部属性为标准内置的 Object 的 prototype 对象.

设定 obj 的 [[Class]] 内部属性为 "Object".

设定 obj 的 [[Extensible]] 内部属性为 true.

设定 obj 的 8.12 指定的所有内部方法

返回 obj.

重新来修改下我们的模拟

function _new(Super) {
    //返回一个function
    return (value) => {
        if (value) {
            switch (typeof value) {
                case "object":
                    //这里因为不同的宿主环境也就是不同的引擎会有不同的写法,找了很多博文书籍也没有详解具体的判断逻辑或方法,只好先写伪代码了
                    if (宿主对象) {
                        //采取动作和返回依赖实现的结果的方式可以使依赖于宿主对象的
                    } else {
                        return value
                    }
                    break;
                case "string":
                    return new String(value);
                    break;
                case "boolean":
                    return new Boolean(value);
                    break;
                case "number":
                    return new Number(value);
                    break;
                default:
                    break;
            }
        }
        let obj = {}; //创建一个新对象
        obj.__proto__ = Super.prototype; //继承父类的属性
        //修改内部属性class 为 “Object”,不过ecma262没有提供任何方法去修改,只提供了一种访问方法 Object.prototype.toString.call("我们的对象")
        //修改内部属性Extensible为 true,不过目前没有提供方法去修改,只有一个修改为false Object.preventExtensions("我们的对象");
        let result = Super.apply(obj, value); //调用Super的构造函数
        return typeof result === "object" ? result : obj;; //判断Super构造器总返回一个Object
    }
}

var a = _new(Super)(["z"])
a; //{name: "z"}

欢迎补充

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

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

相关文章

  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • 数据结构于算法—线性表详解

    摘要:前言通过前面数据结构与算法前导我么知道了数据结构的一些概念和重要性,那么我们今天总结下线性表相关的内容。基本结构对于线性表,我们只需要一个数组和就能表示基本信息。 前言 通过前面数据结构与算法前导我么知道了数据结构的一些概念和重要性,那么我们今天总结下线性表相关的内容。当然,我用自己的理解解分享给大家。 其实说实话,可能很多人依然分不清线性表,顺序表,和链表之间的区别和联系! 线性...

    Freelander 评论0 收藏0
  • JavaScript类型检测详解

    摘要:种原始类型对象属性种原始类型中种原始类型为,,,,发现除外的其他种基本类型均可以用来识别因为会得到,所以直接用来检测对象的对象包括内置对象,,等和自定义对象。其他检测方法,都各有缺陷,不能精确。属性检测属性是否在实例对象中应该用。 本篇介绍一下如何检测JavaScript各种类型。 • 5种原始类型• 对象• Function• Array• 属性 5种原...

    张金宝 评论0 收藏0
  • 2017文章总结

    摘要:欢迎来我的个人站点性能优化其他优化浏览器关键渲染路径开启性能优化之旅高性能滚动及页面渲染优化理论写法对压缩率的影响唯快不破应用的个优化步骤进阶鹅厂大神用直出实现网页瞬开缓存网页性能管理详解写给后端程序员的缓存原理介绍年底补课缓存机制优化动 欢迎来我的个人站点 性能优化 其他 优化浏览器关键渲染路径 - 开启性能优化之旅 高性能滚动 scroll 及页面渲染优化 理论 | HTML写法...

    dailybird 评论0 收藏0

发表评论

0条评论

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