beautify 1st part of the tutorial
This commit is contained in:
parent
e3dd2cedc0
commit
6444024a9d
327 changed files with 2358 additions and 1986 deletions
|
@ -5,6 +5,7 @@
|
|||
Если вы вдруг захотите копнуть поглубже -- аналог `bind` для IE8- и старых версий других браузеров будет выглядеть следующим образом:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
function bind(func, context /*, args*/) {
|
||||
var bindArgs = [].slice.call(arguments, 2); // (1)
|
||||
function wrapper() { // (2)
|
||||
|
|
|
@ -9,7 +9,7 @@ function f() {
|
|||
var user = {
|
||||
g: f.bind("Hello")
|
||||
}
|
||||
|
||||
|
||||
user.g();
|
||||
```
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ function f() {
|
|||
var user = {
|
||||
g: f.bind("Hello")
|
||||
}
|
||||
|
||||
|
||||
user.g();
|
||||
```
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Ответ: `"Вася"`.
|
||||
|
||||
```js
|
||||
//+ run
|
||||
//+ run no-beautify
|
||||
function f() {
|
||||
alert(this.name);
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ f(); // Вася
|
|||
|
||||
```js
|
||||
function bind(func, context) {
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
@ -28,6 +28,7 @@ function bind(func, context) {
|
|||
Код станет таким:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
function f() {
|
||||
alert(this.name);
|
||||
}
|
||||
|
@ -43,8 +44,8 @@ f(); // Вася
|
|||
```js
|
||||
function bind(func, context) {
|
||||
*!*
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
*/!*
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Что выведет этот код?
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
function f() {
|
||||
alert(this.name);
|
||||
}
|
||||
|
|
|
@ -5,16 +5,18 @@
|
|||
В свойство функции записано значение. Изменится ли оно после применения `bind`? Обоснуйте ответ.
|
||||
|
||||
```js
|
||||
function sayHi() {
|
||||
alert(this.name);
|
||||
function sayHi() {
|
||||
alert( this.name );
|
||||
}
|
||||
sayHi.test = 5;
|
||||
alert(sayHi.test); // 5
|
||||
alert( sayHi.test ); // 5
|
||||
|
||||
*!*
|
||||
var bound = sayHi.bind({ name: "Вася" });
|
||||
var bound = sayHi.bind({
|
||||
name: "Вася"
|
||||
});
|
||||
|
||||
alert(bound.test); // что выведет? почему?
|
||||
alert( bound.test ); // что выведет? почему?
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
|
|
@ -19,11 +19,11 @@ var user = {
|
|||
password: '12345',
|
||||
|
||||
loginOk: function() {
|
||||
alert(this.login + ' вошёл в сайт');
|
||||
alert( this.login + ' вошёл в сайт' );
|
||||
},
|
||||
|
||||
loginFail: function() {
|
||||
alert(this.login + ': ошибка входа');
|
||||
alert( this.login + ': ошибка входа' );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
|
@ -43,6 +43,7 @@ vasya.checkPassword();
|
|||
Альтернативное решение -- сделать функции-обёртки над `user.loginOk/loginFail`:
|
||||
|
||||
```js
|
||||
//+ no-beautify
|
||||
var user = {
|
||||
...
|
||||
checkPassword: function() {
|
||||
|
@ -79,19 +80,23 @@ var user = {
|
|||
password: '12345',
|
||||
|
||||
loginOk: function() {
|
||||
alert(this.login + ' вошёл в сайт');
|
||||
alert( this.login + ' вошёл в сайт' );
|
||||
},
|
||||
|
||||
loginFail: function() {
|
||||
alert(this.login + ': ошибка входа');
|
||||
alert( this.login + ': ошибка входа' );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
*!*
|
||||
var self = this;
|
||||
ask("Ваш пароль?", this.password,
|
||||
function() { self.loginOk(); },
|
||||
function() { self.loginFail(); }
|
||||
ask("Ваш пароль?", this.password,
|
||||
function() {
|
||||
self.loginOk();
|
||||
},
|
||||
function() {
|
||||
self.loginFail();
|
||||
}
|
||||
);
|
||||
*/!*
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ var user = {
|
|||
password: '12345',
|
||||
|
||||
loginOk: function() {
|
||||
alert(this.login + ' вошёл в сайт');
|
||||
alert( this.login + ' вошёл в сайт' );
|
||||
},
|
||||
|
||||
loginFail: function() {
|
||||
alert(this.login + ': ошибка входа');
|
||||
alert( this.login + ': ошибка входа' );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
|
|
|
@ -17,7 +17,7 @@ var user = {
|
|||
password: '12345',
|
||||
|
||||
loginDone: function(result) {
|
||||
alert(this.login + (result ? ' вошёл в сайт' : ' ошибка входа'));
|
||||
alert( this.login + (result ? ' вошёл в сайт' : ' ошибка входа') );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
|
@ -49,15 +49,19 @@ var user = {
|
|||
password: '12345',
|
||||
|
||||
loginDone: function(result) {
|
||||
alert(this.login + (result ? ' вошёл в сайт' : ' ошибка входа'));
|
||||
alert( this.login + (result ? ' вошёл в сайт' : ' ошибка входа') );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
var self = this;
|
||||
*!*
|
||||
ask("Ваш пароль?", this.password,
|
||||
function() { self.loginDone(true); },
|
||||
function() { self.loginDone(false); }
|
||||
function() {
|
||||
self.loginDone(true);
|
||||
},
|
||||
function() {
|
||||
self.loginDone(false);
|
||||
}
|
||||
);
|
||||
*/!*
|
||||
}
|
||||
|
|
|
@ -30,14 +30,18 @@ var user = {
|
|||
|
||||
// метод для вызова из ask
|
||||
loginDone: function(result) {
|
||||
alert(this.login + (result ? ' вошёл в сайт' : ' ошибка входа'));
|
||||
alert( this.login + (result ? ' вошёл в сайт' : ' ошибка входа') );
|
||||
},
|
||||
|
||||
checkPassword: function() {
|
||||
*!*
|
||||
ask("Ваш пароль?", this.password,
|
||||
function() { user.loginDone(true); },
|
||||
function() { user.loginDone(false); }
|
||||
ask("Ваш пароль?", this.password,
|
||||
function() {
|
||||
user.loginDone(true);
|
||||
},
|
||||
function() {
|
||||
user.loginDone(false);
|
||||
}
|
||||
);
|
||||
*/!*
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
```js
|
||||
//+ run
|
||||
setTimeout(function() {
|
||||
alert("Привет");
|
||||
alert( "Привет" );
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
@ -29,13 +29,13 @@ setTimeout(function() {
|
|||
//+ run
|
||||
var user = {
|
||||
firstName: "Вася",
|
||||
sayHi: function() {
|
||||
alert(this.firstName);
|
||||
sayHi: function() {
|
||||
alert( this.firstName );
|
||||
}
|
||||
};
|
||||
|
||||
*!*
|
||||
setTimeout( user.sayHi, 1000); // undefined (не Вася!)
|
||||
setTimeout(user.sayHi, 1000); // undefined (не Вася!)
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -61,15 +61,15 @@ setTimeout(f, 1000); // контекст user потеряли
|
|||
//+ run
|
||||
var user = {
|
||||
firstName: "Вася",
|
||||
sayHi: function() {
|
||||
alert(this.firstName);
|
||||
sayHi: function() {
|
||||
alert( this.firstName );
|
||||
}
|
||||
};
|
||||
|
||||
*!*
|
||||
setTimeout(function() {
|
||||
user.sayHi(); // Вася
|
||||
}, 1000);
|
||||
user.sayHi(); // Вася
|
||||
}, 1000);
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -82,15 +82,15 @@ setTimeout(function() {
|
|||
//+ run
|
||||
var user = {
|
||||
firstName: "Вася",
|
||||
sayHi: function(who) {
|
||||
alert(this.firstName + ": Привет, " + who);
|
||||
sayHi: function(who) {
|
||||
alert( this.firstName + ": Привет, " + who );
|
||||
}
|
||||
};
|
||||
|
||||
*!*
|
||||
setTimeout(function() {
|
||||
user.sayHi("Петя"); // Вася: Привет, Петя
|
||||
}, 1000);
|
||||
user.sayHi("Петя"); // Вася: Привет, Петя
|
||||
}, 1000);
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -108,7 +108,7 @@ setTimeout(function() {
|
|||
```js
|
||||
function bind(func, context) {
|
||||
return function() { // (*)
|
||||
return func.apply(context, arguments);
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
@ -117,10 +117,12 @@ function bind(func, context) {
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function f() { alert(this); }
|
||||
function f() {
|
||||
alert( this );
|
||||
}
|
||||
|
||||
var g = bind(f, "Context");
|
||||
g(); // Context
|
||||
g(); // Context
|
||||
```
|
||||
|
||||
То есть, `bind(f, "Context")` привязывает `"Context"` в качестве `this` для `f`.
|
||||
|
@ -132,16 +134,16 @@ g(); // Context
|
|||
Вот она отдельно:
|
||||
|
||||
```js
|
||||
function() { // (*)
|
||||
return func.apply(context, arguments);
|
||||
function() { // (*)
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
```
|
||||
|
||||
Если подставить наши конкретные аргументы, то есть `f` и `"Context"`, то получится так:
|
||||
|
||||
```js
|
||||
function() { // (*)
|
||||
return f.apply("Context", arguments);
|
||||
function() { // (*)
|
||||
return f.apply("Context", arguments);
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -153,13 +155,13 @@ function() { // (*)
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function f(a, b) {
|
||||
alert(this);
|
||||
alert(a + b);
|
||||
function f(a, b) {
|
||||
alert( this );
|
||||
alert( a + b );
|
||||
}
|
||||
|
||||
var g = bind(f, "Context");
|
||||
g(1, 2); // Context, затем 3
|
||||
g(1, 2); // Context, затем 3
|
||||
```
|
||||
|
||||
Аргументы, которые получила `g(...)`, передаются в `f` также благодаря методу `.apply`.
|
||||
|
@ -171,20 +173,20 @@ g(1, 2); // Context, затем 3
|
|||
```js
|
||||
//+ run
|
||||
function bind(func, context) {
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
var user = {
|
||||
firstName: "Вася",
|
||||
sayHi: function() {
|
||||
alert(this.firstName);
|
||||
alert( this.firstName );
|
||||
}
|
||||
};
|
||||
|
||||
*!*
|
||||
setTimeout( bind(user.sayHi, user), 1000 );
|
||||
setTimeout(bind(user.sayHi, user), 1000);
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -201,7 +203,7 @@ var user = {
|
|||
*!*
|
||||
sayHi: function(who) { // здесь у sayHi есть один аргумент
|
||||
*/!*
|
||||
alert(this.firstName + ": Привет, " + who);
|
||||
alert( this.firstName + ": Привет, " + who );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -228,9 +230,9 @@ sayHi("Маша"); // Вася: Привет, Маша
|
|||
|
||||
```js
|
||||
//+ run
|
||||
function f(a, b) {
|
||||
alert(this);
|
||||
alert(a + b);
|
||||
function f(a, b) {
|
||||
alert( this );
|
||||
alert( a + b );
|
||||
}
|
||||
|
||||
*!*
|
||||
|
@ -238,7 +240,7 @@ function f(a, b) {
|
|||
// var g = bind(f, "Context");
|
||||
var g = f.bind("Context");
|
||||
*/!*
|
||||
g(1, 2); // Context, затем 3
|
||||
g(1, 2); // Context, затем 3
|
||||
```
|
||||
|
||||
Синтаксис встроенного `bind`:
|
||||
|
@ -264,14 +266,14 @@ var wrapper = func.bind(context[, arg1, arg2...])
|
|||
//+ run
|
||||
var user = {
|
||||
firstName: "Вася",
|
||||
sayHi: function() {
|
||||
alert(this.firstName);
|
||||
sayHi: function() {
|
||||
alert( this.firstName );
|
||||
}
|
||||
};
|
||||
|
||||
*!*
|
||||
// setTimeout( bind(user.sayHi, user), 1000 );
|
||||
setTimeout( user.sayHi.bind(user), 1000 ); // аналог через встроенный метод
|
||||
setTimeout(user.sayHi.bind(user), 1000); // аналог через встроенный метод
|
||||
*/!*
|
||||
```
|
||||
|
||||
|
@ -291,7 +293,7 @@ setTimeout( user.sayHi.bind(user), 1000 ); // аналог через встро
|
|||
Если у объекта много методов и мы планируем их активно передавать, то можно привязать контекст для них всех в цикле:
|
||||
|
||||
```js
|
||||
for(var prop in user) {
|
||||
for (var prop in user) {
|
||||
if (typeof user[prop] == 'function') {
|
||||
user[prop] = user[prop].bind(user);
|
||||
}
|
||||
|
@ -327,9 +329,9 @@ function mul(a, b) {
|
|||
var double = mul.bind(null, 2); // контекст фиксируем null, он не используется
|
||||
*/!*
|
||||
|
||||
alert( double(3) ); // = mul(2, 3) = 6
|
||||
alert( double(4) ); // = mul(2, 4) = 8
|
||||
alert( double(5) ); // = mul(2, 5) = 10
|
||||
alert( double(3) ); // = mul(2, 3) = 6
|
||||
alert( double(4) ); // = mul(2, 4) = 8
|
||||
alert( double(5) ); // = mul(2, 5) = 10
|
||||
```
|
||||
|
||||
При вызове `double` будет передавать свои аргументы исходной функции `mul` после тех, которые указаны в `bind`, то есть в данном случае после зафиксированного первого аргумента `2`.
|
||||
|
@ -344,9 +346,9 @@ alert( double(5) ); // = mul(2, 5) = 10
|
|||
var triple = mul.bind(null, 3); // контекст фиксируем null, он не используется
|
||||
*/!*
|
||||
|
||||
alert( triple(3) ); // = mul(3, 3) = 9
|
||||
alert( triple(4) ); // = mul(3, 4) = 12
|
||||
alert( triple(5) ); // = mul(3, 5) = 15
|
||||
alert( triple(3) ); // = mul(3, 3) = 9
|
||||
alert( triple(4) ); // = mul(3, 4) = 12
|
||||
alert( triple(5) ); // = mul(3, 5) = 15
|
||||
```
|
||||
|
||||
При помощи `bind` мы можем получить из функции её "частный вариант" как самостоятельную функцию и дальше передать в `setTimeout` или сделать с ней что-то ещё.
|
||||
|
@ -377,12 +379,12 @@ function ask(question, answer, ok, fail) {
|
|||
ask("Выпустить птичку?", "да", fly, die);
|
||||
*/!*
|
||||
|
||||
function fly() {
|
||||
alert('улетела :)');
|
||||
function fly() {
|
||||
alert( 'улетела :)' );
|
||||
}
|
||||
|
||||
function die() {
|
||||
alert('птичку жалко :(');
|
||||
function die() {
|
||||
alert( 'птичку жалко :(' );
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -400,7 +402,7 @@ setTimeout(function() {
|
|||
<li>...Либо использовать `bind`:
|
||||
|
||||
```js
|
||||
setTimeout( obj.func.bind(obj) );
|
||||
setTimeout(obj.func.bind(obj));
|
||||
```
|
||||
</li>
|
||||
<li>Вызов `bind` часто используют для привязки функции к контексту, чтобы затем присвоить её в обычную переменную и вызывать уже без явного указания объекта.</li>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue