John Resig is a simple instance of the class and "use strict"

Link: http://ejohn.org/blog/simple-class-instantiation/

// makeClass - By John Resig (MIT Licensed) function makeClass(){ return function(args){ if ( this instanceof arguments.callee ) { if ( typeof this.init == "function" ) this.init.apply( this, args.callee ? args : arguments ); } else return new arguments.callee( arguments ); }; } 

I was wondering if there is any ECMAScript 5 compatible way to implement the same functionality. The problem is that access to arguments.callee expired in strict mode.

+7
source share
3 answers

As I understand it, arguments.callee not expired in strict mode, in which case you can continue to use it; rather, it was deleted and an attempt to use will (or should) throw an exception.

The workaround is to use anonymous functions if you forgive the oxymoron. Actually, I have to say "named function expressions" . Example:

 function someFunc(){ return function funcExpressionName(args){ if (this instanceof funcExpressionName) { // do something } else return new funcExpressionName( arguments ); }; } 

The name you specify in my example funcExpressionName should not be accessible from anywhere except inside the function to which it is applied, but unfortunately IE has other ideas (as you can see if you are Google ).

For example, in your question, I'm not sure how to handle args.callee , since I do not know how this is set by the calling function, but using arguments.callee will be replaced according to my example.

+4
source

The above idea of ​​nnnnnn is not bad. And to avoid IE problems, I propose the following solution.

 function makeClassStrict() { var isInternal, instance; var constructor = function(args) { // Find out whether constructor was called with 'new' operator. if (this instanceof constructor) { // When an 'init' method exists, apply it to the context object. if (typeof this.init == "function") { // Ask private flag whether we did the calling ourselves. this.init.apply( this, isInternal ? args : arguments ); } } else { // We have an ordinary function call. // Set private flag to signal internal instance creation. isInternal = true; instance = new constructor(arguments); isInternal = false; return instance; } }; return constructor; } 

Note that we avoid referencing args.callee in the // do something with an internal flag.

+2
source

John Resig source code does not work with a constructor without parameters.

 var Timestamp = makeClass(); Timestamp.prototype.init = function() { this.value = new Date(); }; // ok var timestamp = Timestamp(); alert( timestamp.value ); // TypeError: args is undefined var timestamp = new Timestamp(); alert( timestamp.value ); 

But it can be restored using the following line

 this.init.apply( this, args && args.callee ? args : arguments ); 
+1
source

All Articles