在JavaScript中模拟'new'运算符 [英] Simulate the 'new' operator in JavaScript
问题描述
我尝试在这样的代码中模拟JavaScript中的'new'运算符:
Function.method('new ',function(){
var objPrototype = Object.create(this.prototype);
var instance = this.apply(objPrototype,arguments);
return instance;
});
但是,为了涵盖所有情况,return语句应如下所示:
return(typeof instance ==='object'&& instance)|| objPrototype;
现在进行测试:
var SomeClass = function(param1,param2){
this.param1 = param1;
this.param2 = param2;
};
var test1 = String.new('test1'); //在这种情况下,instance变量是一个对象
var test2 = SomeClass.new('test1','test2'); //在这种情况下,instance变量是未定义的
这究竟是'新'运营商呢?还有什么案例可以解决吗?
来自规范:
11.2.2新算子# Ⓣ Ⓡ Ⓖ
生产 NewExpression :
new
NewExpression 评估如下:
- 让 ref 成为评估 NewExpression 的结果。
- 让构造函数
GetValue
(参考)。
- 如果
类型
(构造函数)不是对象,抛出 TypeError 异常。
- 如果构造函数没有实现[[Construct]]内部方法,抛出一个 TypeError exception。
- 返回在构造函数上调用[[Construct]]内部方法的结果,不提供任何参数(即空参数列表。。
生产 MemberExpression :
new
MemberExpression参数
评估如下:
- 让 ref 是评估 MemberExpression 的结果。
- 让构造函数成为
GetValue
( ref )。
- 让 argList 是评估参数的结果,生成参数值的内部列表( 11.2。 4 )。
- 如果
类型
(构造函数)不是Object,抛出 TypeError 异常。
- 如果构造函数未实现[[Construct]]内部方法,则抛出 TypeError exception。
- 返回调用[[]的结果构造]] 构造函数上的内部方法,提供列表 argList 作为参数值。
在任何一种情况下,都会正确遵循所有步骤:
var objPrototype = Object .create(this.prototype); // 1-4 1-5
var instance = this.apply(objPrototype,arguments); // 5 6
兴趣点是2.
[[construct]]
的规范说明:
当一个Function对象F的[[Construct]]内部方法是
时,调用可能为空的参数列表,以下步骤采取
:
- 让obj成为新创建的本机ECMAScript对象。
。 。 。
- 让结果成为调用F的[[Call]]内部属性的结果,提供obj作为此值并提供参数列表
作为args传入[[Construct]]。
- 如果
键入
(结果)是对象然后返回结果。
- 返回 obj 。
typeof obj
为 null
返回object
,而 null
不是对象。但是,由于 null
是一个假值,您的代码也可以按预期工作:
return(typeof instance ==='object'&& instance)|| objPrototype;
I tried to simulate the 'new' operator in JavaScript in a code like this:
Function.method('new', function ( ) {
var objPrototype = Object.create(this.prototype);
var instance = this.apply(objPrototype, arguments);
return instance;
});
However, in order to cover all the cases, the return statement should look like this:
return (typeof instance === 'object' && instance ) || objPrototype;
Now for the tests:
var SomeClass = function (param1, param2) {
this.param1 = param1;
this.param2 = param2;
};
var test1 = String.new('test1'); //in this case, the "instance" variable is an object
var test2 = SomeClass.new('test1', 'test2'); // in this case, the "instance" variable is undefined
Is this exactly what the 'new' operator does? Is there any case left to cover?
From the specification:
11.2.2 The new Operator # Ⓣ Ⓡ Ⓖ
The production NewExpression :
new
NewExpression is evaluated as follows:
- Let ref be the result of evaluating NewExpression.
- Let constructor be
GetValue
(ref).- If
Type
(constructor) is not Object, throw a TypeError exception.- If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
- Return the result of calling the [[Construct]] internal method on constructor, providing no arguments (that is, an empty list of arguments).
The production MemberExpression :
new
MemberExpression Arguments is evaluated as follows:
- Let ref be the result of evaluating MemberExpression.
- Let constructor be
GetValue
(ref).- Let argList be the result of evaluating Arguments, producing an internal list of argument values (11.2.4).
- If
Type
(constructor) is not Object, throw a TypeError exception.- If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
- Return the result of calling the [[Construct]] internal method on constructor, providing the list argList as the argument values.
In either case, all steps are correctly followed:
var objPrototype = Object.create(this.prototype); // 1-4 1-5
var instance = this.apply(objPrototype, arguments); // 5 6
The point of interest is 2.
The specification for [[construct]]
states:
When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:
- Let obj be a newly created native ECMAScript object.
. . .
- Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
- If
Type
(result) is Object then return result.- Return obj.
typeof obj
returns "object"
for null
, while null
is not an object. However, since null
is a falsy value, your code also works as intended:
return (typeof instance === 'object' && instance ) || objPrototype;
这篇关于在JavaScript中模拟'new'运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!