简体   繁体   中英

Javascript Unable to access global object inside a function in an onclick event

We have the usual example code where everything works.

( myFunction gets triggered on an onclick event.)

"use strict";
console.clear();

const obj = {
    name: "falana",
    count: 0
};

function myFunction() {
    obj.count++;
    console.log(obj.count);
    console.log(obj.name);
    console.log(obj);
}

---Output---

1
"falana"
// [object Object] 
{
  "name": "falana",
  "count": 1
}

From this example, we can access a global object obj inside another function (in this case, myFunction ) without any ReferenceError .

I was trying to create a single page Twitter clone (only DOM manipulation) and kept getting this error. Uncaught ReferenceError: Cannot access 'userData' before initialization at postMessage

---Javascript that's causing error---

window.onload = function() {
  console.clear();
}

const userData = {
  username: 'Chinmay Ghule',
  userhandle: generateUserhandle(this.username),
  userPostCount: 0
};

function generateUserhandle(userData) {
  const usernameArr = userData.username.split(" ");
  usernameArr.forEach(element => {
    element.toLowerCase();
  });

  return "@" + usernameArr.join("");
}

// posts message entered in #message-text to
// message-output-container.
function postMessage() {

  console.log(userData);

  // get message from #message-text.
  const message = document.getElementById('message-text').value;
  console.log(`message: ${message}`);

  // check for length.
  console.log(`message length: ${message.length}`);
  if (message.length === 0) {
    return;
  }

  // create new div.
  const card = document.createElement('div');
  const userInfo = document.createElement('div');
  const userMessage = document.createElement('div');

  const usernameSpan = document.createElement('span');
  const userhandleSpan = document.createElement('span');
  const beforeTimeDotSpan = document.createElement('span');
  const timeSpan = document.createElement('span');

  usernameSpan.classList.add('username');
  userhandleSpan.classList.add('userhandle');
  beforeTimeDotSpan.classList.add('before-time-dot');
  timeSpan.classList.add('time');

  userInfo.appendChild(usernameSpan);
  userInfo.appendChild(userhandleSpan);
  userInfo.appendChild(beforeTimeDotSpan);
  userInfo.appendChild(timeSpan);

  console.log(`userInfo : ${userInfo}`);

  userInfo.classList.add('user-info');
  userMessage.classList.add('output-message');

  card.appendChild(userInfo);
  card.appendChild(userMessage);

  console.log(`card : ${card}`);

  card.classList.add('output-message');

  userMessage.innerText = message;

  // check for number of posts.
  if (userData.userPostCount === 0) {
    let noMessageDiv = document.getElementById("no-message-display");

    noMessageDiv.remove();
  }

  // append new div.
  const messageOutputContainer = document.getElementById('message-output-container');

  messageOutputContainer.appendChild(card);

  // increment userPostCount.
  userData.userPostCount++;
}

Why am i getting this ReferenceError in this case, while it didn't in our first example code?

Your code had quite some issues...

The biggest change here was getting rid of generateUserhandle entirely and making it with a getter .

  get userhandle() {
    return this.username.toLowerCase()
  },

Working demo

 window.onload = function() { console.clear(); } const userData = { username: 'Chinmay Ghule', get userhandle() { return this.username.toLowerCase() }, userPostCount: 0 }; // posts message entered in #message-text to // message-output-container. function postMessage() { console.log(userData); // get message from #message-text. const message = document.getElementById('message-text').value; console.log(`message: ${message}`); // check for length. console.log(`message length: ${message.length}`); if (message.length === 0) { return; } // create new div. const card = document.createElement('div'); const userInfo = document.createElement('div'); const userMessage = document.createElement('div'); const usernameSpan = document.createElement('span'); const userhandleSpan = document.createElement('span'); const beforeTimeDotSpan = document.createElement('span'); const timeSpan = document.createElement('span'); usernameSpan.classList.add('username'); userhandleSpan.classList.add('userhandle'); beforeTimeDotSpan.classList.add('before-time-dot'); timeSpan.classList.add('time'); userInfo.appendChild(usernameSpan); userInfo.appendChild(userhandleSpan); userInfo.appendChild(beforeTimeDotSpan); userInfo.appendChild(timeSpan); console.log(`userInfo : ${userInfo}`); userInfo.classList.add('user-info'); userMessage.classList.add('output-message'); card.appendChild(userInfo); card.appendChild(userMessage); console.log(`card : ${card}`); card.classList.add('output-message'); userMessage.innerText = message; // check for number of posts. if (userData.userPostCount === 0) { let noMessageDiv = document.getElementById("no-message-display"); noMessageDiv.remove(); } // append new div. const messageOutputContainer = document.getElementById('message-output-container'); messageOutputContainer.appendChild(card); // increment userPostCount. userData.userPostCount++; }
 *, *::before, *::after { box-sizing: border-box; } body { margin: 0px; padding: 0px; font-family: Arial, Helvetica, sans-serif; } #container { /*background-color: lightskyblue;*/ margin: 2.5rem 25%; } #user-info { /*background-color: orange;*/ padding-bottom: 0.5rem; } .username { font-weight: bold; } .userhandle, .before-time-dot, .time { opacity: 0.75; } #message-text { width: 100%; margin-bottom: 0.5rem; font-size: 18px; padding: 0.5rem; resize: none; border-radius: 0.5rem; outline: 1px solid lightgray; } #message-button { float: right; padding: 0.375rem 1.5rem; font-weight: bold; font-size: 18px; border-radius: 1rem; } #message-button:hover { background-color: lightgray; } #message-input-container { background-color: lightskyblue; padding: 1rem; border-radius: 0.5rem; } #message-input-container::after { content: ""; clear: both; display: table; } #message-output-container { /*background-color: lightskyblue;*/ margin-top: 30px; border-top: 3px solid black; } #no-message-display { text-align: center; padding: 0.5rem; } .output-message { padding: 0.5rem; font-size: 18px; border-bottom: 1px solid lightgray; }
 <div id="container"> <div id="message-input-container"> <textarea id="message-text" rows="5" placeholder="Type your message here..." contenteditable="" value=""></textarea> <input id="message-button" type="button" value="Post" onclick="postMessage();" /> </div> <div id="message-output-container"> <div id="no-message-display"> <span>No messages yet!</span> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM