Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык JavaScript часть1.pdf
Скачиваний:
204
Добавлен:
22.03.2016
Размер:
8.92 Mб
Скачать

Сумма произвольного количества скобок

важность: 2

Напишите функцию sum, которая будет работать так:

sum(1)(2) == 3; // 1 + 2 sum(1)(2)(3) == 6; // 1 + 2 + 3 sum(5)( 1)(2) == 6 sum(6)( 1)( 2)( 3) == 0 sum(0)(1)(2)(3)(4)(5) == 15

Количество скобок может быть любым.

Пример такой функции для двух аргументов — есть в решении задачи Сумма через замыкание.

К решению

Создание объектов через «new»

Обычный синтаксис {...}позволяет создать один объект. Но зачастую нужно создать много однотипных объектов.

Для этого используют «функции-конструкторы», запуская их при помощи специального оператора new.

Конструктор

Конструктором становится любая функция, вызванная через new.

Например:

function Animal(name) { this.name = name; this.canWalk = true;

}

var animal = new Animal("ёжик");

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

Алгоритм работы функции, запущенной через new:

1.Автоматически создается новый пустой объект.

2.Ключевое слово thisполучает ссылку на этот объект.

3.Функция выполняется. Как правило, она модифицирует this, добавляет методы, свойства.

4.Возвращается this.

Врезультате вызова new Animal("ёжик");получаем такой объект:

animal = { name: "ёжик", canWalk: true

}

Иными словами, при вызове new Animalпроисходит что-то в таком духе (первая и последняя строка

— это то, что делает интерпретатор):

function Animal(name) { // this = {}

// в this пишем свойства, методы this.name = name;

this.canWalk = true;

// return this

}

Правила обработки return

Как правило, конструкторы ничего не возвращают. Их задача — записать всё, что нужно, в this, который автоматически станет результатом.

Но если явный вызов returnвсё же есть, то применяется простое правило:

При вызове returnс объектом, будет возвращён он, а не this.

При вызове returnс примитивным значением, оно будет отброшено.

Иными словами, вызов returnс объектом вернёт объект, а с чем угодно, кроме объекта — возвратит, как обычно, this.

Например, возврат объекта:

function BigAnimal() { this.name = "Мышь";

return { name: "Годзилла" }; // < возвратим объект

}

alert( new BigAnimal().name ); // Годзилла, получили объект вместо this

А вот пример с возвратом строки:

function BigAnimal() { this.name = "Мышь";

return "Годзилла"; // < возвратим примитив

}

alert( new BigAnimal().name ); // Мышь, получили this (а Годзилла пропал)

Эта особенность работы newпрописана в стандарте, но используется она весьма редко.

Можно без скобок

Кстати, при вызове newбез аргументов скобки можно не ставить:

var animal = new BigAnimal; // < без скобок

// то же самое что

var animal = new BigAnimal();

Не сказать, что выбрасывание скобок — «хороший стиль», но такой синтаксис допустим стандартом.

Создание методов в конструкторе

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

Добавим в создаваемый объект ещё и метод.

Например, new User(name)создает объект с заданным значением свойства nameи методом sayHi:

function User(name) { this.name = name;

this.sayHi = function() {

alert( "Моё имя: " + this.name ); };

}

var ivan = new User("Иван");

ivan.sayHi(); // Моё имя: Иван

/*

ivan = {

name: "Иван", sayHi: функция

}

*/

Локальные переменные

В функции-конструкторе бывает удобно объявить вспомогательные локальные переменные и

вложенные функции, которые будут видны только внутри:

function User(firstName, lastName) {

//вспомогательная переменная var phrase = "Привет";

//вспомогательная вложенная функция function getFullName() {

return firstName + " " + lastName;

}

this.sayHi = function() {

alert( phrase + ", " + getFullName() ); // использование };

}

var vasya = new User("Вася", "Петров"); vasya.sayHi(); // Привет, Вася Петров

