beautify 1st part of the tutorial

This commit is contained in:
Ilya Kantor 2015-03-10 12:36:58 +03:00
parent e3dd2cedc0
commit 6444024a9d
327 changed files with 2358 additions and 1986 deletions

View file

@ -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`.

View file

@ -6,8 +6,8 @@
```js
if ("a" in window) {
var a = 1;
var a = 1;
}
alert(a);
alert( a );
```

View file

@ -5,8 +5,8 @@
```js
//+ run untrusted refresh
if ("a" in window) {
a = 1;
}
alert(a); // <-- error!
a = 1;
}
alert( a ); // <-- error!
```

View file

@ -6,8 +6,8 @@
```js
if ("a" in window) {
a = 1;
a = 1;
}
alert(a);
alert( a );
```

View file

@ -5,10 +5,10 @@
```js
//+ run untrusted refresh
if ("a" in window) {
a = 1;
a = 1;
}
var a;
alert(a); // 1
alert( a ); // 1
```

View file

@ -6,10 +6,10 @@
```js
if ("a" in window) {
a = 1;
a = 1;
}
var a;
alert(a);
alert( a );
```

View file

@ -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>
```

View file

@ -2,15 +2,14 @@
```js
//+ run
*!*
say('Вася'); // Что выведет? Не будет ли ошибки?
say('Вася'); // Что выведет? Не будет ли ошибки?
*/!*
var phrase = 'Привет';
function say(name) {
alert(name + ", " + phrase);
alert( name + ", " + phrase );
}
```

View file

@ -5,15 +5,14 @@
Что будет, если вызов `sayHi('Вася');` стоит в самом-самом начале, в первой строке кода?
```js
*!*
say('Вася'); // Что выведет? Не будет ли ошибки?
say('Вася'); // Что выведет? Не будет ли ошибки?
*/!*
var phrase = 'Привет';
function say(name) {
alert(name + ", " + phrase);
alert( name + ", " + phrase );
}
```

View file

@ -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();

View file

@ -3,12 +3,12 @@
```js
//+ run
function test() {
alert(window);
alert( window );
var window = 5;
alert(window);
alert( window );
}
test();

View file

@ -6,12 +6,12 @@
```js
function test() {
alert(window);
alert( window );
var window = 5;
alert(window);
alert( window );
}
test();

View file

@ -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() {

View file

@ -5,6 +5,7 @@
Каков будет результат выполнения кода? Почему?
```js
//+ no-beautify
var a = 5
(function() {

View file

@ -7,8 +7,8 @@
```js
function makeCounter() {
var currentCount = 1;
return function() {
return function() {
var currentCount;
// можно ли здесь вывести currentCount из внешней функции (равный 1)?
};

View file

@ -8,9 +8,9 @@
//+ run
var currentCount = 1;
function makeCounter() {
return function() {
return currentCount++;
function makeCounter() {
return function() {
return currentCount++;
};
}

View file

@ -7,9 +7,9 @@
```js
var currentCount = 1;
function makeCounter() {
return function() {
return currentCount++;
function makeCounter() {
return function() {
return currentCount++;
};
}

View file

@ -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
*!*

View file

@ -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; ');
*/!*

View file

@ -6,8 +6,8 @@
//+ run
function sum(a) {
return function(b) {
return a + b; // возьмет a из внешнего LexicalEnvironment
return function(b) {
return a + b; // возьмет a из внешнего LexicalEnvironment
};
}

View file

@ -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'
```

View file

@ -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'
```

View file

@ -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() {

View file

@ -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 );
});
```

View file

@ -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(...)`

View file

@ -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
```

View file

@ -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
```

View file

@ -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();

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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 раз.

View file

@ -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) {

View file

@ -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) {

View file

@ -11,7 +11,9 @@ var a = 1;
var b;
*/!*
var obj = { b: 2 }
var obj = {
b: 2
}
with(obj) {
alert( a + b );

View file

@ -7,7 +7,9 @@
```js
var a = 1;
var obj = { b: 2 };
var obj = {
b: 2
};
with(obj) {
var b;

View file

@ -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>