Скрытые функции JavaScript? [закрытый]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

312
задан 11 revs, 6 users 36% 23 May 2017 в 02:10
поделиться

99 ответов

Подарок Microsofts JavaScript: AJAX

AJAXCall('http://www.abcd.com/')

function AJAXCall(url) {
 var client = new XMLHttpRequest();
 client.onreadystatechange = handlerFunc;
 client.open("GET", url);
 client.send();
}

function handlerFunc() {
 if(this.readyState == 4 && this.status == 200) {
 if(this.responseXML != null)
   document.write(this.responseXML)
 }
}
7
ответ дан Binoj Antony 23 November 2019 в 01:10
поделиться

Можно повернуть "любого* объект с целочисленными свойствами и свойством длины в надлежащий массив, и таким образом обеспечить его всеми методами массива, такими как нажатие, поп, соединение встык, карта, отфильтровать, уменьшить, и т.д.

Array.prototype.slice.call({"0":"foo", "1":"bar", 2:"baz", "length":3 }) 

//возвраты ["нечто", "панель", "baz"]

Это работает с объектами jQuery, наборами HTML и объектами Массива от других кадров (как одно возможное решение целой вещи типа массива). Я говорю, если это имеет свойство длины, можно превратить его в массив, и это не имеет значения. Существует много из не, выстраивают объекты со свойством длины, вне объекта arguments.

8
ответ дан 2 revs 23 November 2019 в 01:10
поделиться

Если Вы вслепую eval() JSON представляет в виде строки для десериализации его, можно столкнуться с проблемами:

  1. Это не безопасно. Строка может содержать злонамеренные вызовы функции!
  2. , Если Вы не включаете строку JSON в круглые скобки, имена свойства могут быть ошибочными как маркировки, приводящие к неожиданному поведению или синтаксической ошибке:

    eval("{ \"foo\": 42 }"); // syntax error: invalid label
    eval("({ \"foo\": 42 })"); // OK
    
8
ответ дан Ates Goral 23 November 2019 в 01:10
поделиться

let.

Дубликат к отсутствие var обзора блока let, представлено в JavaScript 1.7.

  • оператор, которому позволяют, позволяет связывать значения с переменными в рамках блока, не влияя на значения подобно названных переменных вне блока.
  • выражение, которому позволяют, позволяет, Вы установить переменные определили объем только к отдельному выражению.
  • определение, которому позволяют, определяет переменные, объем которых ограничивается к блоку, в котором они определяются. Этот синтаксис очень похож на синтаксис, используемый для var.
  • можно также использовать, позволяют для установления переменных, которые существуют только в контексте для цикла.
  function varTest() {
        var x = 31;
    if (true) {
      var x = 71;  // same variable!
      alert(x);  // 71
    }
    alert(x);  // 71
  }

  function letTest() {
    let x = 31;
    if (true) {
      let x = 71;  // different variable
      alert(x);  // 71
    }
    alert(x);  // 31
  }

По состоянию на 2008, JavaScript 1.7 поддерживается в FireFox 2.0 + и Safari 3.x.

8
ответ дан 2 revs 23 November 2019 в 01:10
поделиться

== оператор имеет совершенно особое свойство, которое создает это тревожащее равенство (Да, я знаю на других динамических языках как Perl, это поведение ожидалось бы, но JavaScript ususally не пытается быть умным в сравнениях):

>>> 1 == true
true
>>> 0 == false
true
>>> 2 == true
false
8
ответ дан Malde 23 November 2019 в 01:10
поделиться

Можно выполнить метод объекта на любом объекте, независимо от того, имеет ли он тот метод или нет. Конечно, это не могло бы всегда работать (если метод предполагает, что объект имеет что-то, что это не делает), но это может быть чрезвычайно полезно. Например:

function(){
    arguments.push('foo') // This errors, arguments is not a proper array and has no push method
    Array.prototype.push.apply(arguments, ['foo']) // Works!
}
8
ответ дан Dan 23 November 2019 в 01:10
поделиться

