UPDATE t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
SET t1.a = 'something',
t2.b = 42,
t3.c = t2.c
WHERE t1.a = 'blah';
Чтобы узнать, что он собирается обновить, вы можете преобразовать это в оператор select, например :
SELECT t2.t1_id, t2.t3_id, t1.a, t2.b, t2.c AS t2_c, t3.c AS t3_c
FROM t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
WHERE t1.a = 'blah';
В случае анонимного выражения функции функция анонимна & nbsp; & mdash; буквально, у него нет имени. Переменная, которую вы назначаете, имеет имя, но функция не работает. (Обновление: это было верно через ES5. Начиная с ES2015 [aka ES6], часто функция, созданная с анонимным выражением, получает истинное имя, читается далее ...)
Имена полезны. Имена можно увидеть в трассировках стека, столах вызовов, списках точек останова и т. Д. Имена - это Good Thing ™.
Вам нужно остерегаться именованных функциональных выражений в более старых версиях IE (IE8 и ниже) , потому что IE ошибочно создает два полностью отдельных объекта функции в два совершенно разных раза (больше в моей статье в блоге Double take ). Если вам нужно поддерживать IE8, лучше всего использовать анонимные выражения функций или функции declarations , но избегать названных функциональных выражений.
Как и в ES2015, анонимные "выражения функций создают функции с именами, и это было обусловлено тем, что различные современные механизмы JavaScript были достаточно умны в определении имен из контекста. В ES2015 выражение анонимной функции приводит к функции с именем boo
. Это разбросано по всему spec , а не определено в одном месте с кучей правил: Поиск вхождения «SetFunctionName», в настоящее время найденный в:
let
и const
семантика декларации) Краткая версия в основном в любое время, когда выражение анонимной функции появляется справа от чего-то вроде назначение или инициализацию, например:
var boo = function() { /*...*/ };
(или это могут быть let
или const
, а не var
) или
var obj = {
boo: function() { /*...*/ }
};
или
doSomething({
boo: function() { /*...*/ }
});
(последние два - это одно и то же) , результирующая функция будет иметь имя (boo
в примерах).
Существует важное и преднамеренное исключение: Назначение ap rperty на существующем объекте:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Это было из-за проблем с утечкой информации, возникающих при добавлении новой функции в процессе добавления; подробности в моем ответе на другой вопрос здесь .
Вы всегда должны использовать выражения функции NAMED.
2.Анонимные функции не 't помогает при отладке, поскольку вы не можете увидеть имя функции, которая вызывает проблемы.
3. Когда вы не называете функцию, позже ее сложнее понять, что ее делает. имя упрощает понимание.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Здесь, например, поскольку строка имени используется в выражении функции, она не объявляется во внешней области. С помощью названных функциональных выражений имя выражение функции заключено в пределах своей области.
Функции именования полезны, если им нужно ссылаться на себя (например, для рекурсивных вызовов). Действительно, если вы передаете литеральное выражение функции в качестве аргумента непосредственно другой функции, это выражение функции не может напрямую ссылаться на себя в строгом режиме ES5, если оно не названо.
Например , рассмотрим этот код:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
Невозможно было бы написать этот код достаточно чисто, если бы выражение функции, переданное в setTimeout
, было анонимным; мы должны были бы назначить его переменной вместо перед вызовом setTimeout
. Таким образом, с выражением с именем функции, немного короче и аккуратнее.
Исторически было возможно написать такой код, даже используя выражение анонимной функции, используя arguments.callee
...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... но arguments.callee
устарел и категорически запрещен в строгом режиме ES5. Поэтому MDN советует:
Избегайте использования
< / blockquote>arguments.callee()
либо , давая функциональным выражениям имя , либо используйте объявление функции, в котором функция должна вызывать себя.(основное внимание)
Если функция определена как выражение функции, ей может быть присвоено имя.
Он будет доступен только внутри функции (кроме IE8 -).
Это имя предназначен для надежного рекурсивного вызова функции, даже если он записывается в другую переменную.
Обратите внимание, что с объявлением функции это невозможно. Это «специальное» имя внутренней функции указывается только в синтаксисе Function Expression.
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
Кроме того, имя NFE (Именованное выражение) не может быть перезаписано:
var test = function sayHi(name) {
sayHi = "тест"; // try to redefine
alert( sayHi ); // function... (redefinition is unsuccessful )
};
test();
Использование названных функциональных выражений лучше, если вы хотите иметь возможность ссылаться на рассматриваемую функцию, не полагаясь на устаревшие функции, такие как arguments.callee
.
new
(предоставление всех имен таких функций делает свойство.constructor
более полезным при отладке для выяснения того, какой черт какой-то объект является экземпляром), а для литералов функций передается непосредственно в функцию без предварительного присвоения свойства или переменной (например,setTimeout(function () {/*do stuff*/});
). Даже Chrome показывает их как(anonymous function)
, если вы не поможете ему, назвав их. – Mark Amery 19 February 2015 в 01:25setTimeout
не захватил имя из формального аргумента, объявленного дляsetTimeout
, если бы он был один. :-) Но да, NFE определенно полезны, если вы знаете, что не будете иметь дело со старыми браузерами, которые делают хэш из них. – T.J. Crowder 19 February 2015 в 10:18