# 章節導航
[TOC]
### [介紹](https://www.theodinproject.com/courses/javascript/lessons/objects-and-object-constructors#introduction)
在我們的JavaScript基礎課程中,您應該已經學習了[使用對象](https://www.theodinproject.com/courses/web-development-101/lessons/fundamentals-part-5)來存儲和檢索數據的[基礎知識](https://www.theodinproject.com/courses/web-development-101/lessons/fundamentals-part-5)。讓我們先來回顧一下吧。
有多種方法可以定義對象,但在大多數情況下,最好使用**對象文字**語法,如下所示:
~~~javascript
const myObject = {
property: 'Value!',
otherProperty: 77,
"obnoxious property": function() {
// do stuff!
}
}
~~~
還有兩種方法可以從對象中獲取信息:點表示法和括號表示法。
~~~javascript
// dot notation
myObject.property // 'Value!'
// bracket notation
myObject["obnoxious property"] // [Function]
~~~
您使用哪種方法取決于上下文。點符號更清晰,通常是首選,但有很多情況下無法使用它。例如,`myObject."obnoxious property"`將無法工作,因為該屬性是一個包含空格的字符串。同樣,您不能在點表示法中使用變量:
~~~javascript
const variable = 'property'
myObject.variable // this gives us 'undefined' because it's literally looking for a property named 'variable' in our object
myObject[variable] // 'Value!'
~~~
如果您對使用對象感到生氣,現在可能是回顧并查看我們的JavaScript 101課程中[**基礎5中**](https://www.theodinproject.com/courses/web-development-101/lessons/fundamentals-part-5)的內容的好時機。
### [對象作為設計模式](https://www.theodinproject.com/courses/javascript/lessons/objects-and-object-constructors#objects-as-a-design-pattern)
您可以開始組織代碼的最簡單方法之一是將事物分組到對象中。從“tic tac toe”游戲中獲取這些示例:
~~~javascript
// example one
const playerOneName = "tim"
const playerTwoName = "jenn"
const playerOneMarker = "X"
const playerTwoMarker = "O"
// example two
const playerOne = {
name: "tim",
marker: "X"
}
const playerTwo = {
name: "jenn",
marker: "O"
}
~~~
乍一看,第一個看起來并不那么糟糕......它實際上比使用對象的示例需要更少的行,但好處是巨大的!讓我來證明:
~~~javascript
function printName(player) {
console.log(player.name)
}
~~~
這是您在示例一設置時無法做到的事情。相反,每次你想要打印特定玩家的名字時,你必須記住正確的變量名,然后手動輸入`console.log`:
~~~javascript
console.log(playerOneName)
console.log(playerTwoName)
~~~
再說一次,這并不是*那么*糟糕......但如果你*不知道*你想要打印哪個球員的名字怎么辦?
~~~javascript
function gameOver(winningPlayer){
console.log("Congratulations!")
console.log(winningPlayer.name + " is the winner!")
}
~~~
或者,如果我們不是制作2人游戲,而是更復雜的東西,例如具有大量庫存的在線購物網站,該怎么辦?在這種情況下,使用對象來跟蹤項目的名稱,價格,描述和其他事情是唯一的方法。不幸的是,在那種情況下手動輸入我們對象的內容也是不可行的。我們需要一種更清潔的方式來創建我們的對象,這將我們帶到......
### [對象構造函數](https://www.theodinproject.com/courses/javascript/lessons/objects-and-object-constructors#object-constructors)
如果您需要像我們的播放器或庫存項目那樣復制特定類型的對象,則創建它們的更好方法是使用對象構造函數,該函數看起來像這樣:
~~~javascript
function Player(name, marker) {
this.name = name
this.marker = marker
}
~~~
通過使用關鍵字調用函數來使用它`new`。
~~~javascript
const player = new Player('steve', 'X')
console.log(player.name) // 'steve'
~~~
就像使用Object Literal方法創建的對象一樣,您可以向對象添加函數:
~~~javascript
function Player(name, marker) {
this.name = name
this.marker = marker
this.sayName = function() {
console.log(name)
}
}
const player1 = new Player('steve', 'X')
const player2 = new Player('also steve', 'O')
player1.sayName() // logs 'steve'
player2.sayName() // logs 'also steve'
~~~
### [行使](https://www.theodinproject.com/courses/javascript/lessons/objects-and-object-constructors#exercise)
編寫一個用于制作“book”對象的構造函數。我們將在本課結束時重新審視這個項目。你的書的對象應該有這本書的`title`,`author`,數量`pages`,以及你是否有`read`這本書
將函數放入可以報告書籍信息的構造函數中
~~~javascript
book.info() // "The Hobbit by J.R.R. Tolkien, 295 pages, not read yet"
~~~
注意:幾乎*總是*最好的`return`事情,而不是`console.log()`直接進入功能。在這種情況下,返回`info`字符串并在調用函數后記錄它:
~~~javascript
console.log(theHobbit.info());
~~~
### [原型](https://www.theodinproject.com/courses/javascript/lessons/objects-and-object-constructors#the-prototype)
在我們進一步深入研究之前,您需要了解有關JavaScript對象的重要信息。JavaScript中的所有對象都有`prototype`。簡單地說,原型是原始對象*繼承的*另一個對象,也就是說,原始對象可以訪問其原型的所有方法和屬性。
這個概念很重要,所以你有一些閱讀要做。在繼續之前確保你真的得到了這個!
1. [本文](http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/)是對該概念的直接介紹和演示。它還包括施工人員..審查的好時機!這里的重要部分,一旦你涵蓋了基礎知識,就是'基于原型的繼承'和'原型鏈'
2. 要更深入地了解鏈和繼承,花一些時間來閱讀[這篇偉大的文章](http://javascript.info/prototype-inheritance)。像往常一樣,最后做練習將有助于鞏固你的思想。不要跳過它們!重要提示:本文`__proto__`一般不推薦大量使用。這里的概念是我們目前正在尋找的。我們很快將學習另一種方法來設置原型。
如果您已經理解了原型的概念,那么關于構造函數的下一部分將不會讓人感到困惑!
~~~javascript
function Student(name) {
this.name = name
this.grade = grade
}
Student.prototype.sayName = function() {
console.log(this.name)
}
Student.prototype.goToProm = function() {
// eh.. go to prom?
}
~~~
如果您正在使用構造函數來創建對象,則最好在該`prototype`對象上定義函數。這樣做意味著將在所有Student對象之間共享每個函數的單個實例。如果我們在構造函數中直接聲明函數,就像我們在第一次引入它時所做的那樣,每次創建一個新學生時,該函數都會被復制。在這個例子中,這并不重要,但在一個創建數千個對象的項目中,它確實可以產生影響。
#### 推薦的原型繼承方法
到目前為止,您已經看到了幾種使對象從另一個對象繼承原型的方法。在歷史的這一點上,建議設置對象原型的方法是`Object.create`([這里](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)是該方法的文檔。)`Object.create`非常簡單地返回一個具有指定原型的新對象以及要添加的任何其他屬性。出于我們的目的,您可以這樣使用它:
~~~javascript
function Student() {
}
Student.prototype.sayName = function() {
console.log(this.name)
}
function EighthGrader(name) {
this.name = name
this.grade = 8
}
EighthGrader.prototype = Object.create(Student.prototype)
const carl = new EighthGrader("carl")
carl.sayName() // console.logs "carl"
carl.grade // 8
~~~
你可以弄清楚這里發生了什么。在為EighthGrader創建構造函數之后,我們將它的原型設置為一個具有副本的新對象`Student.prototype`。
警告......這不起作用:
~~~javascript
EighthGrader.prototype = Student.prototype
~~~
因為它會將EighthGrader的原型設置為Student.prototype(即不是副本),如果您想在將來編輯某些內容,可能會導致問題。再考慮一個例子:
~~~javascript
function Student() {
}
Student.prototype.sayName = function() {
console.log(this.name)
}
function EighthGrader(name) {
this.name = name
this.grade = 8
}
// don't do this!!!
EighthGrader.prototype = Student.prototype
function NinthGrader(name) {
this.name = name
this.grade = 9
}
// noooo! not again!
NinthGrader.prototype = Student.prototype
NinthGrader.prototype.sayName = function() {console.log("HAHAHAHAHAHA")}
const carl = new EighthGrader("carl")
carl.sayName() //uh oh! this logs "HAHAHAHAHAHA" because we edited the sayName function!
~~~
如果我們`Object.create`在這個例子中使用過那么我們可以安全地編輯`NinthGrader.prototype.sayName`函數而不改變函數`EighthGrader`。
- 前言
- 你真的懂This嗎?
- 對象和對象構造函數
- 工廠功能和模塊模式
- API的使用
- async and await
- 關于async的很棒的一篇文章
- 掘金:關于forEach,map,fiter循環操作
- Node.js 實例與基礎
- 原創: Express 學習使用筆記
- 零碎知識點方法
- 關于滾動吸頂的方法
- Vue學習筆記
- Vue向導
- vuex是啥?
- vue代碼風格指南
- 關于vue的初體驗
- 超詳細解毒Vue
- Vue實例
- 模版語言
- 組件基礎
- 條件渲染、列表渲染、Class與style綁定
- Todolist的制作超詳細
- vue-router
- Vue基礎2.0x 筆記
- 搭建vuepress
- JavaScript之ES6
- 箭頭函數
- 這就是This