Все функции являются на самом деле экземплярами встроенного Функция тип, который имеет конструктора, который берет строку, содержащую функциональное определение, таким образом, можно на самом деле определить функции во времени выполнения, например, связав строки:

//e.g., createAddFunction("a","b") returns function(a,b) { return a+b; }
function createAddFunction(paramName1, paramName2)
 { return new Function( paramName1, paramName2
                       ,"return "+ paramName1 +" + "+ paramName2 +";");
 }

кроме того, для пользовательских функций, Function.toString () возвраты функциональное определение как литеральная строка.

8
ответ дан Mark Cidade 23 November 2019 в 01:10
поделиться

JavaScript имеет статические переменные в функциях:

function someFunction(){
  var Static = arguments.callee;
  Static.someStaticVariable = (Static.someStaticVariable || 0) + 1;
  alert(Static.someStaticVariable);
}
someFunction() //Alerts 1
someFunction() //Alerts 2
someFunction() //Alerts 3

Это также имеет статические переменные в Объектах:

function Obj(){
  this.Static = arguments.callee;
}
a = new Obj();
a.Static.name = "a";
b = new Obj();
alert(b.Static.name); //Alerts b
8
ответ дан Marius 23 November 2019 в 01:10
поделиться

window.name значение сохраняется через изменения страницы, может быть считан родительским окном, если в том же домене (если в iframe, используйте document.getElementById("your frame's ID").contentWindow.name для доступа к нему), и ограничен только доступной памятью.

9
ответ дан bbrown 23 November 2019 в 01:10
поделиться

Функциональные операторы и выражения function обрабатываются по-другому.

function blarg(a) {return a;} // statement
bleep = function(b) {return b;} //expression

Все функциональные операторы анализируются, прежде чем код выполняется - функция у основания файла JavaScript будет доступна в первом операторе. С другой стороны, это не будет в состоянии использовать в своих интересах определенный динамический контекст, такой как окружение with, операторы - эти with не были выполнены, когда функция анализируется.

Выражения function выполняются встроенный, правильный, где с ними встречаются. Они не доступны перед тем временем, но они могут использовать в своих интересах динамический контекст.

9
ответ дан Justin Love 23 November 2019 в 01:10
поделиться

Понятие truthy и значений falsy. Вы не должны делать чего-то как

если (someVar ===, неопределенный || пустой указатель someVar ===)...

Просто сделайте:

, если (! someVar).

Каждое значение имеет соответствующее булево представление.

9
ответ дан Rakesh Pai 23 November 2019 в 01:10
поделиться

Можно сделать почти что-либо между круглыми скобками при разделении операторов с запятыми:

var z = ( x = "can you do crazy things with parenthesis", ( y = x.split(" "), [ y[1], y[0] ].concat( y.slice(2) ) ).join(" ") )

alert(x + "\n" + y + "\n" + z)

Вывод:

can you do crazy things with parenthesis
can,you,do,crazy,things,with,parenthesis
you can do crazy things with parenthesis
10
ответ дан 2 revs, 2 users 92% 23 November 2019 в 01:10
поделиться

Одно из моего избранного является проверкой типа конструктора:

function getObjectType( obj ) {  
    return obj.constructor.name;  
}  

window.onload = function() {  
    alert( getObjectType( "Hello World!" ) );  
    function Cat() {  
        // some code here...  
    }  
    alert( getObjectType( new Cat() ) );  
}

Так вместо усталого старого [Объектный объект] Вы часто добираетесь с typeof ключевым словом, можно на самом деле получить реальные типы объектов, основанные на конструкторе.

Другой использует аргументы переменной в качестве способа "перегрузить" функции. Все, что Вы делаете, использует выражение для обнаружения количества аргументов и возвращает перегруженный вывод:

function myFunction( message, iteration ) {  
    if ( arguments.length == 2 ) {  
        for ( i = 0; i < iteration; i++ ) {  
            alert( message );  
        }  
    } else {  
        alert( message );  
    }  
}  

