结构器和操作符 “new”
惯例的 {...}
语法容许创立一个对象。然而咱们常常须要创立许多相似的对象,例如多个用户或菜单项等。
这能够应用构造函数和 "new"
操作符来实现。
构造函数
构造函数在技术上是惯例函数。不过有两个约定:
- 它们的命名以大写字母结尾。
- 它们只能由
"new"
操作符来执行。
例如:
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("Jack");
alert(user.name); // Jack
alert(user.isAdmin); // false
当一个函数被应用 new
操作符执行时,它依照以下步骤:
- 一个新的空对象被创立并调配给
this
。 - 函数体执行。通常它会批改
this
,为其增加新的属性。 - 返回
this
的值。
换句话说,new User(...)
做的就是相似的事件:
function User(name) {// this = {};(隐式创立)// 增加属性到 this
this.name = name;
this.isAdmin = false;
// return this;(隐式返回)}
所以 new User("Jack")
的后果是雷同的对象:
let user = {
name: "Jack",
isAdmin: false
};
当初,如果咱们想创立其余用户,咱们能够调用 new User("Ann")
,new User("Alice")
等。比每次都应用字面量创立要短得多,而且更易于浏览。
这是结构器的次要目标 —— 实现可重用的对象创立代码。
让咱们再强调一遍 —— 从技术上讲,任何函数都能够用作结构器。即:任何函数都能够通过 new
来运行,它会执行下面的算法。“首字母大写”是一个独特的约定,以明确示意一个函数将被应用 new
来运行。
new function() { …}
如果咱们有许多行用于创立单个简单对象的代码,咱们能够将它们封装在构造函数中,像这样:
let user = new function() {
this.name = "John";
this.isAdmin = false;
// ……用于用户创立的其余代码
// 兴许是简单的逻辑和语句
// 局部变量等
};
结构器不能被再次调用,因为它不保留在任何中央,只是被创立和调用。因而,这个技巧旨在封装构建单个对象的代码,而无需未来重用。
结构器模式测试:new.target
进阶内容:
本节波及的语法内容很少应用,除非你想理解所有内容,否则你能够间接跳过该语法。
在一个函数外部,咱们能够应用 new.target
属性来查看它是否被应用 new
进行调用了。
对于惯例调用,它为空,对于应用 new
的调用,则等于该函数:
function User() {alert(new.target);
}
// 不带 "new":User(); // undefined
// 带 "new":new User(); // function User { ...}
它能够被用在函数外部,来判断该函数是被通过 new
调用的“结构器模式”,还是没被通过 new
调用的“惯例模式”。
咱们也能够让 new
调用和惯例调用做雷同的工作,像这样:
function User(name) {if (!new.target) { // 如果你没有通过 new 运行我
return new User(name); // ……我会给你增加 new
}
this.name = name;
}
let john = User("John"); // 将调用重定向到新用户
alert(john.name); // John
这种办法有时被用在库中以使语法更加灵便。这样人们在调用函数时,无论是否应用了 new
,程序都能工作。
不过,到处都应用它并不是一件坏事,因为省略了 new
使得很难察看到代码中正在产生什么。而通过 new
咱们都能够晓得这创立了一个新对象。
结构器的 return
通常,结构器没有 return
语句。它们的工作是将所有必要的货色写入 this
,并主动转换为后果。
然而,如果这有一个 return
语句,那么规定就简略了:
- 如果
return
返回的是一个对象,则返回这个对象,而不是this
。 - 如果
return
返回的是一个原始类型,则疏忽。
换句话说,带有对象的 return
返回该对象,在所有其余状况下返回 this
。
例如,这里 return
通过返回一个对象笼罩 this
:
function BigUser() {
this.name = "John";
return {name: "Godzilla"}; // <-- 返回这个对象
}
alert(new BigUser().name ); // Godzilla,失去了那个对象
这里有一个 return
为空的例子(或者咱们能够在它之后搁置一个原始类型,没有什么影响):
function SmallUser() {
this.name = "John";
return; // <-- 返回 this
}
alert(new SmallUser().name ); // John
通常结构器没有 return
语句。这里咱们次要为了完整性而提及返回对象的非凡行为。
省略括号
顺便说一下,如果没有参数,咱们能够省略 new
后的括号:
let user = new User; // <-- 没有参数
// 等同于
let user = new User();
这里省略括号不被认为是一种“好格调”,然而标准容许应用该语法。
结构器中的办法
应用构造函数来创建对象会带来很大的灵活性。构造函数可能有一些参数,这些参数定义了如何结构对象以及要放入什么。
当然,咱们不仅能够将属性增加到 this
中,还能够增加办法。
例如,上面的 new User(name)
用给定的 name
和办法 sayHi
创立了一个对象:
function User(name) {
this.name = name;
this.sayHi = function() {alert( "My name is:" + this.name);
};
}
let john = new User("John");
john.sayHi(); // My name is: John
/*
john = {
name: "John",
sayHi: function() { ...}
}
*/
类 是用于创立简单对象的一个更高级的语法,咱们稍后会讲到。
总结
- 构造函数,或简称结构器,就是惯例函数,但大家对于结构器有个独特的约定,就是其命名首字母要大写。
- 构造函数只能应用
new
来调用。这样的调用意味着在开始时创立了空的this
,并在最初返回填充了值的this
。
咱们能够应用构造函数来创立多个相似的对象。
JavaScript 为许多内置的对象提供了构造函数:比方日期 Date
、汇合 Set
以及其余咱们打算学习的内容。
对象,咱们还会回来哒!
在本章中,咱们只介绍了对于对象和结构器的基础知识。它们对于咱们在下一章中,学习更多对于数据类型和函数的相干常识十分重要。
在咱们学习了那些之后,咱们将回到对象,在 <info:prototypes> 和 <info:classes> 章节中深刻介绍它们。
作业题
先本人做题目再看答案。
1. 两个函数 — 一个对象
重要水平:⭐️⭐️
是否能够创立像 new A()==new B()
这样的函数 A
和 B
?
function A() { ...}
function B() { ...}
let a = new A;
let b = new B;
alert(a == b); // true
如果能够,请提供一个它们的代码示例。
2. 创立 new Calculator
重要水平:⭐️⭐️⭐️⭐️⭐️
创立一个构造函数 Calculator
,它创立的对象中有三个办法:
read()
应用prompt
申请两个值并把它们记录在对象的属性中。sum()
返回这些属性的总和。mul()
返回这些属性的乘积。
例如:
let calculator = new Calculator();
calculator.read();
alert("Sum=" + calculator.sum() );
alert("Mul=" + calculator.mul() );
3. 创立 new Accumulator
重要水平:⭐️⭐️⭐️⭐️⭐️
创立一个构造函数 Accumulator(startingValue)
。
它创立的对象应该:
- 将“以后 value”存储在属性
value
中。起始值被设置到结构器startingValue
的参数。 read()
办法应该应用prompt
来读取一个新的数字,并将其增加到value
中。
换句话说,value
属性是所有用户输出值与初始值 startingValue
的总和。
上面是示例代码:
let accumulator = new Accumulator(1); // 初始值 1
accumulator.read(); // 增加用户输出的 value
accumulator.read(); // 增加用户输出的 value
alert(accumulator.value); // 显示这些值的总和
答案:
在微信公众号「技术漫谈」后盾回复 1-4-5
获取作业答案。
古代 JavaScript 教程:开源的古代 JavaScript 从入门到进阶的优质教程。React 官网文档举荐,与 MDN 并列的 JavaScript 学习教程。
在线收费浏览:https://zh.javascript.info
扫描下方二维码,关注微信公众号「技术漫谈」,订阅更多精彩内容。