如何在函数外部使用函数的声明变量但将它们的值保留在 javascript 中?

Posted

技术标签:

【中文标题】如何在函数外部使用函数的声明变量但将它们的值保留在 javascript 中?【英文标题】:How can I use declared variables of a function outside the function but keeping their values in javascript? 【发布时间】:2021-05-08 09:46:39 【问题描述】:

我有这个对象数组

const GALLERY = [

    color: "red",
    titulo: "Stuff"
,

    color: "pink",
    titulo: "Thing"
,

    color: "green",
    titulo: "Something"

];

以及这些带有模板字面量的函数

function galTemplate(gal) 
    let modalBtn = gal.color + "-btn";
    return `
    <div class="content-entry" id="$modalBtn">
        <div href="" style="background-color: $gal.color;"></div>
        <p class="gallery-entry-titulo">$gal.titulo</p>
    </div>
    `


function galModal(modal) 
    let modalModal = modal.color + "-modal";
    return `
    <div class="popup-bg" id="$modalModal">
      <div class="entry-popup">
        <div style="background-color: $modal.color;></div>
      </div>
    </div>
    `

情况是我想使用变量 modalBtn 和 modaModal 及其值来创建一个看起来像这样的简单模态函数

modalBtn.onclick = function() 
    modalModal.style.display = "block";

当然,这是一个真实项目的例子。 这是完整示例中的Codepen,以便更好地理解

【问题讨论】:

模板文字实际上只是字符串。 【参考方案1】:

javascript 中,我们有一个叫做 Global Variables 的东西。我们可以利用这个类似于下面的代码:

let global_var;
function set_var()
    global_var = "Hello"

set_var();
console.log(global_var);

【讨论】:

是的,已经尝试过并且还给出了未定义的值,但在这种情况下不起作用。还是谢谢你【参考方案2】:

变量

您可以使用关键字var 在函数范围之外声明变量,如下所示:

var my_global = 1;
function do_something_with_global() 
    console.log(my_global++);

do_something_with_global(); // will print: 1
console.log(my_global); // will print: 2

它们将生活在全球空间中,因此您可以从任何地方访问它们。这通常是一个糟糕的设计选择,因为这些东西不会被垃圾收集(在函数范围内,一旦执行,内存就会被释放)。

此外,现在可以从任何地方修改全局变量,所以您也不希望这样。如果您不小心覆盖了变量,也可能会出现难以发现的错误。

请注意这一点。您可能还想在这里阅读:https://www.w3.org/wiki/JavaScript_best_practices

根据您的目标可能的解决方案

我可能会选择一种不同的方式来创建元素并一次性渲染它们(即createElement(),然后依次添加侦听器和模态)。

但是,我想尽可能少地进行更改,以便您可以更轻松地使用它。

您可以也可能应该只切换 CSS 类,而不是修改单个属性。

以下内容如何:

const GALLERY = [
    color: 'red',
    titulo: 'Stuff'
  ,
  
    color: 'pink',
    titulo: 'Thing'
  ,
  
    color: 'green',
    titulo: 'Something'
  
];

function galTemplate(gal) 
  let modalBtn = gal.color + '-btn';
  return `
    <div class="content-entry" id="$modalBtn">
        <div href="" style="background-color: $gal.color;"></div>
        <p class="gallery-entry-titulo">$gal.titulo</p>
    </div>
    `;


function galModal(modal) 
  let modalModal = modal.color + '-modal';
  return `
    <div class="popup-bg" id="$modalModal">
      <div class="entry-popup">
        <div style="background-color: $modal.color;"></div>
      </div>
    </div>
    `;


function addClickListeners(gal) 
  let btnId = gal.color + '-btn';
  let modalId = gal.color + '-modal';
  let elBtn = document.getElementById(btnId);
  let elModal = document.getElementById(modalId);
  elBtn.onclick = function() 
    console.log('click: btn: ' + this.id + ', modal: ' + elModal.id);
    elModal.classList.toggle('show-popup');
  
  /* to dispose the popup on click */
  elModal.onclick = function() 
    this.classList.toggle('show-popup');
  
  /* --- */


document.getElementById("my-content").innerhtml = `
  <div class="content">
    $GALLERY.map(galTemplate).join('')
  </div>
  $GALLERY.map(galModal).join('')
`;
GALLERY.map(addClickListeners);
body 
  background: #01235f;
  color: white;


.content 
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-gap: 0px;
  grid-auto-rows: 1fr;


.content-entry 
  width: 150px;
  height: 150px;
  position: relative;
  cursor: pointer;


.content-entry div 
  width: 100%;
  height: 100%;


.gallery-entry-titulo 
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translate(-50%, -30%);
  cursor: pointer;


.popup-bg 
  display: none;
  position: fixed;
  z-index: 3;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(5px);


.show-popup 
  display: block;


.entry-popup 
  position: absolute;
  z-index: 9;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  width: 50%;
  height: 80%;
  overflow: auto;
  background-color: rgba(0, 0, 0, 0.4);
  padding: 60px;


.entry-popup div 
  width: 100%;
  height: 100%;
  margin: 20px auto;
&lt;div class="content" id="my-content"&gt;&lt;/div&gt;

【讨论】:

好的,这接近我想要实现的目标,但由于某种原因,只有第一个元素激活了模态,粉色和绿色没有。 @AfxCrush 是的,但是点击有效。从控制台查看日志。问题出在不同的地方。 @AfxCrush 当您检查 DOM 时,您可以看到模式处于父子关系,换句话说,它们是嵌套的。如果你修复了 DOM,我想它应该可以正常工作。 @AfxCrush 您忘记关闭报价...这导致 html 提前关闭了 div,因此它堆叠起来。我修复了它并编辑了我的解决方案。 非常感谢您的帮助。非常感谢

以上是关于如何在函数外部使用函数的声明变量但将它们的值保留在 javascript 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改指针变量的值并将更改保留在函数之外而无需通过引用传递?

Python—闭包

Python全栈之路----函数进阶----闭包

如何理解函数中的指针

python闭包

static修饰的局部变量在函数外不可访问对吗?