最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Call function directly after constructor "new" - Stack Overflow

programmeradmin9浏览0评论

In many languages, to invoke some function directly on new instance I need to wrap it into braces:

 (new Date()).toString()

In JS new Date().toString() and Date().toString() give the same results as well.

Is it allowed to use function call immediately after instantiating new object in this way?

It looks like new keyword is optional sometimes. How is this interpreted by JS engine?

In many languages, to invoke some function directly on new instance I need to wrap it into braces:

 (new Date()).toString()

In JS new Date().toString() and Date().toString() give the same results as well.

Is it allowed to use function call immediately after instantiating new object in this way?

It looks like new keyword is optional sometimes. How is this interpreted by JS engine?

Share Improve this question asked Apr 30, 2017 at 22:27 ANTARAANTARA 8301 gold badge13 silver badges20 bronze badges 3
  • new is not "optional". It's required when you want the behavior it provides, and not when you don't. – Pointy Commented Apr 30, 2017 at 22:32
  • you'd do well learning the nuances of the new keyword in js as well as understand the difference between the object oriented paradigm vs the prototypical paradigm. – Chaim Friedman Commented Apr 30, 2017 at 22:37
  • 1 Please note carefully that new Date().toString() and Date().toString() do give the same result. However, new Date() is a date object while Date() is a string. It is "coincidental" that toString() gives the same result for both. – Freeman Lambda Commented Apr 30, 2017 at 22:43
Add a ment  | 

2 Answers 2

Reset to default 5

In many languages, to invoke some function directly on new instance I need to wrap it into braces Is it allowed to use function call immediately after instantiating new object in this way?

I think the problem here is potential ambiguity. While (new Date()).toString() is clear, new Date().toString() could (theoretically) mean either (new Date()).toString() or new (Date().toString)().

But here es operator precedence to the rescue.

the new (with argument list) operator has a higher precedence than a function call. Therefore the order of execution in new Date().toString() is as clear (at least to the engine) as the order in wich these math operations have to be executed 2 + 3 * 4

But beware, in JS you can also write new Date; without the brackets, and this operator new (without argument list) has a lower precedence than a function call. So new Date.toString() is interpreted as new (Date.toString)() and you get an Error that toString() is no constructor.

It looks like new keyword is optional sometimes. How is this interpreted by JS engine?

Not at all. This ain't a JS feature this is a quirk in the implementation of these functions/classes/constructors

A bit like these implementations:

function Foo(){
    if(!(this instanceof Foo)) 
        return new Foo();

    this.foo = 42;
}

//or something like
function Bar(){
    return Object.create(Bar.prototype, {
        bar: { value: 42 }
    });
}

console.log(new Foo(), Foo());
console.log(new Bar(), Bar());

And again beware. Due to added security/failsafety you can't implement something like that with the new class keyword. It adds (hidden) code to ensure that these constructors are always called with the new keyword, otherwise the constructor throws an error.

Edit: For example the Array constructor works like described above, but as it seems (as pointed out in Freeman Lambdas answer) the Date constructor has (defined by the spec) two different return values, depending on wether you call it as a function or as a constructor.

EMCAScript spec

The Date constructor is the %Date% intrinsic object and the initial value of the Date property of the global object. When called as a constructor it creates and initializes a new Date object. When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).

// with new
const a = new Date();
console.log(typeof a); // object
console.log(a instanceof Date); // true
console.log(a.toString()); // date formatted string

// without new
const b = Date();
console.log(typeof b); // string
console.log(b instanceof Date); // false
console.log(b.toString()); // date formatted string

As you can see this behavior of Date is explicitly described in the language spec, it has nothing to do with new being optional. You can discover a lot about new just by reading through these popular questions: https://stackoverflow./search?q=javascript+new+keyword

Finally, you can use a newly created object immediately. There is no need to wrap it in parenthesis.

发布评论

评论列表(0)

  1. 暂无评论