创建一个JS类:IIFE vs返回原型

Nes*_*tez 17 javascript prototype class iife

让我们看两个例子,我将尝试解释我想要理解的内容.

var Car = function(){
  // Init class
  function Car() { };
  // Private func/vars
  var private = { color:'red' };
  // Public func/vars
  Car.prototype = {
    newColor: function(color) { private.color = color },
    getColor: function() { return private.color }
  };

  return Car.prototype; // return with prototype
};

var myCar = new Car();
Run Code Online (Sandbox Code Playgroud)

和:

var Car = (function(){
  // Init class
  function Car() { };
  // Private func/vars
  var private = { color:'red' };
  // Public func/vars
  Car.prototype = {
    newColor: function(color) { private.color = color },
    getColor: function() { return private.color }
  };

  return Car; // avoid prototype adding parentheses on next line;
})();

var myCar = new Car();
Run Code Online (Sandbox Code Playgroud)

让我们看看!,这两个类都是作为函数表达式创建的,两者都是一样的.它们之间的唯一区别是:第一个返回Car函数及其prototype属性.第二个工作返回Car函数,避免使用原型属性,而是使用IIFE.

使用return Car.prototype;和避免IIFE和使用return Car;IIFE 之间的区别是什么(类声明结束时的括号).

Ada*_*kis 16

第二个代码示例是实现您正在寻找的东西的正确方法.您可以创建一个立即执行的函数,在其中创建一个新函数,添加到其原型,然后返回它.

第一个例子有点奇怪,并没有完全正确地创建构造函数.这条线

return Car.prototype; // return with prototype
Run Code Online (Sandbox Code Playgroud)

使您的Car函数简单地始终返回您先前分配给的对象文字Car.prototype.这会覆盖调用的函数的正常行为new


只需注意一点,这一行:

Car.prototype = {
   newColor: function(color) { private.color = color },
   getColor: function() { return private.color }
};
Run Code Online (Sandbox Code Playgroud)

将导致constructor新创建对象的属性不再指向您的Car函数.如果这对您很重要,有两种简单的方法可以解决这个问题.

Car.prototype = {
   newColor: function(color) { private.color = color },
   getColor: function() { return private.color }
};
Car.prototype.constructor = Car;   // <-------- add this line
Run Code Online (Sandbox Code Playgroud)

或者将上面改为

Car.prototype.newColor = function(color) { private.color = color };
Car.prototype.getColor = function() { return private.color };
Run Code Online (Sandbox Code Playgroud)