在JavaScript中模拟'new'运算符 [英] Simulate the 'new' operator in JavaScript

查看:102
本文介绍了在JavaScript中模拟'new'运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在这样的代码中模拟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 评估如下:


  1. ref 成为评估 NewExpression 的结果。

  2. 构造函数 GetValue 参考)。

  3. 如果 类型 构造函数)不是对象,抛出 TypeError 异常。

  4. 如果构造函数没有实现[[Construct]]内部方法,抛出一个 TypeError exception。

  5. 返回在构造函数上调用[[Construct]]内部方法的结果,不提供任何参数(即空参数列表。。

生产 MemberExpression new MemberExpression参数
评估如下:


  1. ref 是评估 MemberExpression 的结果。

  2. 构造函数成为 GetValue ref )。

  3. argList 是评估参数的结果,生成参数值的内部列表( 11.2。 4 )。

  4. 如果 类型 构造函数)不是Object,抛出 TypeError 异常。

  5. 如果构造函数未实现[[Construct]]内部方法,则抛出 TypeError exception。

  6. 返回调用[[]的结果构造]] 构造函数上的内部方法,提供列表 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:

  1. Let ref be the result of evaluating NewExpression.
  2. Let constructor be GetValue(ref).
  3. If Type(constructor) is not Object, throw a TypeError exception.
  4. If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
  5. 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:

  1. Let ref be the result of evaluating MemberExpression.
  2. Let constructor be GetValue(ref).
  3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (11.2.4).
  4. If Type(constructor) is not Object, throw a TypeError exception.
  5. If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
  6. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