Заметки WEB-разработчика

Полезные материалы для web-разработки

Некоторые замечания по функиям в javascript

В этой статье речь пойдет о некоторых нюансах по работе с функиями в javascript: область видимости (scope chain), замыкания и т.д.

Некоторые замечания по функиям в javascript

Общие замечания

Для начала приведем, что вообще нужно помнить о функциях в javascript:

  • Передаваемые значения копируются в параметры функции и становятся локальными переменными.
  • Параметры функции являются её локальными переменными.
  • Можно объявить новые локальные переменные при помощи var.
  • Значение возвращается оператором return ....
  • Вызов return тут же прекращает функцию.
  • Если return; вызван без значения, или функция завершилась без return, то её результат равен undefined.
  • При обращении к необъявленной переменной функция будет искать внешнюю переменную с таким именем.

Параметр, передаваемый в функцию внутри функции всегда имеет локальную область видимости.

 function foo (a){
	//равносильно var a
	++a;
	alert(a); //2
}
alert(a); // здесь перменная a уже НЕ видна

В js функция – это тип данных, поэтому функцию можно хранить в переменной.

var foo = function(){ 
	function(){alert('!')}
}
// в foo будет function(){alert('!')}

Внутри функции мы можем использоваать объект arguments который хранит аргументы функции.

function foo(a,b){
	console.log(arguments)
}; 
foo(1,2) // [1,2]

У функции есть свойство length – означает количество ожидаемых аргументов (arguments.length)

У функций нет параметров по умолчанию, как например в php

// неправильно!
function foo(x = 1){
	alert(x);
}

Если параметр не передан при вызове — он считается равным undefined. Такую ситуацию можно отловить и назначить значение «по умолчанию»:

function showMessage(text) {
  text = text || 'hello!'; 
  /* 
  if (text === undefined) {
      text = 'hello!;
  }
  */
}

Если return; вызван без значения, или функция завершилась без return, то её результат равен undefined.

	var foo = function (){
    	// ...
    }
    console.log(foo); //undefined 

Есть такое понятие 'Подъём'. Все объявление переменных в функции подымаются вверх функции (хостинг).

function foo(){
	alert(x);
	var x = 1;
}
foo(); //undified ибо объявление переменных интерпретатором инициализируются в начале
/*
равносильно:
function foo(){
	var x;
	alert(x);
	x = 1;
}
*/

Цепочки областей видимости (scope chain)

Глобальные переменные – объявленные вне функции
Локальные переменные – объявленные внутри функции (только функции создают локальную область видимости)

Локальная переменная с таким же именем как и глобальная имеет больший приоритет

var i = 5;
var func = function (){
	var i = 10;
	console.log(i);
}
func() // 10

Функции могут быть вложенными

var i = 5;
var func = function (){
	var i = 10;
	console.log(i);
	var innerFunc = function(){
		var i = 15;
		console.log(i);
	}
	innerFunc();
}
func() // 10 15

Если убрать var i = 15; то интерпретатор пойдет искать переменную выше

var i = 5;
var func = function (){
	var i = 10;
	console.log(i);
	var innerFunc = function(){
		//var i = 15;
		console.log(i);
	}
	innerFunc();
}
func() // 10 10

Замыкания

Если говорить просто, то замыкание - это внутренняя функция. Ведь javascript разрешает создавать функции по ходу выполнения скрипта. И эти функции имеют доступ к переменным внешней функции (в которой созданы).

В этом примере создается внутренняя функция func, изнутри которой доступны как локальные переменные, так и переменные внешней функции outer:

function outer () {
	var outerVar = 1;
	var func = function() {
		return outerVar;
	}
	alert(func())
}
outer();
//1

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

function createCounter() {
	var numberOfCalls = 0;
	return function() {
		return ++numberOfCalls;
	}
}
var fn = createCounter();
fn(); //1
fn(); //2
fn(); //3

Комментарии

Комментарии через Вконтакте