使用 JavaScript 对象构建项目。
你好,世界!这篇文章是一个项目模板。它更像是一个完整的项目,只不过只包含 Javascript(即没有 HTML 或 CSS)。
我一直不太喜欢JavaScript 的对象和类,并非我不了解其基本原理,只是我觉得没必要太担心,因为我认为函数式编程更简单。我一直这么想,到目前为止,我所有的项目都是用函数式编程做的。但当我参加 CodeCademy 的 JavaScript 课程时,我发现了自己对面向对象编程的热爱,对我来说,它更简单,尤其是使用Getters 和 Setters的时候。
在我完成课程的JavaScript 对象模块后,他们(CodeCademy)准备开发一个叫做Meal Maker 的项目。虽然我无法以免费用户的身份访问它,但我理解开发这个项目的目的,即在实际项目中使用Getters 和 Setters 。
有一个问题,我不知道“餐食制作器”是做什么的,也不知道它通常是怎么工作的,但我有个好主意,可以练习一下“Getters 和 Setters”;一个预约应用程序。很棒吧?是的,我知道,它的功能很简单,就是为商务用户预约。
假设我是埃隆马斯克(但我不是),我可以使用此应用程序创建一个帐户,这样其他用户就可以与我预约。
现在,埃隆马斯克不会是唯一拥有商业账户的用户,我们将使用工厂功能(而不是类)来复制并拥有我们想要的任意数量的商业账户。
这个应用可能很基础,但它包含了开发预约应用的所有难点。请记住,本文的目的并非向您展示开发预约应用的某种方法,而是向您展示如何在此类项目中使用Getter 和 Setter方法。
如果您不了解 JavaScript Getters 和 Setters 或JavaScript 对象,我建议您学习CodeCademy 的 JS 对象课程。
写得够多了,我们开始写代码吧。向下滚动查看完整代码,或者直接访问GitHub 获取代码。
// alert: am tired of using John Doe, i wanna use Elon Musk
const elonMusk = {
_hoursfree: [10, 12, 9], // currently hard-coded, but will change in time
};
_
属性前加下划线 ( )的原因hoursFree
是,我故意不想让该属性被直接访问。程序员应该了解并遵守这一点。但我们需要访问 Elon Musk 的空闲时间,为此,我们将使用 JavaScript Getters,即
const elonMusk = {
_hoursFree: [10, 12, 9],
get hoursFree() {
return this._hoursFree; // can now be accessed legitimately
},
};
现在我们想向 elonMusk 对象添加更多属性
const elonMusk = {
_hoursFree: [10, 12, 9],
acceptedPurpose: 'any',
pendingMeetongs: [], // meetings yet to be approved by Elon Musk
declinedMeetings: [], // meetings not approved by Elon Musk
approvedMeetings: [], // meetings approved by Elon Musk
canceledMeetings: [], // meetings already approved but later canceled maybe something came up
_feedback: '', // feedback to the booking user (user making the booking)
get hoursFree() {
return this._hoursFree;
},
get feedBack() {
return this._feedback); // simply return a feedback
},
};
该acceptedPurpose
属性仅表示 Elon Musk 当前想要接受的目的。假设该应用程序的设计包含一个会议目的,可以根据具体情况每周或每天设置;由 Elon Musk 设定。假设acceptedPurpose
该应用程序提供的选项是商务、家庭、娱乐或任何
因此,目前我们假设伊隆·马斯克可以参加任何类型的会议,无论是商务会议、娱乐会议还是家庭会议。目前的硬编码稍后会更改。
现在让我们开始使用Setters。假设我们想预约与 Elon Musk 的会面,该怎么做?
// still in the elonMusk object, just under the feedBack getter
set newMeeting(time) {
if (this._hoursFree.indexOf(time) !== -1) {
this.pendingMeetings.push(time);
this._feedback =
'Your meeting was sent successfully. Elon Musk can now review and approve or decline';
} else {
this._feedback = 'Time not suitable for Elon Musk';
}
},
// outside of the elonMusk object
elonMusk.newMeeting = 10
console.log(elonMusk.feedBack)
这是非常基础的,关于安排会议还有很多内容,我们稍后再讨论。首先,我们来分析一下:
- 我们通过将用户提供的时间与 Elon Musk 提供的空闲时间进行比较,检查了用户提供的时间是否适合 Elon Musk。
- 如果为真,我们将时间添加到
pendingMeetings
数组中,并给出反馈。 - 如果为假,我们只需向进行此预订的用户返回反馈。
会议不应该只包含时间,伊隆·马斯克当然需要更多关于这次会议的信息,即
创建会议:
// still in the elonMusk object, just under the feedBack getter
set newMeeting(meeting) {
const { name, time, purpose } = meeting;
if (
this._hoursFree.indexOf(time) !== -1 &&
this.acceptedPurpose === 'any'
) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
} else if (this.acceptedPurpose === purpose.toLowerCase()) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
} else {
this._feedback = `${name}, this meeting is not suitable for Elon Musk`;
}
},
}
// outside of the elonMusk object
const clientMeeting = {id: 10, name: 'Bill Gates', time: 10, purpose: 'fun'};
elonMusk.newMeeting = clientMeeting;
console.log(elonMusk.feedBack);
我们只是稍微加了点料,应该不难理解。我们把 ID、名称和目的添加到时间中,构成了会议对象。
如果满足以下条件,会议将成功发送:
- 伊隆马斯克的设置
acceptedPurpose
为任意,并且如果预订用户的会议时间是hoursFree
伊隆马斯克数组中的一项。 - Elon Musk 的用途
acceptedPurpose
与预订用户提供的目的类似
现在让我们开始批准、拒绝和取消会议
批准会议:
// still in the elonMusk object, right under the newMeeting
set approveMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id; // filter out a meeting with its id and preview
})[0];
// approve previewing meeting and mark the previewingMeeting.time as a booked hour
this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings with a 'd' is the array while approveMeeting without a 'd' is the setter
this._hoursFree.splice(this._hoursFree.indexOf(previewingMeeting.time), 1);
this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
},
// outside the elonMusk object;
elonMusk.newMeeting = clientMeeting //clientMeeting already declared before, scroll up
elonMusk.approveMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
设置器approveMeeting
没有任何条件语句,因为它的目的是直奔主题:批准会议。所以这可以归因于一个“批准会议”按钮,当 Elon 点击该按钮时,会议就被批准并发送到数组approvedMeetings
。
如果会议获得批准,则意味着伊隆·马斯克的某个特定时间已被预订。为此,我们应该尽量移除该预订时间,以避免在同一时间安排两场或两场以上的会议。为此,我们使用了 splice 方法移除了该时间。您可以hoursFree
在控制台中记录当前日志以查看结果,即console.log(elonMusk.hoursFree)
拒绝会议:
// still in the elonMusk object, right under the approveMeeting
set declineMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id; // filter out a meeting with its id and preview
})[0];
this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings with a 'd' is the array while declineMeeting without a 'd' is the setter
this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to Elon Musk`;
},
// outside the elonMusk object;
elonMusk.newMeeting = clientMeeting //clientMeeting already declared before, scroll up
elonMusk.declineMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
需要注意的是,delineMeeting
设置者是埃隆·马斯克手动拒绝的,自动拒绝从未添加到pendingBookings
数组中。换句话说,添加到pendingBookings
数组中的预订是需要企业帐户所有者(现为埃隆·马斯克)审核的预订。
hoursFree
当数组和字符串中规定的时间或目的不适合 Elon Musk 时,就会自动拒绝acceptedPurpose
。
取消会议:
// still in the elonMusk object, right under the declineMeeting
set cancelMeeting(id) {
// the meeting has to be approved first
const previewingMeeting = this.approvedMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array
this._feedback = `${previewingMeeting.name}, your meeting with Elon Musk scheduled at ${previewingMeeting.time} has been canceled by Elon Musk. Don't ask me why? am not Elon Musk.`;
},
// outside the elonMusk object
elonMusk.newMeeting = clientMeeting; //clientMeeting already declared above
elonMusk.approveMeeting = clientMeeting.id; // approve meeting first
elonMusk.cancelMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
非常简单。你可以添加一个 setter 函数,用于从hoursFree
数组中删除空闲时间。如果会议取消,则该预定时间将自动被视为空闲时间;但如果 Elon Musk 不想让该时间继续空闲,他只需点击一个按钮即可(手动)删除该时间的空闲状态。
申请取消免费小时:
// still in the elonMusk object, right under the cancelMeeting
set requestHourCancelation(hr) {
if (this._hoursFree.indexOf(hr) !== -1) {
this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
}
}
// outside of the elonMusk object
elonMusk.requestHourCancelation = 10;
console.log(elonMusk.hoursFree);
伊隆·马斯克预订对象:
const elonMusk = {
_hoursFree: [10, 12, 9],
acceptedPurpose: 'family',
pendingMeetings: [], // meetings yet to be approved by Elon Musk
declinedMeetings: [], // meetings not approved by Elon Musk
approvedMeetings: [], // meetings approved by Elon Musk
canceledMeetings: [], // meetings already approved but later canceled maybe something came up
_feedback: '', // feedback to the booking user (user making the booking)
get hoursFree() {
return this._hoursFree;
},
get feedBack() {
this._feedback; // simply return a feedback.
},
set newMeeting(meeting) {
const { name, time, purpose } = meeting;
if (
this._hoursFree.indexOf(time) !== -1 &&
this.acceptedPurpose === 'any'
) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
} else if (this.acceptedPurpose === purpose.toLowerCase()) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
} else {
this._feedback = `${name}, this meeting is not suitable for Elon Musk`;
}
},
set approveMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
// approve previewing meeting and mark the previewingMeeting.time as a booked hour
this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings is the array while approveMeeting is the setter
this._hoursFree.splice(this._hoursFree.indexOf(previewingMeeting.time), 1);
this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
},
set declineMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings is the array while declineMeeting is the setter
this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to Elon Musk`;
},
set cancelMeeting(id) {
// the meeting has to be approved first
const previewingMeeting = this.approvedMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array
this._feedback = `${previewingMeeting.name}, your meeting with Elon Musk scheduled at ${previewingMeeting.time} has been canceled by Elon Musk. Don't ask me why? am not Elon Musk.`;
},
set requestHourCancelation(hr) {
if (this._hoursFree.indexOf(hr) !== -1) {
this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
}
},
};
拥有多个企业主:
假设我们希望比尔·盖茨和拉里·佩奇都拥有自己的商业账户,我们无需复制elonMusk
对象中的代码并粘贴;这完全没必要。由于elonMusk
对象中的 getter 和 setter 与其他方法类似(当然应该如此),我们只需为每个用户创建实例即可。
通常,这可以通过 JavaScript 类来实现,但这里我们不会使用类(但以后会用),而是使用我最近从Codecademy.com学到的工厂函数。
具体操作如下。
// make a function and return all properties, getters and setters in the elonMusk object
function businessUser(businessName, _hoursFree, acceptedPurpose) {
// the three parameters above are properties of this object that are going to vary with different business users
return {
businessName,
_hoursFree,
acceptedPurpose,
pendingMeetings: [], // meetings yet to be approved by Elon Musk
declinedMeetings: [], // meetings not approved by Elon Musk
approvedMeetings: [], // meetings approved by Elon Musk
canceledMeetings: [], // meetings already approved but later canceled maybe something came up
_feedback: '', // feedback to the booking user (user making the booking)
get hoursFree() {
return this._hoursFree;
},
get feedBack() {
this._feedback; // simply return a feedback.
},
set newMeeting(meeting) {
const { name, time, purpose } = meeting;
if (
this._hoursFree.indexOf(time) !== -1 &&
this.acceptedPurpose === 'any'
) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. ${this.businessName} can now review and approve or decline`;
} else if (this.acceptedPurpose === purpose.toLowerCase()) {
this.pendingMeetings.push(meeting);
this._feedback = `${name}, your meeting was sent successfully. ${this.businessName} can now review and approve or decline`;
} else {
this._feedback = `${name}, this meeting is not suitable for ${this.businessName}`;
}
},
set approveMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
// approve previewing meeting and mark the previewingMeeting.time as a booked hour
this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings is the array while approveMeeting is the setter
this._hoursFree.splice(
this._hoursFree.indexOf(previewingMeeting.time),
1
);
this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
},
set declineMeeting(id) {
const previewingMeeting = this.pendingMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings is the array while declineMeeting is the setter
this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to ${this.businessName}`;
},
set cancelMeeting(id) {
// the meeting has to be approved first
const previewingMeeting = this.approvedMeetings.filter((meeting) => {
return meeting.id === id;
})[0];
this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array
this._feedback = `${previewingMeeting.name}, your meeting with ${this.businessName} scheduled at ${previewingMeeting.time} has been canceled by ${this.businessName}. Don't ask me why? am not ${this.businessName}.`;
},
set requestHourCancelation(hr) {
if (this._hoursFree.indexOf(hr) !== -1) {
this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
}
},
};
}
businessUser 函数中的所有内容,足以创建一百万个正常运行的企业账户。让我们尝试创建三个账户并访问它们的属性。
const larryPage = businessUser('Larry Page', [15, 12, 9], 'any');
console.log(larryPage.hoursFree);
const willSmith = businessUser('Will Smith', [9, 10], 'fun');
console.log(willSmith.hoursFree);
const billGates = businessUser(
'Bill Gates',
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
'any'
); // Mr. Gates is always free.
console.log(billGates.hoursFree);
在 GitHub 上获取代码,使用 JavaScript 对象构建项目。别忘了点个星。
结论
值得注意的是,上面所有的 setter 函数都可以用方法替换,并且仍然能正常工作。不过既然我们主要讨论 setter,不妨从头到尾都用它。我打算在下一篇文章中用 JavaScript 类和方法创建一个库,它与这个完全不同,而且更高级、更有趣。一定会很有趣。
希望你和我一样学到了很多。注意,我很快就会有一个很棒的项目(一个开发者项目)给你,你一定会喜欢的。感谢阅读,如果你有任何抱怨或故事(我喜欢故事),别忘了在下方留言,也别忘了和你的同事分享。如果你想支持我,可以请我喝杯咖啡。非常感谢。
鏂囩珷鏉ユ簮锛�https://dev.to/elijahtrillionz/building-a-project-with-javascript-objects-1dn