window.onload = function() {  
    myFunction( "Hello World!", 3 );  
}

Наконец, я сказал бы стенографию оператора присваивания. Я узнал об этом из источника платформы jQuery... старый путь:

var a, b, c, d;
b = a;
c = b;
d = c;

новое (стенография) путь:

var a, b, c, d;
d = c = b = a;

Хорошее развлечение:)

10
ответ дан user4903 23 November 2019 в 01:10
поделиться

Предотвратите раздражающие ошибки при тестировании в Internet Explorer при использовании console.log () для Firebug:

function log(message) {
    (console || { log: function(s) { alert(s); }).log(message);
}
11
ответ дан 3 revs, 3 users 62% 23 November 2019 в 01:10
поделиться

JavaScript использует литерал простого объекта:

var x = { intValue: 5, strValue: "foo" };

Это создает законченный объект.

JavaScript использует основанную на прототипе объектную ориентацию и обеспечивает способность расширить типы во времени выполнения:

String.prototype.doubleLength = function() {
    return this.length * 2;
}

alert("foo".doubleLength());

объект делегирует весь доступ к атрибутам, которые это не содержит само к его "прототипу", другому объекту. Это может использоваться для реализации наследования, но на самом деле более мощно (даже если более громоздкий):

/* "Constructor" */
function foo() {
    this.intValue = 5;
}

/* Create the prototype that includes everything
 * common to all objects created be the foo function.
 */
foo.prototype = {
    method: function() {
        alert(this.intValue);
    }
}

var f = new foo();
f.method();
11
ответ дан Sebastian Rittau 23 November 2019 в 01:10
поделиться

Вот несколько ярлыков:

var a = []; // equivalent to new Array()
var o = {}; // equivalent to new Object()
13
ответ дан 3 revs, 2 users 88% 23 November 2019 в 01:10
поделиться

Путем JavaScript работает с Датой (), просто волнует меня!

function isLeapYear(year) {
    return (new Date(year, 1, 29, 0, 0).getMonth() != 2);
}

Это - действительно "скрытая функция".

Редактирование: Удаленный"?" условие, как предложено в комментариях для politcorrecteness. Был:... новая Дата (год, 1, 29, 0, 0) .getMonth ()! = 2? верный: ложь... Посмотрите на комментарии для деталей.

15
ответ дан 3 revs 23 November 2019 в 01:10
поделиться

Существует несколько ответов в этом потоке, показывающем, как расширить объект Массива через его прототип. Это - ПЛОХАЯ ИДЕЯ, потому что она повреждается for (i in a) оператор.

Так он хорошо, если Вы, оказывается, не используете for (i in a) нигде в Вашем коде? Ну, только если Ваш собственный код является единственным кодом, который Вы выполняете, который не является, слишком вероятно, в браузере. Я боюсь, что, если люди начинают расширять свои объекты Массива как это, Переполнение стека начнет переполняться с набором таинственных ошибок JavaScript.

Посмотрите полезные детали здесь .

17
ответ дан 3 revs, 2 users 59% 23 November 2019 в 01:10
поделиться

Когда Вы хотите удалить элемент из массива, можно использовать , удаляют оператор, как таковой:

var numbers = [1,2,3,4,5];
delete numbers[3];
//numbers is now [1,2,3,undefined,5]

, Как Вы видите, элемент был удален, но дыру покинули в массиве, так как элемент был заменен неопределенный значение.

Таким образом, для работы вокруг этой проблемы, вместо того, чтобы использовать удаляют , используют соединение встык метод массива... как таковой:

var numbers = [1,2,3,4,5];
numbers.splice(3,1);
//numbers is now [1,2,3,5]

первый аргумент [1 113] соединение встык является ординалом в массиве [индекс], и вторым является число элементов для удаления.

17
ответ дан Andreas Grech 23 November 2019 в 01:10
поделиться

Все объекты в JavaScript реализованы как хеш-таблицы, таким образом, к их свойствам можно получить доступ через индексатор и наоборот. Кроме того, можно перечислить все свойства с помощью для/в оператор:

var x = {a: 0};
x["a"]; //returns 0

x["b"] = 1;
x.b; //returns 1

for (p in x) document.write(p+";"); //writes "a;b;"
19
ответ дан Mark Cidade 23 November 2019 в 01:10
поделиться

Метки времени в JavaScript:

// Usual Way
var d = new Date();
timestamp = d.getTime();

// Shorter Way
timestamp = (new Date()).getTime();

// Shortest Way
timestamp = +new Date();
21
ответ дан 4 revs, 4 users 69% 23 November 2019 в 01:10
поделиться

Вы никогда не должны использовать eval() собрать имена глобальной переменной.

Таким образом, если у Вас есть несколько globals (по любой причине) названный spec_grapes, spec_apples, Вы не должны получать доступ к ним с eval("spec_" + var).

Все globals являются членами window[], таким образом, можно сделать window["spec_" + var].

12
ответ дан Lucent 23 November 2019 в 01:10
поделиться

The parentheses are optional when creating new "objects".

function Animal () {

}

var animal = new Animal();
var animal = new Animal;

Same thing.

9
ответ дан Dave 23 November 2019 в 01:10
поделиться

Вы можете назначить локальные переменные, используя [] слева сторона руки. Пригодится, если вы хотите вернуть более одного значения из функции без создания ненужного массива.

function fn(){
    var cat = "meow";
    var dog = "woof";
    return [cat,dog];
};

var [cat,dog] = fn();  // Handy!

alert(cat);
alert(dog);

Это часть ядра JS, но почему-то я так и не понял до этого года.

20
ответ дан 23 November 2019 в 01:10
поделиться

Самыми быстрыми циклами в JavaScript являются циклы while (i--). Во всех браузерах. Поэтому, если порядок обработки элементов вашего цикла не так важен, вы должны использовать форму while (i--):

var names = new Array(1024), i = names.length;
while(i--)
  names[i] = "John" + i;

Кроме того, если вам нужно использовать цикл for () в дальнейшем, не забывайте всегда кэшировать. свойство length:

var birds = new Array(1024); 
for(var i = 0, j = birds.length; i < j; i++)
  birds[i].fly();

Для объединения больших строк используйте массивы (это быстрее):

var largeString = new Array(1024), i = largeString.length;
while(i--) {
  // It's faster than for() loop with largeString.push(), obviously :)
  largeString[i] = i.toString(16);
}

largeString = largeString.join("");

Это намного быстрее, чем largeString + = "something" внутри цикла.

10
ответ дан 23 November 2019 в 01:10
поделиться

Если вы пытаетесь изолировать код javascript, отключите все возможные способы оценивать строки в коде javascript, имейте в виду, что блокировки всех очевидных eval / document.write / new Function / setTimeout / setInterval / innerHTML и других манипуляций с DOM недостаточно.

Для любого объекта o, o.constructor .constructor ("alert ('hi')") () вызовет диалоговое окно с предупреждением со словом «привет» в нем.

Вы можете переписать его как

var Z="constructor";
Z[Z][Z]("alert('hi')")();

Fun stuff.

8
ответ дан 23 November 2019 в 01:10
поделиться

Шаблон модуля

<script type="text/javascript">
(function() {

function init() {
  // ...
}

window.onload = init;
})();
</script>

Переменные и функции, объявленные без оператора var или вне функции будет определен в глобальной области видимости. Если переменная / функция с таким же именем уже существует, она будет автоматически переопределена, что может привести к очень трудному обнаружению ошибок. Распространенное решение - заключить все тело кода в анонимную функцию и немедленно выполнить ее. Таким образом, все переменные / функции определяются в области действия анонимной функции и не попадают в глобальную область видимости.

Чтобы явно определить переменную / функцию в глобальной области видимости, они должны иметь префикс window :

window.GLOBAL_VAR = 12;
window.global_function = function() {};
7
ответ дан 23 November 2019 в 01:10
поделиться

Мой любимый трюк - использовать apply для выполнения обратного вызова метода объекта и поддержания правильной переменной «this».

function MakeCallback(obj, method) {
    return function() {
        method.apply(obj, arguments);
    };
}

var SomeClass = function() { 
     this.a = 1;
};
SomeClass.prototype.addXToA = function(x) {
     this.a = this.a + x;
};

var myObj = new SomeClass();

brokenCallback = myObj.addXToA;
brokenCallback(1); // Won't work, wrong "this" variable
alert(myObj.a); // 1


var myCallback = MakeCallback(myObj, myObj.addXToA);
myCallback(1);  // Works as expected because of apply
alert(myObj.a); // 2
13
ответ дан 23 November 2019 в 01:10
поделиться

Дзен замыканий

Другие упоминали замыкания. Но удивительно, как много людей знают о замыканиях, пишут код, используя замыкания, но все равно имеют неверное представление о том, что такое замыкания на самом деле. Некоторые путают первоклассные функции с замыканиями. А другие видят в этом своего рода статическую переменную.

Для меня замыкание - это своего рода глобальная переменная 'private' . То есть, своего рода переменная, которую одни функции видят как глобальную, а другие нет. Теперь я знаю, что это играет быстро и свободно с описанием основного механизма, но именно так он чувствует себя и ведет себя. Для иллюстрации:

// Say you want three functions to share a single variable:

// Use a self-calling function to create scope:
(function(){

    var counter = 0; // this is the variable we want to share;

    // Declare global functions using function expressions:
    increment = function(){
        return ++counter;
    }
    decrement = function(){
        return --counter;
    }
    value = function(){
        return counter;
    }
})()

теперь три функции инкремент, декремент и значение делят переменную счетчик, при этом счетчик не является актуальной глобальной переменной. Такова истинная природа замыкания:

increment();
increment();
decrement();
alert(value()); // will output 1

Вышеуказанное не является действительно полезным использованием замыкания. На самом деле, я бы сказал, что использование его таким образом - это антипаттерн. Но это полезно для понимания природы замыканий. Например, большинство людей попадаются, когда пытаются сделать что-то вроде:

for (var i=1;i<=10;i++) {
    document.getElementById('span'+i).onclick = function () {
        alert('this is span number '+i);
    }
}
// ALL spans will generate alert: this span is span number 10

Это потому, что они не понимают природу замыканий. Они думают, что передают в функции значение i, когда на самом деле функции совместно используют одну переменную i. Как я уже говорил, особый вид глобальной переменной.

Чтобы обойти это, нужно отсоединить *закрытие:

function makeClickHandler (j) {
    return function () {alert('this is span number '+j)};
}

for (var i=1;i<=10;i++) {
    document.getElementById('span'+i).onclick = makeClickHandler(i);
}
// this works because i is passed by reference 
// (or value in this case, since it is a number)
// instead of being captured by a closure

*замечание: здесь я не знаю правильной терминологии.

13
ответ дан 23 November 2019 в 01:10
поделиться

В функции вы можете вернуть саму функцию:

function showSomething(a){
   alert(a);
   return arguments.callee;
}

// Alerts: 'a', 'b', 'c'
showSomething('a')('b')('c');

// Or what about this:
(function (a){
   alert(a);
   return arguments.callee;
}​)('a')('b')('c');​​​​

Я не знаю, когда это может быть полезно, в любом случае, это довольно странно и весело :

var count = function(counter){
   alert(counter);
   if(counter < 10){
      return arguments.callee(counter+1);
   }
   return arguments.callee;
};

count(5)(9); // Will alert 5, 6, 7, 8, 9, 10 and 9, 10

На самом деле, фреймворк FAB для Node.js, похоже, реализовал эту функцию; см., например, этот раздел .

16
ответ дан 23 November 2019 в 01:10
поделиться