构造函数

创建对象的一个重要方式是使用构造函数,构造函数以大写字母开头,构造函数必须始终使用特殊关键字 new 来调用,
与普通函数的区别是:普通函数必须创建将返回的对象并直接修改该对象,而构造函数会自动创建对象,
然后,为了向此对象中添加属性或方法,需要使用特殊的关键字 this

  • 要实例化(即 创建 )一个新的对象,我们可以使用 new 运算符来调用这个函数:
    new SoftwareDeveloper();

构造函数:结构和语法


function SoftwareDeveloper() {
this.favoriteLanguage = 'JavaScript';
}

首先,构造函数并不声明局部变量,而是使用 this 关键字来保存数据。以上函数将为所创建的任何对象添加一个 favoriteLanguage 属性,并为其分配一个默认值 ‘JavaScript’。现在不用太在意构造函数中的 this;只要知道 this 是指在构造函数前面使用 new 关键字创建的新对象即可。我们很快就会详细介绍这个 this
最后一点比较特别的是,这个函数似乎不会返回任何东西!JavaScript 中的构造函数不应该有一个显式的返回值(即使用 return 语句)。

创建一个新的对象


正如我们在上面看到的,让我们使用 new 运算符来创建一个新的对象:

let developer = new SoftwareDeveloper();

我们已经把这个调用的返回值保存到了变量 developer 中。让我们执行 console.log(developer); 将这个 SoftwareDeveloper 对象记录到控制台:

console.log(developer); // SoftwareDeveloper {favoriteLanguage: "JavaScript"}

用对象字面量的方式来创建对象,看看有何不同

let orderDeveloper = { favoriteLanguage: 'JavaScript' };

otherDeveloper; // { favoriteLanguage: "JavaScript" }

可以看出 与 developer 相比,创建对象的构造函数 SoftwareDeveloper 没有列在Chrome 开发者工具中;
在 Chrome 开发者工具中 构造函数通常显示在 {} 前面;
developer 的构造函数是 SoftwareDeveloper,而 orderDeveloper 的构造函数是 object 构造函数;比较之下,两者原型将有所不同。

构造函数可以有参数


与常规函数一样,使用构造函数的一个好处是它们也可以接受参数。让我们更新以上构造函数来接受一个参数,并为其分配 name 属性:

function SoftwareDeveloper(name) {
this.favoriteLanguage = 'JavaScript';
this.name = name;
}

在更新的 SoftwareDeveloper() 函数中,无论传入函数的值是什么,它都将是对象的 name 属性的值。让我们来看看:

let instructor = new SoftwareDeveloper('Andrew');

console.log(instructor);

// SoftwareDeveloper { favoriteLanguage: 'JavaScript', name: 'Andrew' }

正如我们在上面看到的,我们可以使用相同的构造函数来创建不同的对象:

let teacher = new SoftwareDeveloper('Richard');

console.log(teacher);

// SoftwareDeveloper { favoriteLanguage: 'JavaScript', name: 'Richard' }

构造函数的好处是,我们可以调用相同的构造函数,创建无数个实例或对象。

省略 new 运算符


如果你无意中 没有 使用 new 运算符来调用构造函数,会发生什么?

function SoftwareDeveloper(name) {
this.favoriteLanguage = 'JavaScript';
this.name = name;
}

let coder = SoftwareDeveloper('David');

console.log(coder);
// undefined

这是怎么回事?如果不使用 new 运算符,则不会创建对象。该函数会像任何其他常规函数一样被调用。由于该函数不会 _返回_ 任何东西(除了所有函数都会默认返回的 undefined 之外),因此 coder 变量最终会被分配给 undefined

还有一点需要注意:由于这个函数作为一个常规函数被调用,因此 this 的值也会截然不同。现在不用太在意这一点,我们将在下一部分深入探讨 this 关键字!

查看对象的构造函数(instanceof)


如果我们想查看某个对象是否是用构造函数创建的呢?我们可以使用 instanceof(它会返回一个布尔值)来窥见一些端倪。让我们来看看吧!

function Developer(name){
this.name = name;
}
const dev = new Developer('Veronkia');

typeof dev; // "object"

dev instanceof Developer; // true

instanceof 和原型链


在以上示例中,instanceof 确认一个特定的构造函数确实创建了一个特定的对象。我们知道这一点,是因为我们在调用 Developer() 构造函数之后直接实例化了 dev 对象。

然而,很多时候并没有这么简单:instanceof 运算符实际上会测试构造函数是否出现在某个对象的原型链中。这意味着,虽然我们不是总能检查到底是 哪个构造函数 创建了该对象,但是它使我们能够洞察某个对象可能访问哪些其他的属性和方法。

小结


JavaScript 的类系统是直接使用函数和对象来构建的。使用 new 运算符来调用构造函数可以实例化一个新的对象。相同的构造函数可以用于创建不同的对象。

我们在整篇中广泛讨论了函数、对象和 this。事实证明,这三者是密切相关的! 我们将在下一部分深入探讨 this 关键字,并仔细分析这三者之间的关系。

-------------本文结束 感谢您的阅读-------------
0%