Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Decorators and forwarding, call/apply#171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
otmon76 merged 2 commits intojavascript-tutorial:masterfromotmon76:1.6.9
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
functionspy(func) {
functionšpión(funkce) {

functionwrapper(...args) {
//using ...args instead ofarguments to store "real" array in wrapper.calls
wrapper.calls.push(args);
returnfunc.apply(this,args);
functionobal(...argumenty) {
//použijeme ...argumenty místoarguments, abychom do obal.volání uložili „skutečné“ pole
obal.volání.push(argumenty);
returnfunkce.apply(this,argumenty);
}

wrapper.calls = [];
obal.volání = [];

returnwrapper;
returnobal;
}

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
functionspy(func) {
//your code
functionšpión(funkce) {
//váš kód
}


View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
describe("spy", function() {
it("records calls into its property", function() {
functionwork() {}
describe("špión", function() {
it("zapisuje volání do své vlastnosti", function() {
functionpráce() {}

work =spy(work);
assert.deepEqual(work.calls, []);
práce =špión(práce);
assert.deepEqual(práce.volání, []);

work(1, 2);
assert.deepEqual(work.calls, [
práce(1, 2);
assert.deepEqual(práce.volání, [
[1, 2]
]);

work(3, 4);
assert.deepEqual(work.calls, [
práce(3, 4);
assert.deepEqual(práce.volání, [
[1, 2],
[3, 4]
]);
});

it("transparently wraps functions", function() {
it("transparentně obaluje funkce", function() {

letsum = sinon.spy((a, b) => a + b);
letsečti = sinon.spy((a, b) => a + b);

letwrappedSum =spy(sum);
letobalenéSečti =špión(sečti);

assert.equal(wrappedSum(1, 2), 3);
assert(sum.calledWith(1, 2));
assert.equal(obalenéSečti(1, 2), 3);
assert(sečti.calledWith(1, 2));
});


it("transparently wraps methods", function() {
it("transparentně obaluje metody", function() {

letcalc = {
sum: sinon.spy((a, b) => a + b)
letvypočítej = {
sečti: sinon.spy((a, b) => a + b)
};

calc.wrappedSum =spy(calc.sum);
vypočítej.obalenéSečti =špión(vypočítej.sečti);

assert.equal(calc.wrappedSum(1, 2), 3);
assert(calc.sum.calledWith(1, 2));
assert(calc.sum.calledOn(calc));
assert.equal(vypočítej.obalenéSečti(1, 2), 3);
assert(vypočítej.sečti.calledWith(1, 2));
assert(vypočítej.sečti.calledOn(vypočítej));
});

});
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
The wrapper returned by `spy(f)` should store all arguments and then use`f.apply`to forward the call.
Obal, který vrátí `špión(f)`, by si měl uložit všechny argumenty a pak pomocí`f.apply`přesměrovat volání.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,29 +2,29 @@ importance: 5

---

#Spy decorator
#Špiónský dekorátor

Create a decorator `spy(func)` that should return a wrapper that saves all calls to function in its `calls` property.
Vytvořte dekorátor `špión(funkce)`, který by měl vrátit obal, který si bude ukládat všechna volání funkce do své vlastnosti `volání`.

Every call is saved as an array of arguments.
Každé volání bude uloženo jako pole argumentů.

For instance:
Například:

```js
functionwork(a, b) {
alert( a + b ); //work is an arbitrary function or method
functionpráce(a, b) {
alert( a + b ); //práce je jakákoli funkce nebo metoda
}

*!*
work =spy(work);
práce =špión(práce);
*/!*

work(1, 2); // 3
work(4, 5); // 9
práce(1, 2); // 3
práce(4, 5); // 9

for (letargs ofwork.calls) {
alert( 'call:' +args.join() ); // "call:1,2", "call:4,5"
for (letargumenty ofpráce.volání) {
alert( 'volání:' +argumenty.join() ); // "volání:1,2", "volání:4,5"
}
```

P.S.That decorator is sometimes useful for unit-testing. Its advanced form is `sinon.spy`in[Sinon.JS](http://sinonjs.org/) library.
P.S.Takový dekorátor je někdy užitečný pro jednotkové testování. Jeho pokročilá forma je `sinon.spy`v knihovně[Sinon.JS](http://sinonjs.org/).
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
functiondelay(f, ms) {
functionzpozdi(f, ms) {

return function() {
setTimeout(() => f.apply(this, arguments), ms);
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
describe("delay", function() {
describe("zpozdi", function() {
before(function() {
this.clock = sinon.useFakeTimers();
this.hodiny = sinon.useFakeTimers();
});

after(function() {
this.clock.restore();
this.hodiny.restore();
});

it("calls the function after the specified timeout", function() {
letstart = Date.now();
it("volá funkci až po specifikované době", function() {
letzačátek = Date.now();

function f(x) {
assert.equal(Date.now() -start, 1000);
assert.equal(Date.now() -začátek, 1000);
}
f = sinon.spy(f);

let f1000 =delay(f, 1000);
let f1000 =zpozdi(f, 1000);
f1000("test");
this.clock.tick(2000);
assert(f.calledOnce, 'calledOncecheck fails');
this.hodiny.tick(2000);
assert(f.calledOnce, 'ověřenícalledOnceselhalo');
});

it("passes arguments and this", function() {
letstart = Date.now();
letuser = {
sayHi: function(phrase, who) {
assert.equal(this,user);
assert.equal(phrase, "Hello");
assert.equal(who, "John");
assert.equal(Date.now() -start, 1500);
it("předává argumenty a this", function() {
letzačátek = Date.now();
letuživatel = {
řekniAhoj: function(věta, kdo) {
assert.equal(this,uživatel);
assert.equal(věta, "Ahoj");
assert.equal(kdo, "Jan");
assert.equal(Date.now() -začátek, 1500);
}
};

user.sayHi = sinon.spy(user.sayHi);
uživatel.řekniAhoj = sinon.spy(uživatel.řekniAhoj);

letspy =user.sayHi;
user.sayHi =delay(user.sayHi, 1500);
letšpión =uživatel.řekniAhoj;
uživatel.řekniAhoj =zpozdi(uživatel.řekniAhoj, 1500);

user.sayHi("Hello", "John");
uživatel.řekniAhoj("Ahoj", "Jan");

this.clock.tick(2000);
this.hodiny.tick(2000);

assert(spy.calledOnce, 'calledOncecheck failed');
assert(špión.calledOnce, 'ověřenícalledOnceselhalo');
});
});
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
The solution:
Řešení:

```js run demo
functiondelay(f, ms) {
functionzpozdi(f, ms) {

return function() {
setTimeout(() => f.apply(this, arguments), ms);
};

}

let f1000 =delay(alert, 1000);
let f1000 =zpozdi(alert, 1000);

f1000("test"); //shows "test"after 1000ms
f1000("test"); //zobrazí "test"za 1000 ms
```

Please note how an arrow function is used here. As we know, arrow functions do not have own`this`and `arguments`,so `f.apply(this, arguments)`takes `this`and `arguments`from the wrapper.
Prosíme všimněte si, jak je zde použita šipková funkce. Jak víme, šipkové funkce nemají vlastní`this`ani `arguments`,takže `f.apply(this, arguments)`převezme `this`a `arguments`z obalu.

If we pass a regular function, `setTimeout`would call it without arguments and `this=window` (assuming we're in the browser).
Předáme-li běžnou funkci, `setTimeout`ji bude volat bez argumentů a `this=window` (za předpokladu, že jsme v prohlížeči).

We still can pass the right`this`by using an intermediate variable, but that's a little bit more cumbersome:
Můžeme také předávat skutečné`this`pomocí mezilehlé proměnné, ale to je trochu pracnější:

```js
functiondelay(f, ms) {
functionzpozdi(f, ms) {

return function(...args) {
letsavedThis = this; //store thisinto an intermediate variable
return function(...argumenty) {
letuloženéThis = this; //uloží thisdo mezilehlé proměnné
setTimeout(function() {
f.apply(savedThis, args); //use it here
f.apply(uloženéThis, argumenty); //zde ji použijeme
}, ms);
};

Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,25 +2,25 @@ importance: 5

---

#Delaying decorator
#Zpožďovací dekorátor

Create a decorator `delay(f, ms)` that delays each call of `f`by `ms`milliseconds.
Vytvořte dekorátor `zpozdi(f, ms)`, který zpozdí každé volání funkce `f`o `ms`milisekund.

For instance:
Například:

```js
function f(x) {
alert(x);
}

//create wrappers
let f1000 =delay(f, 1000);
let f1500 =delay(f, 1500);
//vytvoření obalů
let f1000 =zpozdi(f, 1000);
let f1500 =zpozdi(f, 1500);

f1000("test"); //shows "test"after 1000ms
f1500("test"); //shows "test"after 1500ms
f1000("test"); //zobrazí "test"za 1000 ms
f1500("test"); //zobrazí "test"za 1500 ms
```

In other words, `delay(f, ms)`returns a "delayed by `ms`" variant of `f`.
Jinými slovy, `zpozdi(f, ms)`vrátí variantu `f` „zpožděnou o `ms`“.

In the code above, `f`is a function of a single argument, but your solution should pass all arguments and the context `this`.
V uvedeném kódu je `f`funkce s jediným argumentem, ale vaše řešení by mělo předávat všechny argumenty a kontextové `this`.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
functiondebounce(func, ms) {
lettimeout;
functionvyčkej(funkce, ms) {
letčasovač;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() =>func.apply(this, arguments), ms);
clearTimeout(časovač);
časovač = setTimeout(() =>funkce.apply(this, arguments), ms);
};
}
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
describe('debounce', function () {
describe('vyčkej', function () {
before(function () {
this.clock = sinon.useFakeTimers();
this.hodiny = sinon.useFakeTimers();
});

after(function () {
this.clock.restore();
this.hodiny.restore();
});

it('for one call -runs it after given ms', function () {
it('pro jedno volání -spustí je po zadané době v ms', function () {
const f = sinon.spy();
constdebounced =debounce(f, 1000);
constvyčkáváno =vyčkej(f, 1000);

debounced('test');
assert(f.notCalled, 'not called immediately');
this.clock.tick(1000);
assert(f.calledOnceWith('test'), 'called after 1000ms');
vyčkáváno('test');
assert(f.notCalled, 'nevolá se okamžitě');
this.hodiny.tick(1000);
assert(f.calledOnceWith('test'), 'voláno po 1000 ms');
});

it('for 3calls -runs the last one after given ms', function () {
it('pro 3volání -spustí poslední po zadané době v ms', function () {
const f = sinon.spy();
constdebounced =debounce(f, 1000);
constvyčkáváno =vyčkej(f, 1000);

debounced('a');
setTimeout(() =>debounced('b'), 200); //ignored (too early)
setTimeout(() =>debounced('c'), 500); //runs(1000 mspassed)
this.clock.tick(1000);
vyčkáváno('a');
setTimeout(() =>vyčkáváno('b'), 200); //ignorováno (příliš brzy)
setTimeout(() =>vyčkáváno('c'), 500); //spustí se(1000 msuplynulo)
this.hodiny.tick(1000);

assert(f.notCalled, 'not called after 1000ms');
assert(f.notCalled, 'nevoláno po 1000 ms');

this.clock.tick(500);
this.hodiny.tick(500);

assert(f.calledOnceWith('c'), 'called after 1500ms');
assert(f.calledOnceWith('c'), 'voláno po 1500 ms');
});

it('keeps the context of the call', function () {
it('udržuje si kontext volání', function () {
let obj = {
f() {
assert.equal(this, obj);
},
};

obj.f =debounce(obj.f, 1000);
obj.f =vyčkej(obj.f, 1000);
obj.f('test');
this.clock.tick(5000);
this.hodiny.tick(5000);
});

});
Loading

[8]ページ先頭

©2009-2025 Movatter.jp