Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Ранние версии JavaScript не позволили названные выражения function, и из-за этого мы не могли сделать выражение рекурсивной функции:
// This snippet will work:
function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
}
[1,2,3,4,5].map(factorial);
// But this snippet will not:
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : /* what goes here? */ (n-1)*n;
});
Для двигений это, arguments.callee
было добавлено так, мы могли сделать:
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : arguments.callee(n-1)*n;
});
Однако это было на самом деле действительно плохим решением, поскольку это (в сочетании с другими аргументами, вызываемым и проблемами вызывающей стороны) делает встраивание и хвостовую рекурсию невозможными в общем случае (можно достигнуть его в избранных случаях посредством трассировки и т.д., но даже лучший код sub оптимальный из-за проверок, которые иначе не были бы необходимы). Другая главная проблема - то, что рекурсивный вызов получит различное this
значение, например:
var global = this;
var sillyFunction = function (recursed) {
if (!recursed)
return arguments.callee(true);
if (this !== global)
alert("This is: " + this);
else
alert("This is the global");
}
sillyFunction();
Во всяком случае, EcmaScript 3 решил эти вопросы путем разрешения названный выражениями function, например:
[1,2,3,4,5].map(function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
});
Это обладает многочисленными преимуществами:
функция может быть вызвана как любой другой из Вашего кода.
Это не загрязняет пространство имен.
значение this
не изменяется.
Это более производительно (доступ , объект arguments является дорогим).
Просто поняли, что в дополнение ко всему остальному вопрос был [приблизительно 118], или более конкретно Function.caller
.
В любом моменте времени можно найти самую глубокую вызывающую сторону любой функции на стеке, и как я сказал выше, смотрение на стек вызовов имеет один единственный главный эффект: Это делает большое количество из оптимизации невозможным, или намного намного более трудным.
, Например, если мы не можем гарантировать, что функция f
не вызовет неизвестную функцию, тогда не возможно встроить f
. В основном это означает, что любой сайт вызова, который, возможно, был тривиально inlinable, накапливает большое количество защиты, возьмите:
function f(a, b, c, d, e) { return a ? b * c : d * e; }
, Если js интерпретатор не может гарантировать, что всеми обеспеченными аргументами являются числа в точке, что вызов выполняется, он должен или вставить проверки на все аргументы перед встроенным кодом, или он не может встроить функцию.
Теперь в данном случае умный интерпретатор должен быть в состоянии перестроить проверки, чтобы быть более оптимальным и не проверить любые значения, которые не использовались бы. Однако во многих случаях это просто не возможно, и поэтому становится невозможно встроить.
Лучше использовать именованные функции , чем arguments.callee:
function foo () {
... foo() ...
}
лучше, чем
function () {
... arguments.callee() ...
}
, именованная функция будет иметь доступ к своей вызывающей стороне через вызывающая сторона свойство:
function foo () {
alert(foo.caller);
}
, который лучше, чем
function foo () {
alert(arguments.callee.caller);
}
, депрекация происходит из-за текущего ECMAScript принципы разработки .
arguments.call ee .call er
не устарел, хотя он использует функцию .call er
свойство. ( arguments.call ee
просто даст вам ссылку на текущую функцию)
Function.call er
, хотя и нестандартный в соответствии с ECMA3, реализован в все основные текущие браузеры . arguments.call er
не рекомендуется в пользу Function.call er
, и не реализована в некоторых основных браузерах (например, Firefox 3). Таким образом, ситуация далеко не идеальная, но если вы хотите получить доступ к вызывающей функции в Javascript во всех основных браузерах, вы можете использовать Function.call er
свойство,