【问题标题】:Constructor concept in JavaScriptJavaScript 中的构造函数概念
【发布时间】:2016-01-14 09:11:08
【问题描述】:

在我的一个问题中,我得到了以下代码作为答案之一。我现在对语言的理解已经好得多了, 只问一个小问题。

var person = function() {
     this.firstName = "";
     this.lastName = "";
} 

person.prototype.showFullName = function () { 
     console.log(this.firstName + " " + this.lastName); 
} 

var perObj = new person();
perObj.firstName = "Penelope";
perObj.lastName = "Barrymore";
perObj.showFullName();

考虑到对象,

var person = function() {
     this.firstName = "";
     this.lastName = "";
} 

当我调用这个对象时,

var perObj = new person();

这类似于构造函数吗?

一码一码

var perObj = new person(); 

被调用会自动执行以下两行吗?

 this.firstName = "";
 this.lastName = "";

在我正在研究的一个博客中,如果文件名是Samplescript.js,并且如果在其中使用相同的名称编写函数,例如var Samplescript=function(){},那么该函数是否会被视为构造函数? 请澄清一下。

尽管理论上事情很清楚,但实际上我没有得到任何令人满意的关于构造函数的答案,在这个例子中,它的编写方式使人们能够清楚地理解。

【问题讨论】:

标签: javascript constructor


【解决方案1】:

首先person 是一个常规的JavaScript 函数。当你调用它时,当然是行:

this.firstName = "";
this.lastName = "";

被执行。 构造函数 与其说是JS语言中真正存在的东西,不如说是一个概念。您需要构造函数通过调用new MyCtr() 创建新的类似对象。同时你需要常规的函数来封装一段逻辑,使其在不同的地方可以重复使用,而不需要复制/粘贴代码。

您可以将 JavaScript 中的所有函数用作构造函数。只需在函数调用表达式前添加new 关键字即可。这件事改变了函数执行的上下文。如果没有new,该函数将针对global 对象(浏览器中的window)执行。而函数内部的this变量是指上下文。

并非每个函数都准备好成为构造函数。通常,构造函数使用this 变量做一些事情,该变量是对在new MyCtr() 调用期间创建的对象的引用。此外,构造函数永远不会返回值。

我们来看几个例子(可以直接在浏览器的控制台中执行):

function foo() {
    this.a = 1;
}

foo();  // using function as a regular function. Ctx is window.
console.log(window.a);  // prints "1"
foo.call(window);  // explicitly specify execution ctx. The same as just foo() call

var instance = new foo();  // using foo as a constructor
console.log(instance.a);   // prints "1"

// actually you can do it without new keyword
var instance = {};  // manually create new object
foo.call(instance); // manually call foo against this object
console.log(instance.a);   // prints "1"

// However, the code above is not strictly equivalent to the code using new. 
// It omits the concept of prototype, but it's enough for our current task.

关于函数和文件。语言中没有像 Java 那样每个类都必须放在单独的文件中的事情。您可以将所有函数放在一个文件中,然后将其用作构造函数或不使用。然而,最佳实践是每个文件(称为模块)驻留一个构造函数(读作 class)。

【讨论】:

  • "您可以将 JavaScript 中的所有函数用作构造函数。" - 不正确。有可构造的对象和可调用的对象,并不是所有的都是。 (不过,使用function 关键字创建的是)
  • @Bergi,你是说这个stackoverflow.com/questions/32928810/…吗? (请看答案末尾)
  • 是的,ES6 箭头和方法等等。
  • 太棒了!非常感谢您的评论。这非常有用。
【解决方案2】:

JavaScript 中的任何函数都可以在使用 new 运算符调用函数时充当构造函数。

现在,构造函数是做什么的? 它从构造函数创建/实例化一个对象。如下图所示。

LINK,基本解释得很清楚。

this 是什么?

当使用 new 调用此构造函数时,this 指向在该调用中创建的新对象。并在该对象中设置firtName 和lastName(这是创建的新对象的初始化)。

现在,当我们向构造函数的原型添加方法时,所有使用构造函数创建的对象都可以共享该方法(图片解释得更清楚了)

关于您上次的查询 “而且在我正在研究的一个博客中,如果文件名是 Samplescript.js,并且如果在其中使用相同的名称编写函数,例如 var Samplescript=function(){},那么该函数是否会被视为构造函数?请澄清一下”

JavaScript 中的任何函数都可以在使用 new 运算符调用函数时充当构造函数,而不是博客所说的方式。

所以请停止阅读该博客,我提供的链接是一个很好的起点

【讨论】:

  • 赞成。感谢您的链接。虽然我现在没有时间仔细阅读它,但它似乎非常有用且有价值。
【解决方案3】:

您的理解似乎有些漏洞。希望我能帮上忙。

首先,构造函数的传统常规语法是function CapitalisedFunctionName()

function Person() {
  this.firstName = "";
  this.lastName = "";
}

注意:这不是一个对象。从您的问题来看,您不清楚这一点。

此时,您可以添加到原型中,从该构造函数创建的所有新对象都将从该原型中继承。您示例中修改后的方法将可用于所有新对象。

Person.prototype.fullname = function () { 
  return this.firstName + " " + this.lastName;
}

现在,构造函数允许您创建新的对象实例。所以当你写的时候:

var perObj = new person();

您正在调用构造函数,创建一个新的对象实例,并将该实例分配给perObj 变量。

当您创建一个新对象实例时,该对象包含 firstName 和 lastName 属性,可以像这样访问:

perObj.firstName;
perObj.lastName;

请注意,目前这些只分配了空字符串。

你也可以调用那个方法:

perObj.fullname();

但是,在这一点上,perObj.fullname(); 不会给你任何东西,因为firstName 和lastName 是空字符串。

您可以像在示例中那样定义它们:`perObj.lastName = 'Jones',或者您甚至可以首先更改创建对象的方式,这通常是首选方法:

考虑一下:

function Person(first, last) {
  this.firstName = first;
  this.lastName = last;
}

var perObj = new Person('Dave', 'Jones');

现在perObj 将预先填充这些属性:

perObj.firstName // Dave
perObj.lastName // Jones
perObj.fullname() // Dave Jones

【讨论】:

  • 准确地说,Person IS 对象本身。但是,我同意,这对于这个解释并不那么重要。
【解决方案4】:

使用new 运算符调用的任何函数都充当构造函数,因此this 将分配给新对象并指向它。构造函数内的代码也将被执行,新对象 (perObj) 将获得属性。

【讨论】:

    【解决方案5】:

    有几种方法可以定义 Javascript 类并使用构造函数调用它们。但请记住,JavaScript 实际上是无类的。

    1. 使用函数
    2. 对象字面量的使用
    3. 使用函数的单例

    关于它的优秀文章可以在这里找到:3 ways to define a Javascript class

    【讨论】:

      猜你喜欢
      • 2014-10-07
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多