未加星标

new做了些什么

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

new 操作符,熟悉又陌生,昨晚翻看了一下《javascript语言精粹》,47页有一段代码说的是 new 执行的过程,代码如下:

Function.method('new',function(){ var that = Object.beget(this.prototype) var other = this.apply(that, arguments) return (typeof other === 'object' && other ) || that })

其中的 method 是 Function 原型上的一个方法,方便给 Function 原型上加方法, Object.beget 方法可以理解为返回一个使用 this.prototype 作为其原型的新对象, 这个方法对应的其实是 Object.create 。

两者的代码如下

if(typeof Object.beget !== 'function') { Object.beget = function(o){ var F = function(){} F.prototype = o return new F() } } Function.prototype.method = function(name, func) { if(!this.prototype[name]) { this.prototype[name] = func } }

老道的那段解释 new 的代码,可以直译为:

创建一个以当前 Function 原型为原型的新对象 that 以 that 作为上下文,当前 Function 接收的参数为参数,执行当前 Function ,得结果记为 other 如果 other 为一个对象返回它,否则返回 that

那么规范里的 new 是按规定是怎么执行的呢?请看 这里 ,摘抄如下:

12.3.3.1 Runtime Semantics: Evaluation

NewExpression : new NewExpression Return ? EvaluateNew(NewExpression, empty). MemberExpression : new MemberExpression Arguments Return ? EvaluateNew(MemberExpression, Arguments).

12.3.3.1.1 Runtime Semantics: EvaluateNew(constructProduction, arguments)

The abstract operation EvaluateNew with arguments constructProduction, and arguments performs the following steps:

Assert: constructProduction is either a NewExpression or a MemberExpression. Assert: arguments is either empty or an Arguments production. Let ref be the result of evaluating constructProduction. Let constructor be ? GetValue(ref). If arguments is empty, let argList be a new empty List. Else, Let argList be ArgumentListEvaluation of arguments. ReturnIfAbrupt(argList). If IsConstructor(constructor) is false, throw a TypeError exception. Return ? Construct(constructor, argList).

简单解释下, new 有两种,一种是带参数的,一种不带参数的,其中 NewExpression 和 MemberExpression 我们先跳过,这是两种表达式,它们包含的种类非常多,我们直接看 EvaluateNew 里的过程

首先断定 表达式要么是 NewExpression 要么是 MemberExpression 断定 arguments 要么是 空, 要么是 Arguments production 设 ref 为表达式执行的结果 设 constructor 为 GetValue(ref) 的值 如果 arguments 是空,设 argList 为一个空的 List 不为空 设 argList 为 arguments 的 ArgumentListEvaluation 调用 ReturnIfAbrupt(argList) 调用 IsConstructor(constructor) ,如果是 false, 抛出一个 TypeError 异常 调用并返回 Construct(constructor, argList) 重点就在最后两步,其中 IsConstructor 首先判断 constructor 是不是一个对象,然后判断它有没有 [[Construct]] 内置方法, 这个内置方法是在函数初始化的时候绑定的,有些内置函数是没有这个属性的,比如 String.prototype.toString 如果对一个没有这个属性 的对象调用 new 就会抛出一个 TypeError 的错误。 最后的 Construct 实际 比较复杂,在又一次校验过 constructor 后,会调用 [[construct]] ,这里调用的又分为两种,一种是 普通的函数对象 ,另外一种是 内置的函数对象

重点看一下第一种的情况,实质就是如果是普通的函数,设置执行上下文, 执行函数体 , 如果有返回值,且返回值是对象,直接返回对象,如果返回 undefined, 抛出 TypeError ,最后是返回正常绑定的 this

最后这一点涉及的分支还是有几个,我就不继续对着文档解读了,困。。。

相对于 ES5 真的复杂了太多!

参考:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new 文章地址:new做了些什么

欢迎关注我的微博与我交流:@草依山

Github上也有一些东西: [Github]

所有文章坚决抵制 jb51.net 的转载!

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: GitJavaJavaScript其实微博
分页:12
转载请注明
本文标题:new做了些什么
本站链接:http://www.codesec.net/view/533139.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(41)