Как изменение разрешений символической ссылки в системе Linux не изменяет разрешения ссылки, а вместо этого указывает файл (в Ubuntu как минимум). Я думаю, что самым безопасным способом для этого было бы удалить ссылку и воссоздать ее с требуемой umask, чтобы получить желаемый результат.
Другую связанную запись можно найти , изменяя разрешения symlink в системе Linux
Вот пример, чтобы добавить к тому, что уже писали другие. Предположим, вы хотите создать массив функций adderFunctions, где каждая функция принимает один аргумент Number и возвращает сумму аргумента и индекс функции в массиве. Попытка сгенерировать adderFunctions с помощью цикла с использованием ключевого слова var не будет работать так, как можно было бы наивно ожидать:
// An array of adder functions.
var adderFunctions = [];
for (var i = 0; i < 1000; i++) {
// We want the function at index i to add the index to its argument.
adderFunctions[i] = function(x) {
// What is i bound to here?
return x + i;
};
}
var add12 = adderFunctions[12];
// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000
// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true
Вышеописанный процесс не генерирует желаемый массив функций, потому что i выходит за пределы итерации блока for, в котором была создана каждая функция. Вместо этого в конце цикла i в закрытии каждой функции ссылается на значение i в конце цикла (1000) для каждой анонимной функции в adderFunctions. Это совсем не то, чего мы хотели: теперь у нас есть массив из 1000 различных функций в памяти с точно таким же поведением. И если мы впоследствии обновим значение i, мутация повлияет на все adderFunctions.
Однако мы можем попробовать снова с помощью ключевого слова let:
// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];
for (let i = 0; i < 1000; i++) {
// NOTE: We're using the newer arrow function syntax this time, but
// using the "function(x) { ..." syntax from the previous example
// here would not change the behavior shown.
adderFunctions[i] = x => x + i;
}
const add12 = adderFunctions[12];
// Yay! The behavior is as expected.
console.log(add12(8) === 20); // => true
// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined
На этот раз i отскок на каждой итерации петли for. Каждая функция теперь сохраняет значение i во время создания функции, а adderFunctions ведет себя как ожидалось.
Теперь изображение смешивает два поведения, и вы, вероятно, увидите, почему это не рекомендуется для смешивания новых let и const со старым var в том же скрипте. Это может привести к некоторому эффектно запутанному коду.
const doubleAdderFunctions = [];
for (var i = 0; i < 1000; i++) {
const j = i;
doubleAdderFunctions[i] = x => x + i + j;
}
const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];
// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
Не позволяйте этому случиться с вами. Используйте linter.
ПРИМЕЧАНИЕ. Это пример обучения, предназначенный для демонстрации поведения var / let в циклах и закрытия функций, которые также будут легко понятны. Это был бы ужасный способ добавить числа. Но общая техника захвата данных при закрытии анонимных функций может встречаться в реальном мире в других контекстах. YMMV.Вот объяснение ключевого слова let с некоторыми примерами.
let работает очень похоже на var. Основное отличие состоит в том, что область действия переменной var представляет собой всю закрывающую функциюобъяснение ключевого слова let в Википедии показывает, какие браузеры поддерживают Javascript 1.7.
Обратите внимание, что поддерживаются только браузеры Mozilla и Chrome. IE, Safari и, возможно, другие нет.
Основное различие заключается в различии областей, в то время как let может быть доступен только в пределах объявленной области, например, в for for, к примеру, var может быть доступен вне цикла. Из документации в MDN (примеры также из MDN):
let позволяет объявлять переменные, которые ограничены в объеме блоком, оператором или выражением, на котором оно используется. Это не похоже на ключевое слово var, которое определяет переменную глобально или локально для целой функции независимо от области блока. Переменные, объявленные let, имеют в качестве своей области действия блок, в котором они определены, а также в любых содержащихся подблоках. Таким образом, пусть работает очень похоже на var. Основное различие заключается в том, что область переменной var является всей охватывающей функцией:function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}`
let позволяет объявлять переменные, которые ограничены по объему блоку, выражению или выражению на который он используется. Это не похоже на ключевое слово var, которое определяет переменную глобально или локально для целой функции независимо от области блока.
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
При использовании внутри блока, ограничивает область переменной это блок. Обратите внимание на разницу между let , область видимости которой находится внутри функции, где она объявлена. var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2
На верхнем уровне программ и функций пусть, в отличие от var, не создает свойство для глобального объекта. Например:
При использовании let
Ключевое слово let прикрепляет объявление переменной к какому-либо блоку (обычно к паре { .. }), в котором оно содержится. Другими словами, let неявно захватывает область любого блока для его объявления переменной.
let переменные не могут быть доступны в объекте window, потому что они не могут быть глобально доступны.
function a(){
{ // this is the Max Scope for let variable
let x = 12;
}
console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined
Когда Использование let
var и переменных в ES5 имеет области действия, означающие, что переменные действительны внутри функции, а не вне самой функции.
var могут быть доступны в объекте window, потому что они не могут быть глобально доступны.
function a(){ // this is the Max Scope for var variable
{
var x = 12;
}
console.log(x);
}
a(); // 12
Если вы хотите узнать больше, продолжайте читать ниже
одно из самых известных интервью вопросы по сфере охвата также могут быть достаточными для точного использования let и var, как показано ниже:
Если вы хотите узнать больше продолжить чтение ниже
for (let i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 0 to 9, that is literally AWW!!!
},
100 * i);
}
Это связано с тем, что при использовании let для каждой итерации цикла переменная имеет область действия и имеет свой n.
При использовании var
for (var i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 10 times 10
},
100 * i);
}
Это связано с тем, что при использовании var для каждой итерации цикла переменная имеет область действия и имеет общую копию.
{
console.log(cc); // undefined. Caused by hoisting
var cc = 23;
}
{
console.log(bb); // ReferenceError: bb is not defined
let bb = 23;
}
На самом деле, Per @Bergi, оба var и let подняты. Объем блока сбора мусора let полезен для закрытия и сбора мусора для восстановления памяти. Рассмотрим, function process(data) {
//...
}
var hugeData = { .. };
process(hugeData);
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});
Обратный вызов обработчика click вообще не нуждается в переменной hugeData. Теоретически, после запуска process(..), огромная структура данных hugeData может быть собрана в мусор. Тем не менее, возможно, что какой-то движок JS по-прежнему должен сохранить эту огромную структуру, поскольку функция click имеет закрытие по всей области. Тем не менее, область блока может сделать эту огромную структуру данных собранной мусором. function process(data) {
//...
}
{ // anything declared inside this block can be garbage collected
let hugeData = { .. };
process(hugeData);
}
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});
let циклы let в цикле могут повторно привязывать его к каждой итерации цикла, чтобы повторно назначить ему значение с конца предыдущей итерации цикла. Рассмотрим // print '5' 5 times
for (var i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
, но заменим var на let // print 1, 2, 3, 4, 5. now
for (let i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
Поскольку let создают новую лексическую среду с этими именами для a) выражение инициализатора b) каждая итерация (предшествующая оценке выражения инкремента), больше подробности здесь. Если я прочитал спецификации прямо, то let, к счастью, также можно использовать, чтобы избежать функций самоисключения, используемых для имитации только частных членов - популярного шаблона дизайна, который уменьшает читаемость кода, усложняет отладку, что не добавляет никакой реальной защиты кода или другого польза - за исключением, может быть, удовлетворения чьего-то стремления к семантике, поэтому прекратите ее использовать. / rant
var SomeConstructor;
{
let privateScope = {};
SomeConstructor = function SomeConstructor () {
this.someProperty = "foo";
privateScope.hiddenProperty = "bar";
}
SomeConstructor.prototype.showPublic = function () {
console.log(this.someProperty); // foo
}
SomeConstructor.prototype.showPrivate = function () {
console.log(privateScope.hiddenProperty); // bar
}
}
var myInstance = new SomeConstructor();
myInstance.showPublic();
myInstance.showPrivate();
console.log(privateScope.hiddenProperty); // error
См. «Эмуляция частных интерфейсов»
В этой статье четко определена разница между var, let и const
const - это сигнал, что идентификатор не будет переназначен. let - сигнал о том, что переменная может быть переназначена, например счетчик в цикле, или обмен значениями в алгоритме. Он также сигнализирует, что переменная будет использоваться только в том блоке, в котором она определена, что не всегда является всей содержащей функцией. var теперь является самым слабым сигналом, доступным при определении переменной в JavaScript. Переменная может быть переназначена или не может быть переназначена, и переменная может использоваться или не использоваться для целой функции или только для целей блока или цикла.https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
Есть некоторые тонкие отличия - let scoping ведет себя больше, как изменение переменных, в более или менее любых других языках.
, например. Он доступен для закрывающего блока. Они не существуют до их объявления и т. Д.
Однако стоит отметить, что let является лишь частью новых реализаций Javascript и имеет разную степень поддержки браузера .
Также представляется, что, по крайней мере, в Visual Studio 2015, TypeScript 1.5, «var» допускает несколько объявлений с одним и тем же именем переменной в блоке, а «let» - нет.
Это выиграло 'генерирует ошибку компиляции:
var x = 1;
var x = 2;
Это будет:
let x = 1;
let x = 2;
Разница заключается в объеме переменных, объявленных с каждым.
На практике существует ряд полезных последствий разницы в видимости: переменные
let отображаются только в ближайшем закрытом блоке ({ ... }). let переменные используются только в строках кода, которые появляются после объявления переменной (даже если они подняты!). let переменные не могут быть повторно описаны с помощью следующих var или let. Глобальные переменные let не добавляются к глобальному объекту window. Переменные let просты в использовании с закрытием (они не вызывают условия гонки).Ограничения, налагаемые let, уменьшают видимость переменных и увеличивают вероятность того, что неожиданные столкновения имен будут найдены раньше. Это облегчает отслеживание и рассуждение о переменных, включая область (помощь в восстановлении неиспользуемой памяти).
Следовательно, переменные let с меньшей вероятностью могут вызывать проблемы при использовании в больших программах или когда независимо разработанные фреймворки объединяются в новые и неожиданные способы.
var может по-прежнему быть полезным, если вы уверены, что хотите эффект единственной привязки при использовании замыкания в цикле ( # 5) или для объявления внешне видимых глобальных переменных в вашем коде (# 4). Использование var для экспорта может быть вытеснено, если export мигрирует из пространства транспилера и на основной язык.
1. Без использования внешнего ближайшего закрывающего блока: этот блок кода выдает опорную ошибку, потому что второе использование x происходит за пределами блока, где оно объявлено с помощью let:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
В отличие от , тот же пример с var работает.
1. Без использования внешнего ближайшего закрывающего блока: Этот блок кода выдает ReferenceError до того, как код может быть запущен, потому что x используется до его объявления:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
В отличие от , тот же пример с var анализирует и работает без каких-либо исключений.
3. Нет повторного объявления. Следующий код демонстрирует, что переменная, объявленная с помощью let, не может быть повторно указана позже:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
3. Нет повторной записи:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5. Простое использование с затворами: переменные, объявленные с помощью var, плохо работают с замыканиями внутри петель. Вот простой цикл, который выводит последовательность значений, которые переменная i имеет в разные моменты времени:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
В частности, эти выходы:
i is 0
i is 1
i is 2
i is 3
i is 4
In JavaScript мы часто используем переменные значительно позже, чем когда они созданы. Когда мы это продемонстрируем, задерживая вывод с закрытием, переданным в setTimeout:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... выход остается неизменным, пока мы придерживаемся let. Напротив, если бы мы использовали var i вместо:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... цикл неожиданно выводит «i is 5» пять раз:
i is 5
i is 5
i is 5
i is 5
i is 5
var - глобальная переменная с возможностью перемещения (hoist-able).
let и const - это область блока.
test.js
{
let l = 'let';
const c = 'const';
var v = 'var';
v2 = 'var 2';
}
console.log(v, this.v);
console.log(v2, this.v2);
console.log(l); // ReferenceError: l is not defined
console.log(c); // ReferenceError: c is not defined
Как упоминалось выше:
Разница заключается в определении области. var привязан к ближайшему функциональному блоку, а let привязан к ближайшему закрывающему блоку, который может быть меньше функционального блока. Оба являются глобальными, если вне любого блока. Давайте посмотрим пример:Example1:
В обоих моих примерах у меня есть функция myfunc. myfunc содержит переменную myvar, равную 10. В моем первом примере я проверяю, равен ли myvar 10 (myvar==10). Если да, я agian объявляю переменную myvar (теперь у меня есть две переменные myvar), используя ключевое слово var и присваиваю ей новое значение (20). В следующей строке я напечатаю его значение на моей консоли. После условного блока я снова распечатаю значение myvar на моей консоли. Если вы посмотрите на вывод myfunc, значение myvar будет равно 20.
Пример1: В моем втором примере вместо использования var в моем условном блоке объявляю myvar с помощью ключевого слова let. Теперь, когда я вызываю myfunc, я получаю два разных выхода: myvar=20 и myvar=10.
Таким образом, различие очень просто в его области.
Проверьте эту ссылку в MDN
let x = 1;
if (x === 1) {
let x = 2;
console.log(x);
// expected output: 2
}
console.log(x);
// expected output: 1
В ECMAScript 6 добавлено еще одно ключевое слово, чтобы объявить переменные, другие «const», кроме «let».
Основная цель введения «let» и «const» над «var» состоит в том, чтобы иметь вместо облачного лексического охвата. ECMAScript 6 .
let также можно использовать, чтобы избежать проблем с закрытием. Он связывает свежую ценность, а не сохраняет старую ссылку, как показано в примерах ниже.
DEMO
for(var i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
В коде выше показана классическая проблема закрытия JavaScript. Ссылка на переменную i хранится в закрытии обработчика кликов, а не фактическое значение i.
Каждый обработчик клика будет ссылаться на один и тот же объект, потому что есть только один объект-счетчик, имеет значение 6, поэтому вы получаете по шесть за каждый клик.
Общим решением является обернуть это анонимной функцией и передать i в качестве аргумента. Эти проблемы также можно избежать, используя let вместо var, как показано в коде ниже.
DEMO (проверено в Chrome и Firefox 50)
'use strict';
for(let i = 1; i < 6; i++) {
document.getElementById('my-element' + i)
.addEventListener('click', function() { alert(i) })
}
let является частью es6. Эти функции объяснят разницу простым способом.
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
Вот пример разницы между двумя (поддержка только что началась для chrome):
Как вы можете видеть, переменная var j все еще имеет значение за пределами области цикла for (Block Scope), но переменная let i не определена вне области цикла for.
"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
console.log(j);
}
console.log(j);
console.log("let:");
for (let i = 0; i < 2; i++) {
console.log(i);
}
console.log(i);
В принятом ответе отсутствует точка:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined