beautify 1st part of the tutorial
This commit is contained in:
parent
e3dd2cedc0
commit
6444024a9d
327 changed files with 2358 additions and 1986 deletions
|
@ -3,9 +3,9 @@
|
|||
```js
|
||||
//+ run untrusted refresh
|
||||
if ("a" in window) {
|
||||
var a = 1;
|
||||
var a = 1;
|
||||
}
|
||||
alert(a);
|
||||
alert( a );
|
||||
```
|
||||
|
||||
Посмотрим, почему.
|
||||
|
@ -16,9 +16,9 @@ alert(a);
|
|||
// window = {a:undefined}
|
||||
|
||||
if ("a" in window) { // в if видно что window.a уже есть
|
||||
var a = 1; // поэтому эта строка сработает
|
||||
var a = 1; // поэтому эта строка сработает
|
||||
}
|
||||
alert(a);
|
||||
alert( a );
|
||||
```
|
||||
|
||||
В результате `a` становится `1`.
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
```js
|
||||
if ("a" in window) {
|
||||
var a = 1;
|
||||
var a = 1;
|
||||
}
|
||||
alert(a);
|
||||
alert( a );
|
||||
```
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
```js
|
||||
//+ run untrusted refresh
|
||||
if ("a" in window) {
|
||||
a = 1;
|
||||
}
|
||||
alert(a); // <-- error!
|
||||
a = 1;
|
||||
}
|
||||
alert( a ); // <-- error!
|
||||
```
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
```js
|
||||
if ("a" in window) {
|
||||
a = 1;
|
||||
a = 1;
|
||||
}
|
||||
alert(a);
|
||||
alert( a );
|
||||
```
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
```js
|
||||
//+ run untrusted refresh
|
||||
if ("a" in window) {
|
||||
a = 1;
|
||||
a = 1;
|
||||
}
|
||||
var a;
|
||||
|
||||
alert(a); // 1
|
||||
alert( a ); // 1
|
||||
```
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
```js
|
||||
if ("a" in window) {
|
||||
a = 1;
|
||||
a = 1;
|
||||
}
|
||||
var a;
|
||||
|
||||
alert(a);
|
||||
alert( a );
|
||||
```
|
||||
|
||||
|
|
|
@ -22,16 +22,16 @@
|
|||
|
||||
```js
|
||||
//+ run untrusted refresh
|
||||
var a = 5; // объявление var создаёт свойство window.a
|
||||
alert(window.a); // 5
|
||||
var a = 5; // объявление var создаёт свойство window.a
|
||||
alert( window.a ); // 5
|
||||
```
|
||||
|
||||
Создать переменную можно и явным присваиванием в `window`:
|
||||
|
||||
```js
|
||||
//+ run untrusted refresh
|
||||
window.a = 5;
|
||||
alert(a); // 5
|
||||
window.a = 5;
|
||||
alert( a ); // 5
|
||||
```
|
||||
|
||||
## Порядок инициализации
|
||||
|
@ -88,7 +88,7 @@ var g = function() { /*...*/ };
|
|||
//+ run
|
||||
a = 5;
|
||||
|
||||
alert(a); // 5
|
||||
alert( a ); // 5
|
||||
```
|
||||
|
||||
Такое присвоение, как и `var a = 5`, создает свойство `window.a = 5`. Отличие от `var a = 5` -- в том, что переменная будет создана не на этапе входа в область видимости, а в момент присвоения.
|
||||
|
@ -100,7 +100,7 @@ alert(a); // 5
|
|||
```js
|
||||
//+ run untrusted refresh
|
||||
*!*
|
||||
alert(a); // undefined
|
||||
alert( a ); // undefined
|
||||
*/!*
|
||||
|
||||
var a = 5;
|
||||
|
@ -111,7 +111,7 @@ var a = 5;
|
|||
```js
|
||||
//+ run untrusted refresh
|
||||
*!*
|
||||
alert(a); // error, a is not defined
|
||||
alert( a ); // error, a is not defined
|
||||
*/!*
|
||||
|
||||
a = 5;
|
||||
|
@ -166,7 +166,7 @@ for (i=0; i<5; i++) { }
|
|||
```js
|
||||
var i = 10;
|
||||
|
||||
for (var i=0; i<20; i++) {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -189,9 +189,9 @@ var i = 5;
|
|||
```html
|
||||
<!--+ run -->
|
||||
<div id="a">...</div>
|
||||
<script>
|
||||
a = 5; // ошибка в IE8-! Правильно будет "var a = 5"
|
||||
alert(a); // никогда не сработает
|
||||
<script>
|
||||
a = 5; // ошибка в IE8-! Правильно будет "var a = 5"
|
||||
alert( a ); // никогда не сработает
|
||||
</script>
|
||||
```
|
||||
|
||||
|
@ -205,12 +205,12 @@ var i = 5;
|
|||
```html
|
||||
<!--+ run height=0 -->
|
||||
<script>
|
||||
// рекурсия через функцию, явно записанную в window
|
||||
window.recurse = function(times) {
|
||||
if (times !== 0) recurse(times-1);
|
||||
}
|
||||
// рекурсия через функцию, явно записанную в window
|
||||
window.recurse = function(times) {
|
||||
if (times !== 0) recurse(times - 1);
|
||||
}
|
||||
|
||||
recurse(13);
|
||||
recurse(13);
|
||||
</script>
|
||||
```
|
||||
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
|
||||
```js
|
||||
//+ run
|
||||
|
||||
*!*
|
||||
say('Вася'); // Что выведет? Не будет ли ошибки?
|
||||
say('Вася'); // Что выведет? Не будет ли ошибки?
|
||||
*/!*
|
||||
|
||||
var phrase = 'Привет';
|
||||
|
||||
function say(name) {
|
||||
alert(name + ", " + phrase);
|
||||
alert( name + ", " + phrase );
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -5,15 +5,14 @@
|
|||
Что будет, если вызов `sayHi('Вася');` стоит в самом-самом начале, в первой строке кода?
|
||||
|
||||
```js
|
||||
|
||||
*!*
|
||||
say('Вася'); // Что выведет? Не будет ли ошибки?
|
||||
say('Вася'); // Что выведет? Не будет ли ошибки?
|
||||
*/!*
|
||||
|
||||
var phrase = 'Привет';
|
||||
|
||||
function say(name) {
|
||||
alert(name + ", " + phrase);
|
||||
alert( name + ", " + phrase );
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
```js
|
||||
var value = 0;
|
||||
|
||||
function f() {
|
||||
function f() {
|
||||
if (1) {
|
||||
value = true;
|
||||
} else {
|
||||
var value = false;
|
||||
}
|
||||
|
||||
alert(value);
|
||||
alert( value );
|
||||
}
|
||||
|
||||
f();
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
```js
|
||||
//+ run
|
||||
function test() {
|
||||
|
||||
alert(window);
|
||||
|
||||
alert( window );
|
||||
|
||||
var window = 5;
|
||||
|
||||
alert(window);
|
||||
alert( window );
|
||||
}
|
||||
|
||||
test();
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
```js
|
||||
function test() {
|
||||
|
||||
alert(window);
|
||||
|
||||
alert( window );
|
||||
|
||||
var window = 5;
|
||||
|
||||
alert(window);
|
||||
alert( window );
|
||||
}
|
||||
|
||||
test();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Результат - **ошибка**. Попробуйте:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
var a = 5
|
||||
|
||||
(function() {
|
||||
|
@ -14,7 +14,7 @@ var a = 5
|
|||
JavaScript воспринимает этот код как если бы перевода строки не было:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
var a = 5(function() {
|
||||
alert(a)
|
||||
})()
|
||||
|
@ -25,7 +25,7 @@ var a = 5(function() {
|
|||
Если точку с запятой поставить, все будет хорошо:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
var a = 5;
|
||||
|
||||
(function() {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Каков будет результат выполнения кода? Почему?
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
var a = 5
|
||||
|
||||
(function() {
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
```js
|
||||
function makeCounter() {
|
||||
var currentCount = 1;
|
||||
|
||||
return function() {
|
||||
|
||||
return function() {
|
||||
var currentCount;
|
||||
// можно ли здесь вывести currentCount из внешней функции (равный 1)?
|
||||
};
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
//+ run
|
||||
var currentCount = 1;
|
||||
|
||||
function makeCounter() {
|
||||
return function() {
|
||||
return currentCount++;
|
||||
function makeCounter() {
|
||||
return function() {
|
||||
return currentCount++;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
```js
|
||||
var currentCount = 1;
|
||||
|
||||
function makeCounter() {
|
||||
return function() {
|
||||
return currentCount++;
|
||||
function makeCounter() {
|
||||
return function() {
|
||||
return currentCount++;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
```js
|
||||
function sayHi(name) {
|
||||
var phrase = "Привет, " + name;
|
||||
alert(phrase);
|
||||
alert( phrase );
|
||||
}
|
||||
|
||||
sayHi('Вася');
|
||||
|
@ -37,7 +37,7 @@ function sayHi(name) {
|
|||
// LexicalEnvironment = { name: 'Вася', phrase: undefined }
|
||||
*/!*
|
||||
var phrase = "Привет, " + name;
|
||||
alert(phrase);
|
||||
alert( phrase );
|
||||
}
|
||||
|
||||
sayHi('Вася');
|
||||
|
@ -56,7 +56,7 @@ function sayHi(name) {
|
|||
*!*
|
||||
// LexicalEnvironment = { name: 'Вася', phrase: 'Привет, Вася'}
|
||||
*/!*
|
||||
alert(phrase);
|
||||
alert( phrase );
|
||||
}
|
||||
|
||||
sayHi('Вася');
|
||||
|
@ -83,7 +83,7 @@ sayHi('Вася');
|
|||
var userName = "Вася";
|
||||
|
||||
function sayHi() {
|
||||
alert(userName); // "Вася"
|
||||
alert( userName ); // "Вася"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -95,6 +95,7 @@ function sayHi() {
|
|||
|
||||
В примере выше таким окружением является `window`, так что создаётся свойство:
|
||||
```js
|
||||
//+ no-beautify
|
||||
sayHi.[[Scope]] = window
|
||||
```
|
||||
|
||||
|
@ -122,7 +123,7 @@ sayHi.[[Scope]] = window
|
|||
Например, в коде ниже функция `sayHi` берёт `phrase` из внешней области:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
|
||||
var phrase = 'Привет';
|
||||
|
||||
|
@ -161,8 +162,8 @@ function sayHiBye(firstName, lastName) {
|
|||
|
||||
*!*
|
||||
function getFullName() {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
*/!*
|
||||
|
||||
}
|
||||
|
@ -175,6 +176,7 @@ sayHiBye("Вася", "Пупкин"); // Привет, Вася Пупкин ;
|
|||
Вложенные функции получают `[[Scope]]` так же, как и глобальные. В нашем случае:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
getFullName.[[Scope]] = объект переменных текущего запуска sayHiBye
|
||||
```
|
||||
|
||||
|
@ -187,9 +189,9 @@ getFullName.[[Scope]] = объект переменных текущего за
|
|||
var phrase = 'Привет';
|
||||
|
||||
function say() {
|
||||
|
||||
|
||||
function go() {
|
||||
alert(phrase); // найдёт переменную снаружи
|
||||
alert( phrase ); // найдёт переменную снаружи
|
||||
}
|
||||
|
||||
go();
|
||||
|
@ -214,7 +216,7 @@ function makeCounter() {
|
|||
*/!*
|
||||
|
||||
return function() { // (**)
|
||||
return currentCount++;
|
||||
return currentCount++;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -250,7 +252,7 @@ function makeCounter() {
|
|||
*!*
|
||||
// LexicalEnvironment = { currentCount: 1 }
|
||||
*/!*
|
||||
|
||||
|
||||
return function() { // [[Scope]] -> LexicalEnvironment (**)
|
||||
return currentCount++;
|
||||
};
|
||||
|
@ -288,9 +290,9 @@ function() { // [[Scope]] -> {currentCount: 1}
|
|||
//+ run
|
||||
function makeCounter() {
|
||||
var currentCount = 1;
|
||||
|
||||
return function() {
|
||||
return currentCount++;
|
||||
|
||||
return function() {
|
||||
return currentCount++;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -298,7 +300,7 @@ var counter = makeCounter(); // [[Scope]] -> {currentCount: 1}
|
|||
|
||||
alert( counter() ); // 1, [[Scope]] -> {currentCount: 1}
|
||||
alert( counter() ); // 2, [[Scope]] -> {currentCount: 2}
|
||||
alert( counter() ); // 3, [[Scope]] -> {currentCount: 3}
|
||||
alert( counter() ); // 3, [[Scope]] -> {currentCount: 3}
|
||||
```
|
||||
|
||||
**Переменную во внешней области видимости можно не только читать, но и изменять.**
|
||||
|
@ -330,7 +332,7 @@ alert( counter2() ); // 1, *!*счётчики независимы*/!*
|
|||
function f() {}
|
||||
|
||||
f.test = 5;
|
||||
alert(f.test);
|
||||
alert( f.test );
|
||||
```
|
||||
|
||||
Свойства функции не стоит путать с переменными и параметрами. Они совершенно никак не связаны. Переменные доступны только внутри функции, они создаются в процессе её выполнения. Это -- использование функции "как функции".
|
||||
|
@ -343,10 +345,10 @@ alert(f.test);
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function makeCounter() {
|
||||
function makeCounter() {
|
||||
*!*
|
||||
function counter() {
|
||||
return counter.currentCount++;
|
||||
function counter() {
|
||||
return counter.currentCount++;
|
||||
};
|
||||
counter.currentCount = 1;
|
||||
*/!*
|
||||
|
@ -354,7 +356,7 @@ function makeCounter() {
|
|||
return counter;
|
||||
}
|
||||
|
||||
var counter = makeCounter();
|
||||
var counter = makeCounter();
|
||||
alert( counter() ); // 1
|
||||
alert( counter() ); // 2
|
||||
```
|
||||
|
@ -366,7 +368,7 @@ alert( counter() ); // 2
|
|||
Например, можно взять и поменять счётчик из внешнего кода:
|
||||
|
||||
```js
|
||||
var counter = makeCounter();
|
||||
var counter = makeCounter();
|
||||
alert( counter() ); // 1
|
||||
|
||||
*!*
|
||||
|
|
|
@ -73,7 +73,7 @@ getFunc()(); // *!*2*/!*, из LexicalEnvironment функции getFunc
|
|||
Ну а если внутри функции, создаваемой через `new Function`, всё же нужно использовать какие-то данные -- без проблем, нужно всего лишь предусмотреть соответствующие параметры и передавать их явным образом, например так:
|
||||
|
||||
```js
|
||||
//+ run untrusted refresh
|
||||
//+ run untrusted refresh no-beautify
|
||||
*!*
|
||||
var sum = new Function('a, b', ' return a + b; ');
|
||||
*/!*
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//+ run
|
||||
function sum(a) {
|
||||
|
||||
return function(b) {
|
||||
return a + b; // возьмет a из внешнего LexicalEnvironment
|
||||
return function(b) {
|
||||
return a + b; // возьмет a из внешнего LexicalEnvironment
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,26 +3,28 @@
|
|||
```js
|
||||
//+ run
|
||||
function makeBuffer() {
|
||||
var text = '';
|
||||
|
||||
var text = '';
|
||||
|
||||
return function(piece) {
|
||||
if (arguments.length == 0) { // вызов без аргументов
|
||||
return text;
|
||||
}
|
||||
text += piece;
|
||||
text += piece;
|
||||
};
|
||||
};
|
||||
|
||||
var buffer = makeBuffer();
|
||||
|
||||
// добавить значения к буферу
|
||||
buffer('Замыкания');
|
||||
buffer(' Использовать');
|
||||
buffer(' Нужно!');
|
||||
buffer('Замыкания');
|
||||
buffer(' Использовать');
|
||||
buffer(' Нужно!');
|
||||
alert( buffer() ); // 'Замыкания Использовать Нужно!'
|
||||
|
||||
var buffer2 = makeBuffer();
|
||||
buffer2(0); buffer2(1); buffer2(0);
|
||||
buffer2(0);
|
||||
buffer2(1);
|
||||
buffer2(0);
|
||||
|
||||
alert( buffer2() ); // '010'
|
||||
```
|
||||
|
|
|
@ -23,9 +23,9 @@ function makeBuffer() { /* ваш код */ }
|
|||
var buffer = makeBuffer();
|
||||
|
||||
// добавить значения к буферу
|
||||
buffer('Замыкания');
|
||||
buffer(' Использовать');
|
||||
buffer(' Нужно!');
|
||||
buffer('Замыкания');
|
||||
buffer(' Использовать');
|
||||
buffer(' Нужно!');
|
||||
|
||||
// получить текущее значение
|
||||
alert( buffer() ); // Замыкания Использовать Нужно!
|
||||
|
@ -35,7 +35,9 @@ alert( buffer() ); // Замыкания Использовать Нужно!
|
|||
|
||||
```js
|
||||
var buffer = makeBuffer();
|
||||
buffer(0); buffer(1); buffer(0);
|
||||
buffer(0);
|
||||
buffer(1);
|
||||
buffer(0);
|
||||
|
||||
alert( buffer() ); // '010'
|
||||
```
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
```js
|
||||
//+ run
|
||||
function makeBuffer() {
|
||||
var text = '';
|
||||
|
||||
var text = '';
|
||||
|
||||
function buffer(piece) {
|
||||
if (arguments.length == 0) { // вызов без аргументов
|
||||
return text;
|
||||
}
|
||||
text += piece;
|
||||
text += piece;
|
||||
};
|
||||
|
||||
buffer.clear = function() {
|
||||
|
|
|
@ -2,24 +2,36 @@
|
|||
|
||||
```js
|
||||
//+ run
|
||||
var users = [
|
||||
{ name: "Вася", surname: 'Иванов', age: 20 },
|
||||
{ name: "Петя", surname: 'Чапаев', age: 25 },
|
||||
{ name: "Маша", surname: 'Медведева', age: 18 }
|
||||
];
|
||||
var users = [{
|
||||
name: "Вася",
|
||||
surname: 'Иванов',
|
||||
age: 20
|
||||
}, {
|
||||
name: "Петя",
|
||||
surname: 'Чапаев',
|
||||
age: 25
|
||||
}, {
|
||||
name: "Маша",
|
||||
surname: 'Медведева',
|
||||
age: 18
|
||||
}];
|
||||
|
||||
*!*
|
||||
function byField(field) {
|
||||
return function(a, b) {
|
||||
return a[field] > b[field] ? 1: -1;
|
||||
return function(a, b) {
|
||||
return a[field] > b[field] ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/!*
|
||||
|
||||
users.sort(byField('name'));
|
||||
users.forEach(function(user) { alert(user.name); });
|
||||
users.forEach(function(user) {
|
||||
alert( user.name );
|
||||
});
|
||||
|
||||
users.sort(byField('age'));
|
||||
users.forEach(function(user) { alert(user.name); });
|
||||
users.forEach(function(user) {
|
||||
alert( user.name );
|
||||
});
|
||||
```
|
||||
|
||||
|
|
|
@ -5,35 +5,47 @@
|
|||
У нас есть массив объектов:
|
||||
|
||||
```js
|
||||
var users = [
|
||||
{ name: "Вася", surname: 'Иванов', age: 20 },
|
||||
{ name: "Петя", surname: 'Чапаев', age: 25 },
|
||||
{ name: "Маша", surname: 'Медведева', age: 18 }
|
||||
];
|
||||
var users = [{
|
||||
name: "Вася",
|
||||
surname: 'Иванов',
|
||||
age: 20
|
||||
}, {
|
||||
name: "Петя",
|
||||
surname: 'Чапаев',
|
||||
age: 25
|
||||
}, {
|
||||
name: "Маша",
|
||||
surname: 'Медведева',
|
||||
age: 18
|
||||
}];
|
||||
```
|
||||
|
||||
Обычно сортировка по нужному полю происходит так:
|
||||
|
||||
```js
|
||||
// по полю name (Вася, Маша, Петя)
|
||||
users.sort(function(a, b) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
users.sort(function(a, b) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
});
|
||||
|
||||
// по полю age (Маша, Вася, Петя)
|
||||
users.sort(function(a, b) {
|
||||
return a.age > b.age ? 1 : -1;
|
||||
users.sort(function(a, b) {
|
||||
return a.age > b.age ? 1 : -1;
|
||||
});
|
||||
```
|
||||
|
||||
Мы хотели бы упростить синтаксис до одной строки, вот так:
|
||||
|
||||
```js
|
||||
users.sort(byField('name'));
|
||||
users.forEach(function(user) { alert(user.name); }); // Вася, Маша, Петя
|
||||
users.sort(byField('name'));
|
||||
users.forEach(function(user) {
|
||||
alert( user.name );
|
||||
}); // Вася, Маша, Петя
|
||||
|
||||
users.sort(byField('age'));
|
||||
users.forEach(function(user) { alert(user.name); }); // Маша, Вася, Петя
|
||||
users.sort(byField('age'));
|
||||
users.forEach(function(user) {
|
||||
alert( user.name );
|
||||
}); // Маша, Вася, Петя
|
||||
```
|
||||
|
||||
То есть, вместо того, чтобы каждый раз писать в `sort` `function...` -- будем использовать `byField(...)`
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
function filter(arr, func) {
|
||||
var result = [];
|
||||
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var val = arr[i];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var val = arr[i];
|
||||
if (func(val)) {
|
||||
result.push(val);
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ function filter(arr, func) {
|
|||
|
||||
var arr = [1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
alert( filter(arr, function(a) { return a % 2 == 0; }) ); // 2, 4, 6
|
||||
alert(filter(arr, function(a) {
|
||||
return a % 2 == 0;
|
||||
})); // 2, 4, 6
|
||||
```
|
||||
|
||||
# Фильтр inBetween
|
||||
|
@ -27,8 +29,8 @@ alert( filter(arr, function(a) { return a % 2 == 0; }) ); // 2, 4, 6
|
|||
function filter(arr, func) {
|
||||
var result = [];
|
||||
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var val = arr[i];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var val = arr[i];
|
||||
if (func(val)) {
|
||||
result.push(val);
|
||||
}
|
||||
|
@ -39,14 +41,14 @@ function filter(arr, func) {
|
|||
|
||||
*!*
|
||||
function inBetween(a, b) {
|
||||
return function(x) {
|
||||
return x >=a && x <= b;
|
||||
};
|
||||
}
|
||||
return function(x) {
|
||||
return x >= a && x <= b;
|
||||
};
|
||||
}
|
||||
*/!*
|
||||
|
||||
var arr = [1, 2, 3, 4, 5, 6, 7];
|
||||
alert( filter(arr, inBetween(3,6)) ); // 3,4,5,6
|
||||
alert( filter(arr, inBetween(3, 6)) ); // 3,4,5,6
|
||||
```
|
||||
|
||||
# Фильтр inArray
|
||||
|
@ -56,8 +58,8 @@ alert( filter(arr, inBetween(3,6)) ); // 3,4,5,6
|
|||
function filter(arr, func) {
|
||||
var result = [];
|
||||
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var val = arr[i];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var val = arr[i];
|
||||
if (func(val)) {
|
||||
result.push(val);
|
||||
}
|
||||
|
@ -68,13 +70,13 @@ function filter(arr, func) {
|
|||
|
||||
*!*
|
||||
function inArray(arr) {
|
||||
return function(x) {
|
||||
return arr.indexOf(x) != -1;
|
||||
};
|
||||
}
|
||||
return function(x) {
|
||||
return arr.indexOf(x) != -1;
|
||||
};
|
||||
}
|
||||
*/!*
|
||||
|
||||
var arr = [1, 2, 3, 4, 5, 6, 7];
|
||||
alert( filter(arr, inArray([1,2,10])) ); // 1,2
|
||||
alert( filter(arr, inArray([1, 2, 10])) ); // 1,2
|
||||
```
|
||||
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
/* .. ваш код для filter, inBetween, inArray */
|
||||
var arr = [1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
alert( filter(arr, function(a) { return a % 2 == 0 }) ); // 2,4,6
|
||||
alert(filter(arr, function(a) {
|
||||
return a % 2 == 0
|
||||
})); // 2,4,6
|
||||
|
||||
alert( filter(arr, inBetween(3,6)) ); // 3,4,5,6
|
||||
alert( filter(arr, inBetween(3, 6)) ); // 3,4,5,6
|
||||
|
||||
alert( filter(arr, inArray([1,2,10])) ); // 1,2
|
||||
alert( filter(arr, inArray([1, 2, 10])) ); // 1,2
|
||||
```
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ var shooters = [];
|
|||
При этом каждый элемент массива -- это функция, так что в итоге после цикла массив будет таким:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
shooters = [
|
||||
function () { alert(i); },
|
||||
function () { alert(i); },
|
||||
|
@ -59,19 +60,19 @@ function makeArmy() {
|
|||
|
||||
var shooters = [];
|
||||
|
||||
for(var i=0; i<10; i++) {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
|
||||
*!*
|
||||
var shooter = function me() {
|
||||
alert( me.i );
|
||||
alert( me.i );
|
||||
};
|
||||
shooter.i = i;
|
||||
*/!*
|
||||
|
||||
shooters.push(shooter);
|
||||
shooters.push(shooter);
|
||||
}
|
||||
|
||||
return shooters;
|
||||
return shooters;
|
||||
}
|
||||
|
||||
var army = makeArmy();
|
||||
|
@ -87,7 +88,7 @@ army[1](); // 1
|
|||
```js
|
||||
...
|
||||
var shooter = function me() {
|
||||
alert( me.i );
|
||||
alert( me.i );
|
||||
};
|
||||
...
|
||||
```
|
||||
|
@ -95,10 +96,10 @@ var shooter = function me() {
|
|||
Если убрать имя `me` и оставить обращение через `shooter`, то работать не будет:
|
||||
|
||||
```js
|
||||
for(var i=0; i<10; i++) {
|
||||
var shooter = function() {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var shooter = function() {
|
||||
*!*
|
||||
alert(shooter.i); // вывести свой номер (не работает!)
|
||||
alert( shooter.i ); // вывести свой номер (не работает!)
|
||||
// потому что откуда функция возьмёт переменную shooter?
|
||||
// ..правильно, из внешнего объекта, а там она одна на всех
|
||||
*/!*
|
||||
|
@ -121,22 +122,22 @@ function makeArmy() {
|
|||
|
||||
var shooters = [];
|
||||
|
||||
for(var i=0; i<10; i++) {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
|
||||
*!*
|
||||
var shooter = (function(x) {
|
||||
|
||||
return function() {
|
||||
alert( x );
|
||||
alert( x );
|
||||
};
|
||||
|
||||
})(i);
|
||||
*/!*
|
||||
|
||||
shooters.push(shooter);
|
||||
shooters.push(shooter);
|
||||
}
|
||||
|
||||
return shooters;
|
||||
return shooters;
|
||||
}
|
||||
|
||||
var army = makeArmy();
|
||||
|
@ -150,7 +151,7 @@ army[1](); // 1
|
|||
```js
|
||||
var shooter = (function(x) {
|
||||
return function() {
|
||||
alert( x );
|
||||
alert( x );
|
||||
};
|
||||
})(i);
|
||||
```
|
||||
|
@ -164,7 +165,7 @@ var shooter = (function(x) {
|
|||
```js
|
||||
var shooter = (function(i) {
|
||||
return function() {
|
||||
alert( i );
|
||||
alert( i );
|
||||
};
|
||||
})(i);
|
||||
```
|
||||
|
@ -190,18 +191,18 @@ function makeArmy() {
|
|||
var shooters = [];
|
||||
|
||||
*!*
|
||||
for(var i=0; i<10; i++) (function(i) {
|
||||
for (var i = 0; i < 10; i++)(function(i) {
|
||||
|
||||
var shooter = function() {
|
||||
alert( i );
|
||||
alert( i );
|
||||
};
|
||||
|
||||
shooters.push(shooter);
|
||||
|
||||
|
||||
shooters.push(shooter);
|
||||
|
||||
})(i);
|
||||
*/!*
|
||||
|
||||
return shooters;
|
||||
return shooters;
|
||||
}
|
||||
|
||||
var army = makeArmy();
|
||||
|
|
|
@ -10,9 +10,9 @@ function makeArmy() {
|
|||
|
||||
var shooters = [];
|
||||
|
||||
for(var i=0; i<10; i++) {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var shooter = function() { // функция-стрелок
|
||||
alert(i); // выводит свой номер
|
||||
alert( i ); // выводит свой номер
|
||||
};
|
||||
shooters.push(shooter);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
//+ run
|
||||
function makeCounter() {
|
||||
var currentCount = 1;
|
||||
|
||||
return function() {
|
||||
return currentCount++;
|
||||
|
||||
return function() {
|
||||
return currentCount++;
|
||||
};
|
||||
}
|
||||
|
||||
var counter = makeCounter();
|
||||
var counter = makeCounter();
|
||||
|
||||
// каждый вызов увеличивает счётчик и возвращает результат
|
||||
alert( counter() ); // 1
|
||||
|
@ -38,13 +38,13 @@ alert( counter() ); // 3
|
|||
//+ run
|
||||
function makeCounter() {
|
||||
var currentCount = 1;
|
||||
|
||||
return { // возвратим объект вместо функции
|
||||
getNext: function() {
|
||||
|
||||
return { // возвратим объект вместо функции
|
||||
getNext: function() {
|
||||
return currentCount++;
|
||||
},
|
||||
|
||||
set: function(value) {
|
||||
|
||||
set: function(value) {
|
||||
currentCount = value;
|
||||
},
|
||||
|
||||
|
@ -85,16 +85,16 @@ alert( counter.getNext() ); // 5
|
|||
//+ run
|
||||
function makeCounter() {
|
||||
var currentCount = 1;
|
||||
|
||||
|
||||
*!*
|
||||
// возвращаемся к функции
|
||||
function counter() {
|
||||
return currentCount++;
|
||||
}
|
||||
function counter() {
|
||||
return currentCount++;
|
||||
}
|
||||
*/!*
|
||||
|
||||
// ...и добавляем ей методы!
|
||||
counter.set = function(value) {
|
||||
counter.set = function(value) {
|
||||
currentCount = value;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ var message = "Привет";
|
|||
|
||||
// функция для вывода этой переменной
|
||||
function showMessage() {
|
||||
alert(message);
|
||||
alert( message );
|
||||
}
|
||||
|
||||
// выводим сообщение
|
||||
|
@ -45,7 +45,7 @@ showMessage();
|
|||
<button>Кнопка</button>
|
||||
<script>
|
||||
// ожидается сообщение из переменной выше...
|
||||
alert(message); // но на самом деле будет введено "Привет"
|
||||
alert( message ); // но на самом деле будет введено "Привет"
|
||||
</script>
|
||||
```
|
||||
|
||||
|
@ -68,13 +68,13 @@ showMessage();
|
|||
```js
|
||||
//+ run
|
||||
(function() {
|
||||
|
||||
|
||||
// глобальная переменная нашего скрипта
|
||||
var message = "Привет";
|
||||
|
||||
// функция для вывода этой переменной
|
||||
function showMessage() {
|
||||
alert(message);
|
||||
alert( message );
|
||||
}
|
||||
|
||||
// выводим сообщение
|
||||
|
@ -97,8 +97,8 @@ showMessage();
|
|||
```js
|
||||
//+ run
|
||||
(function() {
|
||||
|
||||
alert("объявляем локальные переменные, функции, работаем");
|
||||
|
||||
alert( "объявляем локальные переменные, функции, работаем" );
|
||||
// ...
|
||||
|
||||
}());
|
||||
|
@ -111,7 +111,7 @@ showMessage();
|
|||
```js
|
||||
//+ run
|
||||
function() {
|
||||
// будет ошибка
|
||||
// будет ошибка
|
||||
}();
|
||||
```
|
||||
|
||||
|
@ -123,7 +123,7 @@ function() {
|
|||
//+ run
|
||||
function work() {
|
||||
// ...
|
||||
}(); // syntax error
|
||||
}(); // syntax error
|
||||
```
|
||||
|
||||
**Дело в том, что "на месте" разрешено вызывать *только* `Function Expression`.**
|
||||
|
@ -140,7 +140,7 @@ function work() {
|
|||
Можно показать это другим способом, например поставив перед функцией оператор:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
+function() {
|
||||
alert('Вызов на месте');
|
||||
}();
|
||||
|
@ -178,15 +178,20 @@ function work() {
|
|||
|
||||
<p>Функция <code>_.defaults()</code> добавляет отсутствующие свойства.</p>
|
||||
<script>
|
||||
var user = { name: 'Вася' };
|
||||
var user = {
|
||||
name: 'Вася'
|
||||
};
|
||||
|
||||
*!*
|
||||
_.defaults(user, { name: 'Не указано', employer: 'Не указан' });
|
||||
_.defaults(user, {
|
||||
name: 'Не указано',
|
||||
employer: 'Не указан'
|
||||
});
|
||||
*/!*
|
||||
|
||||
alert(user.name); // Вася
|
||||
alert(user.employer); // Не указан
|
||||
alert(_.size(user)); // 2
|
||||
alert( user.name ); // Вася
|
||||
alert( user.employer ); // Не указан
|
||||
alert( _.size(user) ); // 2
|
||||
</script>
|
||||
```
|
||||
|
||||
|
@ -196,7 +201,7 @@ alert(_.size(user)); // 2
|
|||
Вот выдержка из исходного файла:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
;(function() {
|
||||
|
||||
*!*
|
||||
|
@ -255,6 +260,7 @@ var a = 5
|
|||
|
||||
Второй файл `lib.js`:
|
||||
```js
|
||||
//+ no-beautify
|
||||
(function() {
|
||||
// без точки с запятой в начале
|
||||
})()
|
||||
|
@ -263,7 +269,7 @@ var a = 5
|
|||
После объединения в один файл:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
*!*
|
||||
var a = 5
|
||||
*/!*
|
||||
|
@ -285,6 +291,7 @@ var a = 5
|
|||
Можно оформить модуль и чуть по-другому, например передать значение через `return`:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
var lodash = (function() {
|
||||
|
||||
var version;
|
||||
|
|
|
@ -41,7 +41,9 @@
|
|||
Например, была создана ссылка в переменной, и эту переменную тут же перезаписали:
|
||||
|
||||
```js
|
||||
var user = { name: "Вася" };
|
||||
var user = {
|
||||
name: "Вася"
|
||||
};
|
||||
user = null;
|
||||
```
|
||||
|
||||
|
@ -87,7 +89,11 @@ function marry(man, woman) {
|
|||
}
|
||||
}
|
||||
|
||||
var family = marry({ name: "Василий" }, { name: "Мария"});
|
||||
var family = marry({
|
||||
name: "Василий"
|
||||
}, {
|
||||
name: "Мария"
|
||||
});
|
||||
```
|
||||
|
||||
Функция `marry` принимает два объекта, даёт им ссылки друг на друга и возвращает третий, содержащий ссылки на оба.
|
||||
|
@ -164,7 +170,7 @@ function showTime() {
|
|||
function f() {
|
||||
var value = 123;
|
||||
|
||||
function g() { } // g видна только изнутри
|
||||
function g() {} // g видна только изнутри
|
||||
}
|
||||
|
||||
f();
|
||||
|
@ -178,7 +184,7 @@ f();
|
|||
function f() {
|
||||
var value = 123;
|
||||
|
||||
function g() { }
|
||||
function g() {}
|
||||
|
||||
*!*
|
||||
return g;
|
||||
|
@ -197,7 +203,7 @@ var g = f(); // функция g будет жить и сохранит ссы
|
|||
function f() {
|
||||
var value = Math.random();
|
||||
|
||||
return function() { };
|
||||
return function() {};
|
||||
}
|
||||
|
||||
// 3 функции, каждая ссылается на свой объект переменных,
|
||||
|
@ -212,15 +218,15 @@ var arr = [f(), f(), f()];
|
|||
function f() {
|
||||
var value = 123;
|
||||
|
||||
function g() { }
|
||||
function g() {}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
var g = f(); // функция g жива
|
||||
var g = f(); // функция g жива
|
||||
// а значит в памяти остается соответствующий объект переменных f()
|
||||
|
||||
g = null; // ..а вот теперь память будет очищена
|
||||
g = null; // ..а вот теперь память будет очищена
|
||||
```
|
||||
|
||||
</li>
|
||||
|
@ -241,14 +247,14 @@ g = null; // ..а вот теперь память будет очищена
|
|||
function f() {
|
||||
var value = Math.random();
|
||||
|
||||
function g() {
|
||||
debugger; // выполните в консоли alert(value); Нет такой переменной!
|
||||
}
|
||||
function g() {
|
||||
debugger; // выполните в консоли alert( value ); Нет такой переменной!
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
var g = f();
|
||||
var g = f();
|
||||
g();
|
||||
```
|
||||
|
||||
|
@ -263,14 +269,14 @@ var value = "Сюрприз";
|
|||
function f() {
|
||||
var value = "самое близкое значение";
|
||||
|
||||
function g() {
|
||||
debugger; // выполните в консоли alert(value); Сюрприз!
|
||||
}
|
||||
function g() {
|
||||
debugger; // выполните в консоли alert( value ); Сюрприз!
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
var g = f();
|
||||
var g = f();
|
||||
g();
|
||||
```
|
||||
|
||||
|
@ -290,27 +296,27 @@ g();
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function sumTo(n) { // обычный цикл 1+2+...+n
|
||||
function sumTo(n) { // обычный цикл 1+2+...+n
|
||||
var result = 0;
|
||||
for (var i=1; i<=n; i++) {
|
||||
for (var i = 1; i <= n; i++) {
|
||||
result += i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function sumToRec(n) { // рекурсия sumToRec(n) = n+SumToRec(n-1)
|
||||
return n == 1 ? 1 : n + sumToRec(n-1);
|
||||
return n == 1 ? 1 : n + sumToRec(n - 1);
|
||||
}
|
||||
|
||||
var timeLoop = performance.now();
|
||||
for (var i=1;i<1000;i++) sumTo(1000); // цикл
|
||||
timeLoop = performance.now() - timeLoop;
|
||||
for (var i = 1; i < 1000; i++) sumTo(1000); // цикл
|
||||
timeLoop = performance.now() - timeLoop;
|
||||
|
||||
var timeRecursion = performance.now();
|
||||
for (var i=1;i<1000;i++) sumToRec(1000); // рекурсия
|
||||
for (var i = 1; i < 1000; i++) sumToRec(1000); // рекурсия
|
||||
timeRecursion = performance.now() - timeRecursion;
|
||||
|
||||
alert("Разница в " + ( timeRecursion / timeLoop ) + " раз");
|
||||
alert( "Разница в " + (timeRecursion / timeLoop) + " раз" );
|
||||
```
|
||||
|
||||
Различие в скорости на таком примере может составлять, в зависимости от интерпретатора, 2-10 раз.
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function f() { alert(1) }
|
||||
function f() {
|
||||
alert(1)
|
||||
}
|
||||
|
||||
var obj = {
|
||||
f: function() { alert(2) }
|
||||
var obj = {
|
||||
f: function() {
|
||||
alert(2)
|
||||
}
|
||||
};
|
||||
|
||||
with(obj) {
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
Какая из функций будет вызвана?
|
||||
|
||||
```js
|
||||
function f() { alert(1) }
|
||||
function f() {
|
||||
alert(1)
|
||||
}
|
||||
|
||||
var obj = {
|
||||
f: function() { alert(2) }
|
||||
var obj = {
|
||||
f: function() {
|
||||
alert(2)
|
||||
}
|
||||
};
|
||||
|
||||
with(obj) {
|
||||
|
|
|
@ -11,7 +11,9 @@ var a = 1;
|
|||
var b;
|
||||
*/!*
|
||||
|
||||
var obj = { b: 2 }
|
||||
var obj = {
|
||||
b: 2
|
||||
}
|
||||
|
||||
with(obj) {
|
||||
alert( a + b );
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
```js
|
||||
var a = 1;
|
||||
|
||||
var obj = { b: 2 };
|
||||
var obj = {
|
||||
b: 2
|
||||
};
|
||||
|
||||
with(obj) {
|
||||
var b;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
```js
|
||||
with(obj) {
|
||||
... код ...
|
||||
...код...
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -23,12 +23,14 @@ with(obj) {
|
|||
//+ run
|
||||
var a = 5;
|
||||
|
||||
var obj = { a : 10 };
|
||||
var obj = {
|
||||
a: 10
|
||||
};
|
||||
|
||||
*!*
|
||||
with(obj) {
|
||||
alert(a); // 10, из obj
|
||||
}
|
||||
alert( a ); // 10, из obj
|
||||
}
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -38,12 +40,14 @@ with(obj) {
|
|||
//+ run
|
||||
var b = 1;
|
||||
|
||||
var obj = { a : 10 };
|
||||
var obj = {
|
||||
a: 10
|
||||
};
|
||||
|
||||
*!*
|
||||
with(obj) {
|
||||
alert(b); // 1, из window
|
||||
}
|
||||
alert( b ); // 1, из window
|
||||
}
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -64,7 +68,7 @@ var obj = {
|
|||
with(obj) {
|
||||
with(size) { // size будет взят из obj
|
||||
*!*
|
||||
alert( width*height / weight ); // width,height из size, weight из obj
|
||||
alert( width * height / weight ); // width,height из size, weight из obj
|
||||
*/!*
|
||||
}
|
||||
}
|
||||
|
@ -81,14 +85,16 @@ with(obj) {
|
|||
|
||||
```js
|
||||
//+ run
|
||||
var obj = { a : 10 }
|
||||
var obj = {
|
||||
a: 10
|
||||
}
|
||||
|
||||
*!*
|
||||
with(obj) {
|
||||
a = 20;
|
||||
}
|
||||
a = 20;
|
||||
}
|
||||
*/!*
|
||||
alert(obj.a); // 20, переменная была изменена в объекте
|
||||
alert( obj.a ); // 20, переменная была изменена в объекте
|
||||
```
|
||||
|
||||
## Почему отказались от with?
|
||||
|
@ -104,15 +110,17 @@ alert(obj.a); // 20, переменная была изменена в объе
|
|||
|
||||
```js
|
||||
//+ run
|
||||
var obj = { weight: 10 };
|
||||
var obj = {
|
||||
weight: 10
|
||||
};
|
||||
|
||||
with(obj) {
|
||||
weight = 20; // (1)
|
||||
size = 35; // (2)
|
||||
size = 35; // (2)
|
||||
}
|
||||
|
||||
alert(obj.size);
|
||||
alert(window.size);
|
||||
alert( obj.size );
|
||||
alert( window.size );
|
||||
```
|
||||
|
||||
В строке `(2)` присваивается свойство, отсутствующее в `obj`. В результате интерпретатор, не найдя его, создает новую глобальную переменную `window.size`.
|
||||
|
@ -134,20 +142,20 @@ function fast() {
|
|||
i++;
|
||||
}
|
||||
|
||||
function slow() {
|
||||
function slow() {
|
||||
with(i) {}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
var time = performance.now();
|
||||
while(i < 1000000) fast();
|
||||
alert("Без with: " + (performance.now() - time));
|
||||
while (i < 1000000) fast();
|
||||
alert( "Без with: " + (performance.now() - time) );
|
||||
|
||||
var time = performance.now();
|
||||
i=0;
|
||||
while(i < 1000000) slow();
|
||||
alert("С with: " + (performance.now() - time));
|
||||
i = 0;
|
||||
while (i < 1000000) slow();
|
||||
alert( "С with: " + (performance.now() - time) );
|
||||
```
|
||||
|
||||
</li>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue