【问题标题】:Javascript Unable to access global object inside a function in an onclick eventJavascript无法在onclick事件中访问函数内的全局对象
【发布时间】:2021-11-04 19:41:33
【问题描述】:

我们有一切正常的常用示例代码。

myFunction 在 onclick 事件上触发。)

"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);
}

---输出---

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

从这个例子中,我们可以在没有任何ReferenceError的情况下访问另一个函数(在本例中为myFunction)内的全局对象obj

我试图创建单个页面 Twitter clone(仅 DOM 操作)并不断收到此错误。 Uncaught ReferenceError: Cannot access 'userData' before initialization at postMessage

---导致错误的Javascript---

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++;
}

为什么在这种情况下我会得到这个ReferenceError,而在我们的第一个示例代码中却没有?

【问题讨论】:

  • 请将无效代码放入您的问题中,而不是依赖外部链接
  • 那么为什么我们没有看到导致此错误的代码?
  • 错误信息对我来说似乎很清楚:您正试图在变量被赋值之前访问它。
  • 我已经编辑了问题。

标签: javascript onclick referenceerror


【解决方案1】:

你的代码有很多问题...

这里最大的变化是完全摆脱了generateUserhandle,并改为使用getter

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

工作演示

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2011-07-23
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多