No.js - utilização do módulo.exportações como construtor

de acordo com o nó.manual js:

Se quiser que a raiz da exportação do seu módulo seja uma função (como por exemplo: um construtor) ou se quiser exportar um objecto completo num atribuição em vez de construir uma propriedade de cada vez, atribua-a a modulo.exportações em vez de exportações.

o exemplo dado é:

// file: square.js
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

e usados assim:

var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());

a minha pergunta: porque é que o exemplo não usa o quadrado como um objecto? É válido o seguinte e torna o exemplo mais "orientado a objetos"?

var Square = require('./square.js');
var mySquare = new Square(2);
console.log('The area of my square is ' + mySquare.area());
Author: Naresh, 2013-12-12

4 answers

Os módulos CommonJS permitem duas formas de definir propriedades exportadas. Em ambos os casos você está retornando um Objeto / Função. Como as funções são cidadãos de primeira classe em JavaScript eles podem agir como objetos (tecnicamente eles são objetos). Isso disse que a sua pergunta sobre o uso das palavras-chave new tem uma resposta simples: sim. Vou ilustrar...

Exportações de Módulos

Pode usar a variável exports fornecida para anexar propriedades a ela. Uma vez exigido em outro módulo essas propriedades de atribuição ficam disponíveis. Ou pode atribuir um objecto ao módulo.exporta propriedade. Em qualquer dos casos, o que é devolvido por require() é uma referência ao valor de module.exports.

Um exemplo de pseudo-código de como um módulo é definido:

var theModule = {
  exports: {}
};

(function(module, exports, require) {

  // Your module code goes here

})(theModule, theModule.exports, theRequireFunction);

No exemplo acima module.exports e exports são o mesmo objecto. A parte legal é que você não vê nada disso em seus módulos CommonJS como todo o sistema cuida disso para você tudo que você precisa saber é que há um objeto módulo com uma propriedade exportadora e uma variável Exportadora que aponta para a mesma coisa o módulo.as exportações sim.

Exigir com Construtores

, uma vez que você pode anexar uma função diretamente para module.exports você pode essencialmente de retorno de uma função e, como qualquer função pode ser administrado como um construtor (Que está em itálico, uma vez que a única diferença entre uma função e um construtor em JavaScript é como você pretende usá-lo. Tecnicamente, não há diferença.)

Seguir é um código perfeitamente bom e eu pessoalmente encorajo:

// My module
function MyObject(bar) {
  this.bar = bar;
}

MyObject.prototype.foo = function foo() {
  console.log(this.bar);
};

module.exports = MyObject;

// In another module:
var MyObjectOrSomeCleverName = require("./my_object.js");
var my_obj_instance = new MyObjectOrSomeCleverName("foobar");
my_obj_instance.foo(); // => "foobar"

Exigir para não Construtores

A mesma coisa se aplica a funções não-construtoras:

// My Module
exports.someFunction = function someFunction(msg) {
  console.log(msg);
}

// In another module
var MyModule = require("./my_module.js");
MyModule.someFunction("foobar"); // => "foobar"
 156
Author: Sukima, 2016-02-11 15:31:17
Na minha opinião, alguns dos nódulos.os exemplos js são bastante inventados. Podes esperar ver algo mais parecido com isto no mundo real.
// square.js
function Square(width) {

  if (!(this instanceof Square)) {
    return new Square(width);
  }

  this.width = width;
};

Square.prototype.area = function area() {
  return Math.pow(this.width, 2);
};

module.exports = Square;

Utilização

var Square = require("./square");

// you can use `new` keyword
var s = new Square(5);
s.area(); // 25

// or you can skip it!
var s2 = Square(10);
s2.area(); // 100

Para o povo ES6

class Square {
  constructor(width) {
    this.width = width;
  }
  area() {
    return Math.pow(this.width, 2);
  }
}

export default Square;

Usando - o no ES6

import Square from "./square";
// ...

Ao usar uma classe, você deve usar a palavra-chave new para a instalar. Tudo o resto permanece igual.

 121
Author: maček, 2015-07-08 08:24:45
Esta pergunta não tem nada a ver com como funciona. Basicamente, o que você definir {[[2]} para o seu módulo será devolvido a partir da chamada require() para ele.

Isto seria equivalente a:

var square = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

Não há necessidade da palavra-chave new quando se chama square. Você não está retornando a instância de função em si de square, Você está retornando um novo objeto no final. Portanto, você pode simplesmente chamar esta função diretamente.

Para mais intrincado argumentos em torno de new, confira isto: A Palavra-chave "nova" do JavaScript é considerada nociva?

 1
Author: Brad, 2017-05-23 10:31:24

O código de exemplo é:

No principal

square(width,function (data)
{
   console.log(data.squareVal);
});

Usando o seguinte pode funcionar

exports.square = function(width,callback)
{
     var aa = new Object();
     callback(aa.squareVal = width * width);    
}
 0
Author: AmirtharajCVijay, 2013-12-12 06:53:45