javascript的中的new
考察 ECMAScript 语言规范中 new 运算符的定义:
The new Operator
The production NewExpression : new NewExpression is evaluated as follows:
- Evaluate NewExpression.
- Call GetValue(Result(1)).
- If Type(Result(2)) is not Object, throw a TypeError exception.
- If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
- Call the [[Construct]] method on Result(2), providing no arguments (that is, an empty list of arguments).
- Return Result(5).
注意到,这段定义中的 new 后的表达式不带参数,即是说,这段内容针对的是诸如 obj = new Object; 这样的用法——带参数的用法如 str = new String(“test”); 将在下面给出。两者有区别且区别不大。
回到上述定义,其大意是,new 后必须跟一个对象并且此对象必须有一个名为 [[Construct]] 的内部方法(其实这种对象就是构造器),否则会抛出异常,比如:
var Str = "test";
var aStr = new Str;
// FF 显示“Str is not a constructor”
// IE 显示“对象不支持此操作”
var Num = new Number(999);
var aNum = new Num;
// 结果同上
如果符合以上条件,那么引擎将调用其 [[Construct]] 内部方法,并不提供入口参数。接下来便要考察此内部方法。
另外,下面一段是 new 运算符的带参用法,由于和无参用法区别不大,读者朋友可直接略过。
The production MemberExpression : new MemberExpression Arguments is evaluated as follows:
- Evaluate MemberExpression.
- Call GetValue(Result(1)).
- Evaluate Arguments, producing an internal list of argument values (11.2.4).
- If Type(Result(2)) is not Object, throw a TypeError exception.
- If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
- Call the [[Construct]] method on Result(2), providing the list Result(3) as the argument values.
- Return Result(6).
考察 [[Construct]] 内部方法,先给出语言规范的描述:
When the [[Construct]] property for a Function object F is called, the following steps are taken:
- Create a new native ECMAScript object.
- Set the [[Class]] property of Result(1) to “Object”.
- Get the value of the prototype property of the F.
- If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
- If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
- Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
- If Type(Result(6)) is Object then return Result(6).
- Return Result(1).
引擎将先创建一个语言原生对象,即“{}”或“new Object”,在此我们称之为 O,然后设置其内部属性标识 [[Class]] 为“Object”。接下来,得到构造器 F 的 prototype(根据后文的意思,它可能不是一个对象)。如果 F.prototype 是对象,那么将 O 的内部 [[Prototype]] 属性指向 F.prototype。
请注意,诸如 [[Prototype]] 等为引擎内部标识符,对我们并不可见。[[Prototype]] 正是用于给内部维护原型链,虽然在我们看来,一个对象实例无法直接回溯到其原型(然而引擎内部可以),必须通过构造器中转,即 obj.constructor.prototype。
接着,如果 F.prototype 不是 object,那么将 O 的内部 [[Prototype]] 属性指向“the Object prototype object”(你可以参考这里)。等到 O 的 [[Prototype]] 有了自己的归属以后,引擎调用构造器 F 的 [[Call]] 内部方法,以 O 作为 this 对象,并将传入 [[Construct]] 的参数作为入口参数——如果有的话(即诸如“new Object()”最后括号内的参数)传递过去。最后,如果 [[Call]] 的返回值是对象,那么创建成功并返回此对象,否则回头重来。
根据这些内容,我们完全可以构造一个伪 [[Construct]] 方法来模拟此流程(其实已有众多前辈做过此工作):
function MyObject(age) {
this.age = age;
}
MyObject.construct = function() {
var o = {}, Constructor = MyObject;
o.__proto__ = Constructor.prototype;
// FF 支持用户引用内部属性 [[Prototype]]
Constructor.apply(o, arguments);
return o;
};
var obj1 = new MyObject(10);
var obj2 = MyObject.construct(10);
alert(obj2 instanceof MyObject);
// true
到此,new 运算的过程已经描述得足够清楚了
http://www.pushiming.com/blog/2009/10/the-new-operator/
javascript的中的new的更多相关文章
- JavaScript jQuery 中定义数组与操作及jquery数组操作
首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多 ...
- JavaScript文件中调用AngularJS内部方法或改变$scope变量
需要在其他JavaScript文件中调用AngularJS内部方法或改变$scope变量,同时还要保持双向数据绑定: 首先获取AngularJS application: 方法一:通过controll ...
- JavaScript ES7 中使用 async/await 解决回调函数嵌套问题
原文链接:http://aisk.me/using-async-await-to-avoid-callback-hell/ JavaScript 中最蛋疼的事情莫过于回调函数嵌套问题.以往在浏览器中, ...
- 警惕javascript代码中的“</script>”!
之前在写<博客园自定义博客侧边栏公告的过滤漏洞>的时候遇到了一个javascript代码报错“语法错误”的问题,一直不得以解决,感谢Arliang发现了并为我进行了耐心的解释,现整理如下: ...
- [记录] javascript 对象中使用setTimeout
参考:Javascript对象中关于setTimeout和setInterval的this介绍 使用最后一个方法终于弄好了,简直了,在对象中使用setTimeout原来是这样的 做的是分钟倒计时,倒数 ...
- 第一百节,JavaScript表达式中的运算符
JavaScript表达式中的运算符 学习要点: 1.什么是表达式 2.一元运算符 3.算术运算符 4.关系运算符 5.逻辑运算符 6.*位运算符 7.赋值运算符 8.其他运算符 9.运算符优先级 E ...
- Javascript Jquery 中的数组定义与操作_子木玲_新浪博客
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- JavaScript 语言中的 this
JavaScript 语言中的 this 由于其运行期绑定的特性,JavaScript 中的 this 含义要丰富得多,它可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式.JavaSc ...
- JavaScript面向对象中的继承
1.1继承的基本概念 使用一个子类,继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承. >>>继承的两方,发生在两个类之间. 实现继承的三种方式: 扩展O ...
- JavaScript ES6中export及export default的区别
相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...
随机推荐
- freemarker多个checkbox一个被选中示例
前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的不难!!!!! 前端真的 ...
- 如何使用Win8系统自带杀毒软件
首先我们要说明的是,Windows Defender并不是我们杀毒首选,这只是微软在用户没有安装仍和杀软时提供的备用防护机制.因此我们如果安装了第三方的杀毒软件,系统就会将Windows Defend ...
- 终于知道为什么我的mysql总是卸载的不干净以及老是找不到my.ini文件
感谢博主: http://blog.sina.com.cn/s/blog_6fc5bfa90100qmr9.html 如果你的电脑里装过MySQL,想再重新安装MySQL的时候可能就会因为前一版本卸载 ...
- 201621123006 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词. 继承.接口.抽象类.多态.interfac.comparable 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一 ...
- SQL竖列变横列
DROP TABLE IF EXISTS curriculumTable; CREATE TABLE curriculumTable ( id INT PRIMARY KEY AUTO_INCREME ...
- linux网络监控_网速测试
Linux下查看网络即时网速 1.sar命令(一般般) sar -n DEV 1 100 1代表一秒统计并显示一次 100代表统计一百次 sar在sysstat包 2.使用ntop图形工具(没详细用过 ...
- Julia 语言的一些尝试
前些天发现了Julia 这门编程语言后便决定对其进行一些尝试,便写了下面的小程序,也算是看看这门语言所谓的速度快到底是怎么快法. 整数累加: x= function fff() : global x ...
- BZOJ3298: [USACO 2011Open]cow checkers(佐威夫博弈)
3298: [USACO 2011Open]cow checkers Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 195 Solved: 96[S ...
- spring-security-4 (1)介绍
一.什么是spring security? spring security是基于spring开发的为JavaEE企业级应用提供安全服务的框架.安全服务主要是指 认证(Authentication)和 ...
- .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
我们有很多种方法评估一个方法的执行耗时,比如使用性能分析工具,使用基准性能测试.不过传统的在代码中编写计时的方式依然有效,因为它可以生产环境或用户端得到真实环境下的执行耗时. 如果你希望在 .NET/ ...