![](/img/trans.png)
[英]How can I access a property defined in a constructor of a class inside a method of the same class in Javascript without using this keyword?
[英]Javascript, how can I pass properties from method up to class constructor?
我正在開發一個普通的 JS / jQuery 應用程序,該應用程序從 session 存儲中獲取數據並將其顯示在瀏覽器中。 我在瀏覽器頁面上創建了一個“盒子”class,它代表一個盒子(即html卡)。 構造函數具有各種屬性,例如name: this.name
等等。
有兩種不同類型的框 - Group 和 Subject - 所以我創建了兩個子類class GroupBox extends Box
和class SubjectBox extends Box
。
這是它的設計工作方式:在初始頁面加載時,我們調用 function displayGroupBoxes
來填充新的 GroupBoxes。 function 循環遍歷 session 存儲中的一堆數據,並在循環的每次迭代中創建一個new GroupBox()
。 在 class 構造函數中備份,每次實例化一個新的 GroupBox 時,我們都會創建 HTML 標簽來顯示數據,並在頁面上顯示 append。 該 DOM 操作代碼位於GroupBox
class 方法中,該方法在 class 構造函數中調用。
還有一件事,每個 GroupBox 都有關聯的“主題”,這就是我們有 SubjectBox class 的原因。 當用戶單擊 GroupBox 時,我們會找到關聯的 SubjectBox 對象並將它們顯示在頁面上。
好的,所以一切都在這里工作,除了我遇到了一個問題。 displayGroupBoxes()
function 抓取關聯的主題並將它們傳遞回構造函數,為數據創建 HTML 標記,並將 append 標記到頁面。 當所有 DOM 操作代碼都在構造函數中時,我得到了這個工作。 然而,我收到了一位同事的代碼審查,他們說最好將 DOM 操作代碼分離到 class 方法中以提高可讀性,也就是說,它並不全部在構造函數中。 完成此操作后,我將無法再訪問從displayGroupBoxes
function 傳遞的數據。
我知道這里有很多非常特定於項目的代碼,但我希望通過這種解釋,有人可能能夠查看代碼並理解為什么我無法從 GroupBox class 訪問displayGroupBoxes
function 中的屬性方法createNewElements
。
//////////////////////////////////////////////////////////////////////////////
// CLASSES \\
//////////////////////////////////////////////////////////////////////////////
/////////////////////////
// BOX Parent Class
/////////////////////////
/**
* Represents a box.
* @constructor
* @param {object} boxOptions - An object to hold our list of constructor args
* @param {string} name - Name associated with account
* @param {string} type - Type associated with account
*/
class Box {
constructor(boxOptions) {
this.name = boxOptions.name;
this.type = boxOptions.type;
this.logo = boxOptions.logo;
}
}
/////////////////////////////
// SubjectBox SubClass
////////////////////////////
/**
* Represents a SubjectBox. These are subjects, like individual people, associated with a given group. We don't see these on initial page load. They get created (or if already created, toggled to hidden/visible) when a user clicks on a group.
*/
class SubjectBox extends Box {
constructor(subjectOptions) {
super({
name: subjectOptions.name,
type: subjectOptions.type,
logo: subjectOptions.logo,
});
this.name = subjectOptions.name;
this.type = subjectOptions.type;
this.logo = subjectOptions.logo;
this.subjectId = subjectOptions.subjectId;
this.container = document.createElement("div");
// ---> a bunch of code to create HTML tags and append to page
}
/////////////////////////
// GroupBox SubClass
/////////////////////////
/**
* Represents a GroupBox. New group boxes are instantiated when the "displayGroupBoxes()" function is called. This is what we see on initial page load.
* @constructor
* @param {object} groupOptions - An object to store our list of constructor args
* @param {array} subjectBoxes - An array to store subject boxes so that once they've been instantiated, we can store them here and then toggle to hidden/visible.
*/
class GroupBox extends Box {
constructor(groupOptions) {
super({
name: groupOptions.name,
type: groupOptions.type,
logo: groupOptions.logo,
});
// Use this array to store the subject boxes that have already been created, so if the user clicks on the same subject, we can grab those boxes and show them rather than rebuilding.
this.subjectBoxes = [];
this.name = groupOptions.name;
this.type = groupOptions.type;
this.logo = groupOptions.logo;
// Create HTML Elements and Append To Page
this.createGroupBox();
}
// Class method to create HTML tags and append to page
createGroupBox() {
// Create container div for box
const newGroupBox = document.createElement("div");
newGroupBox.className = "group-box-container";
// ----> A bunch of code here to create name and title, append to page. Now we need to display image icons of the subjects that are associated with the group:
// Container for SubjectBox Icons
const mainContainer = document.createElement("div");
mainContainer.className = "box-main-container";
// Icons
const iconsContainer = document.createElement("div");
iconsContainer.className = "box-icons-container";
// Loop through Icons object, which contains arrays of subjects, to create an img tag for each one and append to iconsContainer.
//// ------ >> this.subjectIcons is now returning undefined << \\
let icons = this.subjectIcons;
for (let i in icons) {
let iconDiv = document.createElement("div");
iconDiv.className = "box-icon-div";
let icon = document.createElement("img");
icon.src = icons[i];
icon.className = "box-icon";
iconDiv.append(icon);
iconsContainer.append(iconDiv);
mainContainer.append(iconsContainer);
i++;
}
newGroupBox.append(mainContainer);
/////////////////////////////////////////////////////////////////
// EVENT LISTENER. -- when the user clicks on a GroupBox, it runs a function to show us the subjects associated with that group
////////////////////////////////////////////////////////////////
newGroupBox.addEventListener("click", () => {
/// --> some code to hide the GroupBoxes that are already on the page so we can display SubjectBoxes instead
// build subject boxes
const boxesContainer = document.getElementById("boxes-container");
// Check to see if subject boxes have already been created. If not, instantiate the new subjectBox objects. Otherwise, if they have already been built, loop through and set them to visible
if (!this.subjectBoxes.length) {
// If subject boxes haven't been created yet, meaning if the user hasn't clicked on this group yet, map over the array of subjects passed up from the `displayGroupBoxes()` function and create a `new SubjectBox` object for each item
//! -----> groupOptions.subjects is returning undefined << \\
this.subjectBoxes = groupOptions.subjects.map((subject, i) => {
return new SubjectBox({
name: groupOptions.subjects[i].entry_text,
type: groupOptions.subjects[i].entry_type,
logo: groupOptions.subjects[i].icon_link,
subjectId: groupOptions.subjects[i].subject_id,
// Set the container for HTML
container: boxesContainer,
});
});
// Otherwise if subject boxes have already been created previously, toggle them to visible
} else {
for (const box of this.subjectBoxes) {
box.show();
}
}
// Append group box to document inside the same container we created for GroupBoxes:
// -------> groupOptions.container is returning undefined ----- \\
groupOptions.container.append(newGroupBox);
}
}
這是上面代碼塊中引用的displayGroupBoxes()
function:
// --------- Populate Group Boxes --------- \\
function displayGroupBoxes() {
// Initialize array to hold collection of group boxes
let groupBoxes = [];
// Grab the "boxes-container" div from HTML and set it to variable "boxesContainer"
const boxesContainer = document.getElementById("boxes-container");
// Loop through the data to grab all the "B" type group boxes
// Create a new GroupBox object for each item in the array
for (let arr in data) {
if (data[arr].entry_type === "B") {
// Find all "Subject" ("P") boxes associated with item and store in variable "subjectGroup". Then grab all the icon image URL's
let subjectGroup = data.filter(
(group) =>
group.group_number === data[arr].goto_group &&
group.entry_type === "P"
);
let subjectGroupIcons = [];
for (let i in subjectGroup) {
if (
subjectGroup[i].group_number === data[arr].goto_group &&
subjectGroup[i].entry_type === "P"
) {
subjectGroupIcons.push(subjectGroup[i].icon_link);
}
}
// Create new GroupBox objects
let groupBox = new GroupBox({
name: data[arr].entry_text,
type: data[arr].entry_type,
logo: data[arr].icon_link,
//! I'm not able to access these from the new "createGroupBoxes" function...
// Set the container for HTML
container: boxesContainer,
// Pass subjects to GroupBox
subjects: subjectGroup,
// Pass subject icons up to GroupBox
subjectIcons: subjectGroupIcons,
// Pass headers (e.g. "Tennis Group") up to GroupBox
headers: headerGroup,
});
// Push each groupBox object into the groupBoxes array.
// This is just for convenience so we can see all the group boxes easily if we need to.
groupBoxes.push(groupBox);
}
}
}
這里有很多東西,但希望很清楚我想要做什么。 我想將此displayGroupBoxes
function 中的container
、 subjectIcons
subjects
傳遞給 class 方法,該方法為數據創建 HTML 標記並將其附加到頁面。 當我在 class 構造函數中擁有所有 DOM 操作代碼時,這很有效,但是當我將它移到構造函數之外時,為了便於閱讀,一切正常,除了這些屬性被傳遞。 我一定是把他們叫錯了,但我不明白這個問題。
問題出在GroupBox
構造中,它僅定義名稱、類型和徽標。 您將需要在 class 定義中添加其他屬性,以便它們可用。
constructor(groupOptions) {
super({
name: groupOptions.name,
type: groupOptions.type,
logo: groupOptions.logo,
container: groupOptions.container,
subjects: groupOptions.subjects,
subjectIcons: groupOptions.subjectIcons || [],
headers: groupOptions.headers
});
根據我得到的回復在這里分享答案。 我標記為正確的答案幾乎是正確的,除了屬性不應在super()
調用中傳遞。 我需要在 class 構造函數中定義屬性,以便稍后能夠從displayGroupFunctions
向它們傳遞數據。
現在正如@Bergi 提到的,我仍然需要從構造函數外部調用 class 方法createGroupBox
,但以下代碼解決了我原來的問題:
class GroupBox extends Box {
// PARAM: groupOptions = {}
constructor(groupOptions) {
super({
name: groupOptions.name,
type: groupOptions.type,
logo: groupOptions.logo,
});
// Use this array to store the subject boxes that have already been created, so if the user clicks on the same subject, we can grab those boxes and show them rather than rebuilding.
this.subjectBoxes = [];
this.name = groupOptions.name;
this.type = groupOptions.type;
this.logo = groupOptions.logo;
-----> new code:
this.container = groupOptions.container;
this.subjects = groupOptions.subjects;
this.subjectIcons = groupOptions.subjectIcons;
this.headers = groupOptions.headers;
----> this should be called from outside the constructor
// Create HTML Elements and Append To Page
this.createGroupBox();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.