【问题标题】:Can I simplify the instantiation of this constructor function?我可以简化这个构造函数的实例化吗?
【发布时间】:2020-07-06 14:44:16
【问题描述】:

是否可以将以下代码(尤其是 new 关键字)分解为更简单的代码(以便我理解发生了什么)?:

function F() {
  this.color = 'red';
  this.printNumber = function printNumber() {
    console.log(5);
  };
 }

 let o = new F();
 console.log(o);

这是我的尝试:

当我被告知 let o = new F();let o = F.call({}) 相同时,我以为我赢了.

新对象的构造函数属性设置是否非常重要?我知道这个构造函数将被视为一个方法,并且其中的this 将这个对象作为一个整体来引用。这让我认为new 的工作原理是:

  1. 立即创建一个将构造函数属性设置为构造函数的对象。
  2. 执行构造函数属性(一种方法),使新对象看起来像:
{
color: "red",
printNumber: printNumber,
constructor: F
//as it is an instance of the inbuilt Object constructor function, it has all the properties/methods of an object
}

【问题讨论】:

  • 或者你可以使用 ES6 类:Class F { color= "red"; printNumber() { console.log(this.color); } }
  • 如果此代码有效,并且您想查看代码,您应该查看Code Review 的帮助中心,看看它是否与主题相关。
  • @HereticMonkey 这个问题在 Code Review 上会偏离主题,因为它缺少上下文。以后推荐 Code Review 时请链接到帮助中心。采取,“这可能是代码审查的主题。请在发布之前检查if it is on-topichow to post a good question。”
  • @Peilonrayz 您的示例将在刻度线中提供更多帮助,以便可以复制和粘贴它。请注意,我确实说过要查看帮助中心,并且所有网站的帮助中心都位于 /help。

标签: javascript


【解决方案1】:

新对象有构造函数属性是不是很重要 设置为构造函数?

如果您打算创建一个可以实例化和继承的对象,那么是的,您应该使用new 语法。 call() 就是这样做的,它调用函数(运行它的代码)而不正式实例化对象的实例。 call() 还允许您定义函数运行时this 将绑定到的对象,但call()new 并不相同。

当您使用new 进行实例化时,会创建一个对象实例并执行构造函数。然后将this 绑定到新实例。

有关new 和原型继承如何工作的更多详细信息,请参阅this other post of mine

另外,仅供参考,您应该将对象的方法(无论您拥有什么特定实例都操作相同)添加到对象的 prototype,而不是对象本身:

function F() {
  this.color = 'red';
}

// Methods are usually added just once to the object's
// prototype and then all instances inherit it, which
// has a lower memory footprint because the method is
// defined and attached just once instead of on each 
// instance.
F.prototype.printNumber = function printNumber() {
    console.log(5);
};

let o = new F();
console.log(o.color);
o.printNumber();

【讨论】:

    【解决方案2】:

    当您使用 new 关键字调用构造函数时,会发生以下情况:

    1. 一个新的空对象被创建并分配给this
    2. 函数体执行。通常它会修改this,为其添加新属性。
    3. 返回this的值。

    返回对象在其原型中具有引用构造函数的constructor 属性。

    现在为什么原型中的构造函数很重要?这都是关于 JS 中的对象继承模式。

    //Here is the Animal constructor
    function Animal() {
       this.live  = true;
    }
    
    //Object methods are attached to the prototype. So, they have a single presence in the object hierarchy
    Animal.prototype.move = function() {console.log('moving')}; 
    
    
    //Here is the Cat constructor. This is how JS makes the Cat inherit from the animal.
    function Cat() {
       Animal.call(this);   //The this keyword points to the Cat object being created
    }
    
    //Let's set its prototype
    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;
    
    
    //All is set. Let's create the child object    
    let cat = new Cat();
    

    这是事件的顺序。

    1. 声明了简单的 Animal 构造函数。它会为每只动物添加live=true

    2. 它的原型有move 方法。所以,任何动物都可以移动,并且这个移动函数不会被实例化——因为它在原型中——而不是在this中。

    3. 定义 Cat 构造函数。它简单地调用 Animal 构造函数而不使用 new。因此,它不会创建 Animal - 但会在结果对象中创建所有动物属性。

    4. 将 Animal 设置为 Cat 的原型。请注意,它继承了 Animals 原型方法 - 即 move。这就是为什么我们说 javascript 具有原型继承。

    5. 将 Cat 构造函数设置为 Cat。这是因为到第 4 点,Cat 的构造函数也是 Animal。我们在这里改变它。 (是的 - 奇怪)

    6. 创建一只新猫。这将 call 没有 new 的 Animal 构造函数,因此,猫具有所有 Animal 属性。猫可以移动——因为它的原型有move 方法。最后,它的构造函数不是 Cat - 所以,new 关键字将使用它。


    新的 Ecmascript 版本将这一切都包含在 Class 中并自动执行。但我相信基本的理解也很重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      相关资源
      最近更新 更多