myList = [[1]*4] * 3
создает один объект списка [1,1,1,1]
в памяти и копирует его ссылку 3 раза. Это эквивалентно obj = [1,1,1,1]; myList = [obj]*3
. Любая модификация obj
будет отражена в трех местах, где obj
упоминается в списке. Правильным утверждением будет:
myList = [[1]*4 for _ in range(3)]
или
myList = [[1 for __ in range(4)] for _ in range(3)]
. Важно отметить, что *
оператор в основном используется для создания список литералов. Поскольку 1
является литералом, значит, obj =[1]*4
создаст [1,1,1,1]
, где каждый 1
будет атомарным, а не ссылкой 1
, повторяемым 4 раза. Это означает, что если мы obj[2]=42
, то obj
станет [1,1,42,1]
не [42,42,42,42]
, как могут предположить некоторые.
Если вы хотите предоставить клиенту значение переменной с сервера, которое никогда не изменяется или не обновляется, вы можете просто добавить скрытое поле ввода в свой шаблон и добавить его значение
В своем шаблоне EJS файл будет выглядеть как
<% if (data) { %>
<input type="hidden" value="<%= data %>" id="myGlobal"/>
<% } %>
, вы должны передать значение данных в вашей функции res.render('template',{data:"hello"})
в шаблон.
Вы можете получить доступ к значению этой переменной из клиента с помощью простого document.getElementById("myGlobal")
. Снова не передавайте конфиденциальную информацию в скрытые поля.
Если вы хотите передать конфиденциальную информацию, внедрите конечную точку на вашем сервере с аутентификацией и вызовите конечную точку от клиента с помощью вызова ajax
. Это также лучший подход для обновления значения переменной со стороны клиента. [ 118]
Это похоже на запах кода ... Но, тем не менее, есть более чистые способы сделать это.
Если вы хотите представить объект данных, то есть объект, содержащий только ключи и значения, вы можете встроить его в отображаемую веб-страницу, сделать его доступным через некоторую конечную точку API, которую клиент может получить с помощью запроса AJAX, или выставить необработанный файл Javascript, который можно включить через <script>
(или, я думаю, script(...)
в pug).
Если вы хотите предоставить более сложный объект Javascript, например, класс или объект с определениями функций, вы можете открыть файл Javascript и включить его через script(...)
.
Однако, вы должны быть очень осторожно раскрывая файл, используемый сервером. Если есть какие-либо уязвимости, они теперь общедоступны. Если есть какие-либо жестко запрограммированные пароли (которых в любом случае не должно быть в коде), они теперь общедоступны. Все в этом файле теперь общедоступно, поэтому, если вы действительно хотите это сделать, будьте очень осторожны с тем, какой код попадает в этот теперь клиентский файл.
Если вам нужно больше подробностей о том, как это может работать, пожалуйста, прокомментируйте:)
Редактировать: Также имейте в виду, что использование встроенных методов и методов include не позволит обновлять переменную на лету. Если вам нужен клиент для отслеживания каких-либо изменений данных по мере их изменения на сервере, вы можете использовать AJAX. Это лучший метод, на мой взгляд. Он предлагает вам максимальную гибкость.
Другое редактирование: Судя по проблемам в проекте экспресс-выставок , он, кажется, не очень хорошо поддерживается и, возможно, имеет проблемы с безопасностью. А пока я бы этого избегал. Может быть, позже, это будет полезно и безопасно.