Мы уже говорили об этом подходе ранее, в главе Локальные переменные для объекта.

Те функции и данные, которые должны быть доступны для внешнего кода, мы пишем в this— и к ним можно будет обращаться, как например vasya.sayHi(), а вспомогательные, которые нужны только внутри самого объекта, сохраняем в локальной области видимости.

Итого

Объекты могут быть созданы при помощи функций-конструкторов:

Любая функция может быть вызвана с new, при этом она получает новый пустой объект в качестве this, в который она добавляет свойства. Если функция не решит возвратить свой объект, то её результатом будет this.

Функции, которые предназначены для создания объектов, называются конструкторами. Их названия пишут с большой буквы, чтобы отличать от обычных.

Задачи

Две функции один объект

важность: 2

Возможны ли такие функции Aи Bв примере ниже, что соответствующие объекты a,bравны (см. код ниже)?

function A() { ... } function B() { ... }

var a = new A; var b = new B;

alert( a == b ); // true

Если да — приведите пример кода с такими функциями.

К решению

Создать Calculator при помощи конструктора

важность: 5

Напишите функцию-конструктор Calculator, которая создает объект с тремя методами:

Метод read()запрашивает два значения при помощи promptи запоминает их в свойствах объекта.

Метод sum()возвращает сумму запомненных свойств.

Метод mul()возвращает произведение запомненных свойств.

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

var calculator = new Calculator(); calculator.read();

alert( "Сумма=" + calculator.sum() ); alert( "Произведение=" + calculator.mul() );

Запустить демо

Открыть песочницу с тестами для задачи.

К решению

Создать Accumulator при помощи конструктора

важность: 5

Напишите функцию-конструктор Accumulator(startingValue). Объекты, которые она создает, должны хранить текущую сумму и прибавлять к ней то, что вводит посетитель.

Более формально, объект должен:

Хранить текущее значение в своём свойстве value. Начальное значение свойства valueставится конструктором равным startingValue.

Метод read()вызывает prompt, принимает число и прибавляет его к свойству value.

Таким образом, свойство valueявляется текущей суммой всего, что ввел посетитель при вызовах метода read(), с учетом начального значения startingValue.

Ниже вы можете посмотреть работу кода:

var accumulator = new Accumulator(1); // начальное значение 1 accumulator.read(); // прибавит ввод prompt к текущему значению accumulator.read(); // прибавит ввод prompt к текущему значению alert( accumulator.value ); // выведет текущее значение

Запустить демо

Открыть песочницу с тестами для задачи.

К решению

Создайте калькулятор

важность: 5

Напишите конструктор Calculator, который создаёт расширяемые объекты-калькуляторы.

Эта задача состоит из двух частей, которые можно решать одна за другой.

1.Первый шаг задачи: вызов calculate(str)принимает строку, например «1 + 2», с жёстко

заданным форматом «ЧИСЛО операция ЧИСЛО» (по одному пробелу вокруг операции), и возвращает результат. Понимает плюс +и минус .

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

var calc = new Calculator;

alert( calc.calculate("3 + 7") ); // 10

2.Второй шаг — добавить калькулятору метод addMethod(name, func), который учит калькулятор новой операции. Он получает имя операции nameи функцию от двух аргументов func(a,b), которая должна её реализовывать.

Например, добавим операции умножить *, поделить /и возвести в степень **:

var powerCalc = new Calculator; powerCalc.addMethod("*", function(a, b) {

return a * b; });

powerCalc.addMethod("/", function(a, b) { return a / b;

});

powerCalc.addMethod("**", function(a, b) { return Math.pow(a, b);

});

var result = powerCalc.calculate("2 ** 3"); alert( result ); // 8

Поддержка скобок и сложных математических выражений в этой задаче не требуется.

Числа и операции могут состоять из нескольких символов. Между ними ровно один пробел.