valores valor usada una retorno retornar para matriz instrucción función funcion devolver cuál array javascript constructor new-operator

javascript - usada - ¿Qué valores puede devolver un constructor para evitar devolver esto?



retornar valor javascript para html (5)

Como nota al margen, el valor de retorno o this es solo parte de la ecuación.

Por ejemplo, considera esto:

function Two() { return new Number(2); } var two = new Two; two + 2; // 4 two.valueOf = function() { return 3; } two + 2; // 5 two.valueOf = function() { return ''2''; } two + 2; // ''22''

Como puede ver, .valueOf() se usa internamente y se puede explotar por diversión y beneficio. Incluso puede crear efectos secundarios, por ejemplo:

function AutoIncrementingNumber(start) { var n = new Number, val = start || 0; n.valueOf = function() { return val++; }; return n; } var auto = new AutoIncrementingNumber(42); auto + 1; // 43 auto + 1; // 44 auto + 1; // 45

Puedo imaginar que esto debe tener algún tipo de aplicación práctica. Y tampoco tiene que ser explícitamente un Number , si agrega .valueOf a cualquier objeto, puede comportarse como un número:

({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638

Puede explotar esto para crear un objeto que siempre devuelva un nuevo GUID, por ejemplo.

¿Cuáles son las circunstancias exactas para las cuales una declaración de retorno en Javascript puede devolver un valor distinto a this cuando se invoca un constructor con la new palabra clave?

Ejemplo:

function Foo () { return something; } var foo = new Foo ();

Si no me equivoco, si something es una primitiva no funcional, se devolverá. De something contrario, se devuelve something . ¿Es esto correcto?

IOW, ¿qué valores puede llevar something a causar (new Foo () instanceof Foo) === false ?


Cuando usa la palabra clave new , se crea un objeto. Luego se llama a la función para inicializar el objeto.

No hay nada que la función pueda hacer para evitar que se cree el objeto, ya que eso se hace antes de que se llame a la función.


Ejemplos concretos http://jsbin.com/zivivucahi/1/edit?html,js,console,output

/* ECMA 262 v 5 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf "4.3.2 primitive value member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6" */ var Person = function(x){ return x; }; console.log(Person.constructor); console.log(Person.prototype.constructor); console.log(typeof(Person)); console.log(typeof(Person.prototype)); function log(x){ console.log(x instanceof Person); console.log(typeof x); console.log(typeof x.prototype); } log(new Person(undefined)); log(new Person(null)); log(new Person(true)); log(new Person(2)); log(new Person("")); //returns a function not an object log(new Person(function(){})); //implementation? //log(new Person(Symbol(''%'')));


La condición exacta se describe en la propiedad interna [[Construct]] , que utiliza el new operador:

Del ECMA-262 3ro. Especificación de la edición:

13.2.2 [[Construct]]

Cuando se llama a la propiedad [[Construct]] para un objeto de Function F , se realizan los siguientes pasos:

  1. Crea un nuevo objeto ECMAScript nativo.
  2. Establezca la propiedad [[Class]] del Result(1) en "Object" .
  3. Obtenga el valor de la propiedad prototipo de F
  4. Si Result(3) es un objeto, establezca la propiedad [[Prototype]] del Result(1) en Result(3) .
  5. Si el Result(3) no es un objeto, establezca la propiedad [[Prototype]] del Result(1) en el Object prototipo del objeto original como se describe en 15.2.3.1 .
  6. Invoque la propiedad [[Call]] de F , proporcionando el Result(1) como this valor y proporcionando la lista de argumentos pasada a [[Construct]] como los valores del argumento.
  7. Si Type (Result(6)) es Object entonces devuelve Result(6) .
  8. Result(1) devolución Result(1) .

Observe los pasos 7 y 8, el nuevo objeto se devolverá solo si el tipo de Result(6) (el valor devuelto por la función del constructor F ) no es un Objeto.


No pude encontrar ninguna documentación sobre el asunto, pero creo que estás en lo correcto. Por ejemplo, puede devolver un new Number(5) desde un constructor, pero no el literal 5 (que se ignora y se devuelve en su lugar).