by Kris Baillargeon
通過克里斯·拜倫
學習使用JavaScript進行面向對象編程的基礎知識(并增強您的編碼能力!) (Learn the basics of object-oriented programming with JavaScript (and supercharge your coding abilities!))
As a moderator of the freeCodeCamp chat rooms, I spend a lot of time with new developers. Boy, are they eager to learn. For a lot us, this can be quite a challenging quality.
作為freeCodeCamp聊天室的主持人,我花了很多時間在新開發人員身上 。 男孩,他們渴望學習嗎? 對于我們很多人來說,這可能是一個具有挑戰性的品質。
In the case of object-oriented programming (OOP), this rings especially true. What the heck is a method and why is it so special? What’s the difference between a method and a property? Why do we even use object-oriented programming, and why is it essential to me as a developer? These are some questions I asked myself while learning OOP, and because you’re here, it’s safe to assume that you have, too.
在面向對象編程(OOP)的情況下,尤其如此。 什么是方法,為什么它如此特別? 方法和屬性有什么區別? 為什么我們甚至使用面向對象的程序,為什么對于我作為開發人員來說這是必不可少的? 這些是我在學習OOP時問自己的一些問題,并且因為您在這里,所以可以肯定地假設您也有。
在JavaScript中使用面向對象的編程 (Using Object-Oriented Programming with JavaScript)
Almost everything in JavaScript is an object. Somewhere behind the scenes, every piece of code you write is either written or stored with OOP. That’s one of the reasons why it’s so important to understand it. If you don’t then you’ll most likely never be able to read other developers’ code. On top of that, your code will never reach its full potential!
JavaScript中的幾乎所有東西都是對象。 在幕后的某個地方,您編寫的每段代碼都是用OOP編寫或存儲的。 這就是理解它如此重要的原因之一。 如果您不這樣做,那么您極有可能永遠無法閱讀其他開發人員的代碼。 最重要的是,您的代碼將永遠無法發揮其全部潛能!
A new object is made in JavaScript by assigning a variable to two curly brackets, like this:
通過將變量分配給兩個大括號來在JavaScript中創建一個新對象,如下所示:
var myObject = {};
// var myObject = new Object(); // Non recommended version, but it works
It’s that simple! You now have an object that can store any type of data you would store in a variable. There are many ways of inserting data into an object, but we’ll stick to the easiest methods right now.
就這么簡單! 現在,您有了一個可以存儲將存儲在變量中的任何類型的數據的對象。 有多種方法可以將數據插入對象,但現在我們將堅持最簡單的方法。
快速語法課 (Quick Syntax Lesson)
To end a line in JavaScript, when making a variable like this:
在制作這樣的變量時,要在JavaScript中結束一行:
var a = 5;
var a = 5;
the “line” ends at the semicolon. When you’re making an object, the “line” will end with a comma, like so:
“行”以分號結尾。 制作對象時,“行”將以逗號結尾,如下所示:
myObject = { myProp: 5, myOtherProp: 10,}
Property/Key: The name of an object variable. An example would be
myProp
in the above code. || Left hand side of assignments屬性/鍵:對象變量的名稱。 一個例子是
myProp
在上面的代碼中。 || 作業的左側- Method : A function inside of an object, only available to that object. This is a type of property. 方法:對象內部的函數,僅對該對象可用。 這是一種屬性。
Value: The value of an object variable. An example would be 10, which is the value of
myOtherProp.
This can be any valid JavaScript datatype.值:對象變量的值。 一個例子是10,這是
myOtherProp.
的值myOtherProp.
這可以是任何有效JavaScript數據類型。
Only the last property in an object may not use a comma.
只有在一個對象中的最后一個屬性可以不使用逗號。
Note: You may enclose your properties in single or double quotes. If there is a space in the property name, you must always use quotes. When using JSON, using quotes is not optional.
注意:您可以將屬性用單引號或雙引號引起來。 如果屬性名稱中有空格,則必須始終使用引號。 使用JSON時 ,使用引號不是可選的。
引用對象屬性 (Referencing Object Properties)
點表示法 (Dot notation)
There are two ways of referencing an object, both having a name as reference. The most commonly used, dot notation, is what is primarily used. It looks like this:
有兩種引用對象的方法,兩種方法都有一個名稱作為引用。 最常用的是點符號,它是主要使用的符號。 看起來像這樣:
var myObject = {
otherObject: { one: 1, two: 2 },
addFunction: function(x,y){ return x+y }
}
var dot = myObject.otherObject;console.log(dot);//evaluates to otherObject: {..props:vals..}
The above code goes into myObject
and adds another object to it, otherObject
via dot notation. Any name that can be used as a variable is suitable for use in dot notation. Dot notation is best practice for referencing any property that doesn’t include spaces.
上面的代碼進入myObject
并向其中添加另一個對象otherObject
通過點表示法。 可以用作變量的任何名稱都適用于點表示法。 點表示法是引用任何不包含空格的屬性的最佳實踐。
括號符號 (Bracket Notation)
var myObject = { "Other Obj": { one: 1, two: 2 }}
var bracket = myObject["Other Obj"];
bracket.newProperty = "This is a new property in myObject";
console.log(bracket.newProperty);
//evaluates to myObject["Other Obj"].newProperty
The other way to reference objects is via bracket notation. This is only recommended if the object’s property contains a space, such as the property myObject[“Other Object”];
. In this case, using bracket notation is a must. When naming methods, don’t use spaces — otherwise the function can’t be called. Additionally, you can use quotes to name any property.
引用對象的另一種方法是通過括號符號。 僅當對象的屬性包含空格時才建議這樣做,例如,屬性myObject[“Other Object”];
。 在這種情況下,必須使用括號符號。 在命名方法時,請勿使用空格-否則無法調用該函數。 此外,您可以使用引號命名任何屬性。
使用JavaScript IRL (Using JavaScript IRL)
Constructor Functions are worth mentioning, as we will be making our own form of constructor functions later on in this article. To do this, we must first learn two JavaScript keywords — new and this. You use the new keyword when referring to the constructor function.
建設者 函數值得一提,因為我們將在本文的后面部分構造自己的構造函數。 要做到這一點,首先要學會兩個JavaScript關鍵字- 新 還有這個 。 引用構造函數時,請使用new關鍵字。
For the this keyword, it’s basically a fancy keyword for the last called function parent object. If it has no parent object, window will be its parent object. You can bind a function to this keyword using Function.bind(). Learn more here. But that’s a bit more advanced. Make any sense? Let’s look at some code:
對于this關鍵字,它基本上是最后一個調用函數的父對象的特殊關鍵字。 如果沒有父對象,則window將為其父對象。 您可以將功能綁定到此 使用Function.bind ()的關鍵字。 在這里了解更多。 但這有點高級。 有道理嗎? 讓我們看一些代碼:
var ConstructorForPerson = function(first, last, email) { this.firstName = first;this.lastName = last;this.fullName = first + " " + last;this.eMail = email;
}
var Bob = new ConstructorForPerson("bob", "brown", "bob122099@gmail.com");
console.log(Bob.eMail);
//evals "bob122099@gmail.com"
The above code will return a new object, Bob.
That is the result of the constructor function, which will have the properties Bob.firstName
, Bob.lastName
, Bob.fullName
, and Bob.eMail
.
上面的代碼將返回一個新對象Bob.
那是構造函數的結果,它將具有屬性Bob.firstName
, Bob.lastName
, Bob.fullName
和Bob.eMail
。
Note that inside of a constructor function, instead of ending a line with a comma, it ends with a semicolon like you would expect inside a function. Optionally, to keep things simple, you can make your own constructor functions without using new or this. That’s what we’ll be doing today so we can see all the moving pieces better.
請注意,在構造函數內部,與其以逗號結尾,不如在函數內部以分號結尾。 (可選)為使事情簡單,您可以使用自己的構造函數而無需使用new 或者這個 。 這就是我們今天要做的,因此我們可以更好地看到所有運動部件。
簡單來說 (In Simple Terms)
Object-oriented programming is a way of structuring your code for optimal readability, use, and maintenance. With this in mind, let’s try coding a representation of Google as a business, including some functions of a normal company.
面向對象的編程是一種結構化代碼以實現最佳可讀性,使用和維護的方式。 考慮到這一點,讓我們嘗試編碼Google的業務代表形式,包括普通公司的某些功能。
The Object — The Building/Management. This will contain all the information about any kind of employee, anything that can be done to an employee, including making a new one.
對象-建筑物/管理。 這將包含有關任何類型雇員的所有信息,可以對雇員進行的所有操作,包括創建新雇員。
The Properties — The Employees. This can be a manager or a desk clerk. This can be a list of employees. This can be your gross profit for this year. Pretty much anything.
屬性-員工。 這可以是經理或辦公桌文員。 這可以是員工列表。 這可以是您今年的毛利。 幾乎任何東西。
The Methods — What Can Google Do? What Can The Employees Do? This is how new employees are made, as well as how they will “perform tasks”.
方法-Google可以做什么? 員工可以做什么? 這就是新員工的培養方式以及他們“執行任務”的方式。
讓我們編碼! (Let’s Code!)
First, let’s look at our end result:
首先,讓我們看一下最終結果:
var google = { //create {google}
employees: { management: { },
developers: { },
maintenance: { } }, NewEmployee: function(name, role, phone, idNumber) { //create NewExployee() var newEmployeeData = { name: name, role: role, phone: phone, idNumber: idNumber, working: false, hours: [], } //make new object to append to google.employees[role] google.employees[role][name] = newEmployeeData; //assign object to google.employees[role][name]
return google.employees[role][name]; //return the new object directly from google.employees[role][name] } //end NewEmployee } //end {google}
google.NewEmployee("james", "maintenance", "2035555555", "1234521"); //create {google:employees:maintenance["james"]} from NewEmployee()
google.employees["maintenance"]["james"].clockInOut = function() { //create clockInOut() - default false if(this.working) { this.hours[this.hours.length - 1].push(Date.now()); this.working = false; return this.name + " clocked out at " + Date.now(); } else{ this.hours.push([Date.now()]); this.working = true; return this.name + " clocked in at " + Date.now(); }
return "Error" //if above doesn't work, "Error" }
google.employees["maintenance"]["james"].clockInOut(); //clock James in or out, returns a string w/ the time & state
Daunting?
令人生畏的?
Let’s break it down into smaller pieces. To start, we’ll make a global object called Google
. It will contain another object for employees, which will contain more objects for each role and its individual employees.
讓我們將其分解為較小的部分。 首先,我們將創建一個名為Google
的全局對象。 它將為員工包含另一個對象,該對象將為每個角色及其單個員工包含更多對象。
So what will this look like in code? For the sake of keeping things easy, we’re going to make a constructor using a normal function. It will have 7 properties: name
, role,
phone
, idNumber
, working
, and hours
.
那么這在代碼中會是什么樣? 為了使事情變得簡單,我們將構造一個構造函數 使用正常功能。 它將具有7個屬性: name
, role,
phone
, idNumber
, working
, 和hours
。
In addition, it will have 1 method: clockInOut(),
which will look at the working
property to update hours.
此外,它將有1個方法: clockInOut(),
它將查看working
屬性以更新hours.
Let’s break it down.
讓我們分解一下。
First, we’re going to update our Google
object with the NewEmployee()
constructor function. Remember, instead of using the regular JavaScript constructor function, we’ll be using our own.
首先,我們將使用NewEmployee()
構造函數更新Google
對象。 請記住,我們將使用自己JavaScript而不是常規JavaScript構造函數。
Note: Pay attention to syntax as it will switch around a bit depending on what you’re doing
注意:請注意語法,因為語法會根據您的操作而有所變化
Also note: These examples will not run properly as they do not have the correct dependencies/properties/variables. Most if not all functionality from the final product will return an error. If you run the final product, however, everything should work fine.
另請注意:這些示例將不正確運行,因為它們沒有正確的依賴關系/屬性/變量。 最終產品的大多數功能(如果不是全部功能)將返回錯誤。 但是,如果您運行最終產品,則一切都會正常運行。
var google = { //create {google}
employees: { management: {
}, developers: {
},
maintenance: {
} }, //<--this comma is unnecessary right now but when we add more object properties it will be necessary}
employees
holds other objects which are various roles in the company: management
, developers
, and maintenance
. We will be adding an employee via the employee’s role, in this case, maintenance.
employees
還擁有公司中其他各種角色: management
, developers
和maintenance
。 我們將通過員工角色(在這種情況下為維護)來添加員工。
var google = { NewEmployee: function(name, role, phone, idNumber) { var newEmployeeData = { name: name, role: role, phone: phone, idNumber: idNumber, working: false, hours: [], } //make new object to append to google.employees[role] google.employees[role][name] = newEmployeeData; //assign object to google.employees[role][name]
return google.employees[role][name]; //return the new object directly from google.employees[role][name] }}
Our “constructor” function”. Pretty straightforward, it takes a new object and appends it to the corresponding role.
我們的“構造函數”。 非常簡單,它需要一個新對象并將其附加到相應的角色。
google.employees["maintenance"]["james"].clockInOut = function() { //create clockInOut() - default false if(this.working) { this.hours[this.hours.length - 1].push(Date.now()); this.working = false; return this.name + " clocked out at " + Date.now(); } else{ this.hours.push([Date.now()]); this.working = true; return this.name + " clocked in at " + Date.now(); }
return "Error" //if above doesn't work, "Error" }
google.employees["maintenance"]["james"].clockInOut(); //call clockInOut()
This is where it might get confusing. Remember that the keyword this is just a funny way to say the calling function’s parent object? In the above, we add the method clockInOut()
to our code. We invoke it simply by calling it. If working is false, it will create a new array with a Unix timestamp at index 0. If you’re already working, it will just append a Unix timestamp to the last created array, creating an array that looks kind of like this: [1518491647421, 1518491668453] with the first timestamp being when the employee “clocks in”, the second being when the employee “clocks out”.
這可能會使您感到困惑。 請記住,關鍵字this 說調用函數的父對象只是一種有趣的方式? 在上面的代碼中,我們將方法clockInOut ()
添加到了代碼中。 我們只需調用它即可調用它。 如果work為false,它將創建一個帶有Unix時間戳索引為0的新數組。如果您已經在工作,它將Unix時間戳附加到最后創建的數組,從而創建一個看起來像這樣的數組:[ 1518491647421、1518491668453],第一個時間戳是員工“進門”的時間,第二個時間戳是員工“進門”的時間。
Now we’ve seen how using OOP can be practical! Each individual employee can “clock in” and “clock out” with a simple function call, and all you have to know is their name and role!
現在我們已經看到了使用OOP的實用性! 每個員工都可以通過一個簡單的函數調用“撥入”和“撥出”,您只需要知道他們的名字和角色!
This can, of course, be optimized to do something like look at an ID number instead of their role and name, but let’s not over-complicate things. Below we bring everything back into one program. Slightly less scary, right?
當然,可以對此進行優化,以執行類似于查看ID號的操作,而不是查看其角色和名稱,但是我們不要使事情復雜化。 下面,我們將所有內容重新整合到一個程序中。 有點嚇人吧?
var google = { //create {google}
employees: { management: { }, developers: { },
maintenance: { } }, NewEmployee: function(name, role, phone, idNumber) { //create NewExployee() var newEmployeeData = { name: name, role: role, phone: phone, idNumber: idNumber, working: false, hours: [], } //make new object to append to google.employees[role] google.employees[role][name] = newEmployeeData; //assign object to google.employees[role][name]
return google.employees[role][name]; //return the new object directly from google.employees[role][name] }//end NewEmployee } //end {google}
google.NewEmployee("james", "maintenance", "2035555555", "1234521"); //create {google:employees:maintenance["james"]} from NewEmployee()
google.employees["maintenance"]["james"].clockInOut = function() { //create clockInOut() - default false if(this.working) { this.hours[this.hours.length - 1].push(Date.now()); this.working = false; return this.name + " clocked out at " + Date.now(); } else{ this.hours.push([Date.now()]); this.working = true; return this.name + " clocked in at " + Date.now(); }
return "Error" //if above doesn't work, "Error" }
google.employees["maintenance"]["james"].clockInOut(); //call clockInOut()
Using Object Oriented Programming can not only make your code more powerful, but also much more readable to other developers. Feel free to contact me through Github for projects, Free Code Camp info, Javascript/HTML/CSS help, to encourage me to write a tutorial on using JSON and APIS, or to talk about cats!
使用面向對象的編程不僅可以使您的代碼更強大,而且對其他開發人員也更具可讀性。 請隨時通過Github與我聯系以獲取項目, 免費的代碼營信息,Javascript / HTML / CSS幫助,鼓勵我編寫有關使用JSON和APIS的教程或談論貓!
By the way, if you didn’t know, everything taught in this tutorial as well as ANYTHING you need to know about vanilla Javascript, HTML, CSS and more, you can count on MDN to have an extensive amount of knowledge on it. It’s basically Google for web developers! It’s also 1220% free and open source.
順便說一句,如果您不知道本教程中教授的所有內容以及有關原始Javascript,HTML,CSS等的任何知識,則可以依靠MDN來獲得大量的知識。 基本上是面向網絡開發人員的Google! 它還是1220%的免費開放源代碼。
Don’t forget to clap & follow if you enjoyed! More articles coming soon! :)
如果您喜歡的話,別忘了拍手跟著! 更多文章即將推出! :)
Keep up with me on Instagram @krux.io
跟我上Instagram @ krux.io
FURTHER LEARNING ON MDN:
關于MDN的進一步學習:
OOP FOR BEGINNERS
適合初學者
GLOBAL OBJECTS
全球對象
JSON TUTORIAL
JSON教程
USING JSON IN JAVASCRIPT — GLOBAL JSON OBJECT
在JAVASCRIPT中使用JSON —全局JSON對象
KEYWORD THIS
關鍵字this
CONSTRUCTOR FUNCTIONS
構造函數
翻譯自: https://www.freecodecamp.org/news/intro-to-object-oriented-programming-oop-with-javascript-made-easy-a317b87d6943/