Double x,y; //объявление полей




sum(double x, double y){ //конструктор

//инициализация полей класса

this.x=x;

this.y=y;

}

}

 

Такой класс только инициализирует поля класса, но ничего не делает.

Сейчас невозможно узнать логику разработчиков стандарта языка JavaScript. Возможно, что они рассуждали так: зачем подчеркивать то, что создается класс с именем sum, если в нем есть конструктор, который имеет тоже имя. Не проще ли записать так:

 

{

double x,y;

sum(double x, double y){

this.x=x;

this.y=y;

}

}

Но можно пойти далее – отказаться от объявления полей класса (x и y), подразумевая, что переменные с именами помеченные словом this иесть поля класса, а те у которых нет этого указателя – являются параметрами конструктора. Тогда описание класса становится совсем простым:

 

sum(double x, double y){

this.x=x;

this.y=y;

}

 

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

 

function sum(x,y){

this.x=x;

this.y=y;

}

 

Как и ранее эта функция ничего не делает. Добавим в нее пару строк, позволяющих найти сумму чисел x и y и вывести ее на экран.

 

function sum(x,y){

this.x=x;

this.y=y;

z=this.x+this.y; //z-не является полем класса

document.write("x+y="+ z+"<BR>");

}

 

Названый класс создается следующим образом:

 

<html>

<head>

<title><h3>Демонстрация класса</h3></title>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<script language="javascript">

function sum(x,y){

this.x=x;

this.y=y;

this.z=this.x+this.y;

document.write("x+y="+this.z+"<BR>");

}

</script>

</head>

<body>

<script>

var x=3,y=4;

var a=5, b=6;

Sum(1,2);//обычный вызов функции

object1=new sum(x,y);

object2=new sum(a,b);

object3=new sum(7,8);

object4=new sum(x,y);

</script>

</body>

</html>

 

Нетрудно заметить, что описание нашего класса есть ни что иное, как функция конструктора. Параметры конструктора предназначены для установки свойств объекта при его создании на базе класса. Свойства определяются простыми ссылками на их имена с указанием ключевого слова this. Это ключевое слово здесь указывает, что в операторе выполняется ссылка на свойства того объекта, для которого вызван конструктор, то есть для создаваемого объекта.

Определение нового класса sum и его методов мы расположили в области заголовка документа HTML, как это принято делать.

 

Области видимости

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

Переменные можно объявлять в любом месте. Ключевое слово var задает переменную в текущей области видимости. Если его забыть, то переменная попадет в глобальный объект window. Возможны неожиданные пересечения с другими переменными окна, конфликты и глюки.

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

Заданная через var переменная видна везде в области видимости, даже до оператора var. Для примера сделаем функцию, которая будет менять переменную, var для которой находится ниже.

Например:

function a() {

z = 5 // поменяет z локально..

//.. т.к z объявлена через var

Var z

}

// тест

Delete z // очистим на всякий случай глобальную z

A()

alert(window.z) // => undefined, т.к. z была изменена локально

 

Параметры функции

Функции можно запускать с любым числом параметров.

Если функции передано меньше параметров, чем есть в определении, то отсутствующие считаются undefined.

Следующая функция возвращает время time, необходимое на преодоление дистанции distance с равномерной скоростью speed.

При первом запуске функция работает с аргументами distance=10, speed=undefined. Обычно такая ситуация, если она поддерживается функцией, предусматривает значение по умолчанию:

// если speed - ложное значение(т.е. undefined, 0, false...) - подставить 10

speed = speed || 10

 

Оператор || в возвращает не true/false, а само значение (первое, которое приводится к true).

Поэтому его используют для задания значений по умолчанию. В нашем вызове speed будет вычислено как undefined || 10 = 10.

Поэтому результат будет 10/10 = 1.

Второй запуск - стандартный.

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

Ну и в последнем случае аргументов вообще нет, поэтому distance = undefined, и имеем результат деления undefined/10 = NaN (Not-A-Number, не число).

 

Работа с неопределенным числом параметров

Непосредственно перед входом в тело функции, автоматически создается объект arguments. Переменная arguments доступна внутри функции и содержит аргументы и ссылку на саму функцию.

  1. Аргументы вызова, которые номеруются, начиная от нуля
  2. Длину (количество аргументов при вызове) в свойстве length
  3. Ссылку на саму функцию в свойстве callee

Например,

function func() { //функция без аргументов

// объект arguments создан автоматически

for(var i=0;i<arguments.length;i++) {

alert("arguments["+i+"] = "+arguments[i])

}

}

Func('a','b',true)

// выведет

// arguments[0] = a

// arguments[1] = b

// arguments[2] = true

Свойство arguments похоже на массив, т.к. у него есть длина и числовые индексы. На самом деле arguments не принадлежит классу Array и не содержит его методов.

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

 

var args = Array.prototype.slice.call(arguments)

//.. теперь args - настоящий массив аргументов..

Args.shift()

...

 

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

var func = function(a,b) { alert(a+b) }

var arr = [1,2]

func.apply(null, arr) // => alert(3)

Пример передачи функции по ссылке

Функцию легко можно передавать в качестве аргумента другой функции. Например, map берет функцию func, применяет ее к каждому элементу массива arr и возвращает получившийся массив:

 

var map = function(func, arr) {

var result = [ ]

for(var i=0; i<arr.length; i++) {

result[i] = func(arr[i])

}

Return result

}

Пример использования:

Можно создать анонимную функцию непосредственно в вызове map:

// анонимная функция утраивает числа

map(function (a) { return a*3 }, [1,2,3]) // = [3,6,9]

 

Сворачивание параметров в объект

Бывают функции, аргументы которых сильно варьируются. Например:

 

// можно указать только часть аргументов

// не указанные - вычисляются или берутся по умолчанию

function resize(toWidth, toHeight, saveProportions, animate) {

// значения по умолчанию

saveProportions = saveProportions || true

animate = animate || true

toHeight = toHeight ||...

}

Вызов с необязательными параметрами приходится делать так:

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: