Skip to content

Commit dd99803

Browse files
committed
Accept Merge Request InterviewMap#33: (yyg-throttle -> master)
Merge Request: yyg-throttle Created By: @yygmind Reviewed By: @13221097537 Approved By: @13221097537 Accepted By: @13221097537 URL: https://coding.net/u/mart_13221097537/p/Front-End-Interview-Map/git/merge/33 Squash commits bb5745d ... ce36991
1 parent 646a43e commit dd99803

File tree

2 files changed

+86
-17
lines changed

2 files changed

+86
-17
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.idea
2-
test.js
2+
test.js
3+
.vscode/

JS/JS-en.md

+84-16
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ console.log(a) // EF
3636

3737
#### Typeof
3838

39-
`typeof` can always display the correct type of the primitive types, except `null`
39+
`typeof` can always display the correct type of the primitive types, except `null`
4040
```js
4141
typeof 1 // 'number'
4242
typeof '1' // 'string'
@@ -108,12 +108,12 @@ function Foo() {
108108
Foo.getName = function () {
109109
console.log('1');
110110
};
111-
Foo.prototype.getName = function () {
111+
Foo.prototype.getName = function () {
112112
console.log('2');
113113
};
114114

115115
new Foo.getName(); // -> 1
116-
new Foo().getName(); // -> 2
116+
new Foo().getName(); // -> 2
117117
```
118118

119119
![](https://user-gold-cdn.xitu.io/2018/4/9/162a9c56c838aa88?w=2100&h=540&f=png&s=127506)
@@ -122,7 +122,7 @@ As you can see from the above image, `new Foo()` has a higher priority than `new
122122

123123

124124
```js
125-
new (Foo.getName());
125+
new (Foo.getName());
126126
(new Foo()).getName();
127127
```
128128

@@ -146,7 +146,7 @@ var obj = {
146146
};
147147
obj.foo();
148148

149-
// In the above two situations, `this` only depends on the object before calling the function,
149+
// In the above two situations, `this` only depends on the object before calling the function,
150150
// and the second case has higher priority than the first case .
151151

152152
// the following situation has the highest priority,`this` will only be bound to c,
@@ -156,7 +156,7 @@ var c = new foo();
156156
c.a = 3;
157157
console.log(c.a);
158158

159-
// finally, using `call、apply、bind` to change what `this` is bound to ,
159+
// finally, using `call、apply、bind` to change what `this` is bound to ,
160160
// is another situation whom's priority is only second to `new`
161161
```
162162

@@ -177,7 +177,7 @@ Actually , the arrow function does not have `this` , `this` in the above functio
177177
#### instanceof
178178

179179
The `instanceof` operator can correctly judge the type of the object , bacause it’s internal mechanism is to find out if `prototype` of this type can be found in the prototype chain of the object
180-
let’s try to implement it
180+
let’s try to implement it
181181
```js
182182
function instanceof(left, right) {
183183
// get the `prototype` of the type
@@ -214,7 +214,7 @@ function b() {
214214
}
215215
```
216216

217-
It’s known that function and variable hoisting is the real reason for the above outputs . The usual explanation for hoisting says that the declarations are ‘moved’ to the top of the code , there is nothing wrong with that and it’s easy for everyone to understand . But a more accurate explanation should be like this :
217+
It’s known that function and variable hoisting is the real reason for the above outputs . The usual explanation for hoisting says that the declarations are ‘moved’ to the top of the code , there is nothing wrong with that and it’s easy for everyone to understand . But a more accurate explanation should be like this :
218218

219219
There would bo two stages when the execution environment is generated . The first stage is the stage of creation(to be specific , the step of generating variable objects ) , in which the JS interpreter would find out the variables and functions that need to be hoisted, and allocate memory for them in advance , then the functions would be deposited into memory entirely , but the variables would only be declared and assigned to `undefined`, therefore , we can use them in advance in the second stage (the code execution stage)
220220

@@ -337,7 +337,7 @@ function MyPromise(fn) {
337337
// execute asynchronously to guarantee the execution order
338338
setTimeout(() => {
339339
if (value instanceof MyPromise) {
340-
// if value is a Promise, execute recursively
340+
// if value is a Promise, execute recursively
341341
return value.then(_this.resolve, _this.reject)
342342
}
343343
if (_this.currentState === PENDING) {
@@ -381,8 +381,8 @@ MyPromise.prototype.then = function(onResolved, onRejected) {
381381

382382
if (self.currentState === RESOLVED) {
383383
return (promise2 = new MyPromise((resolve, reject) => {
384-
// specification 2.2.4, wrap them with `setTimeout`,
385-
// in order to insure that `onFulfilled` and `onRjected` execute asynchronously
384+
// specification 2.2.4, wrap them with `setTimeout`,
385+
// in order to insure that `onFulfilled` and `onRjected` execute asynchronously
386386
setTimeout(() => {
387387
try {
388388
let x = onResolved(self.value);
@@ -441,12 +441,12 @@ function resolutionProcedure(promise2, x, resolve, reject) {
441441
}
442442

443443
// specification 2.3.2, if `x` is a Promise and the state is `pending`,
444-
// the promise must remain, If not, it should execute.
444+
// the promise must remain, If not, it should execute.
445445
if (x instanceof MyPromise) {
446446
if (x.currentState === PENDING) {
447-
// call the function `resolutionProcedure` again to
447+
// call the function `resolutionProcedure` again to
448448
// confirm the type of the argument that x resolves
449-
// If it's a primitive type, it will be resolved again to
449+
// If it's a primitive type, it will be resolved again to
450450
// pass the value to next `then`.
451451
x.then((value) => {
452452
resolutionProcedure(promise2, value, resolve, reject);
@@ -457,7 +457,7 @@ function resolutionProcedure(promise2, x, resolve, reject) {
457457
return;
458458
}
459459

460-
// specification 2.3.3.3.3
460+
// specification 2.3.3.3.3
461461
// if both `reject` and `resolve` are executed, the first successful
462462
// execution takes precedence, and any further executions are ignored
463463
let called = false;
@@ -498,4 +498,72 @@ function resolutionProcedure(promise2, x, resolve, reject) {
498498
499499
The above codes, which is implemented based on the Promise / A+ specification, can pass the full test of `promises-aplus-tests`
500500
501-
![](https://user-gold-cdn.xitu.io/2018/3/29/162715e8e37e689d?w=1164&h=636&f=png&s=300285)
501+
![](https://user-gold-cdn.xitu.io/2018/3/29/162715e8e37e689d?w=1164&h=636&f=png&s=300285)
502+
503+
504+
#### Throttle
505+
506+
`Debounce` and `Throttle` are different in nature. `Debounce` is to turn multiple executions into the last execution, and `Throttle` is to turn multiple executions into execution at regular intervals.
507+
508+
```Js
509+
// The first two parameters with debounce are the same function
510+
// options: You can pass two properties
511+
// trailing: Last time does not execute
512+
// leading: First time does not execute
513+
// The two properties cannot coexist, otherwise the function cannot be executed
514+
_.throttle = function(func, wait, options) {
515+
var context, args, result;
516+
var timeout = null;
517+
// Previous timestamp
518+
var previous = 0;
519+
// Empty if options is not passed
520+
if (!options) options = {};
521+
// Timer callback function
522+
var later = function() {
523+
// If you set leading, then set previous to zero
524+
// The first if statement of the following function is used
525+
previous = options.leading === false ? 0 : _.now();
526+
// The first is prevented memory leaks and the second is judged the following timers when setting timeout to null
527+
timeout = null;
528+
result = func.apply(context, args);
529+
if (!timeout) context = args = null;
530+
};
531+
return function() {
532+
// Get current timestamp
533+
var now = _.now();
534+
// It must be true when it entering firstly
535+
// If you do not need to execute the function firstly
536+
// Set the last timestamp to current
537+
// Then it will be greater than 0 when the remaining time is calculated next
538+
if (!previous && options.leading === false)
539+
previous = now;
540+
// Calculated remaining time
541+
var remaining = wait - (now - previous);
542+
context = this;
543+
args = arguments;
544+
// It will add wait time if the current call time greater than the last call time
545+
// Or the user manually adjusted the time
546+
// This condition will only be entered if it set trailing
547+
// This condition will be entered firstly if it not set leading
548+
// Another point, you may think that this condition will not be entered if you turn on the timer
549+
// In fact, it will still enter because the timer delay is not accurate
550+
// It is very likely that you set 2 seconds, but it needs 2.2 seconds to trigger, then this time will enter this condition
551+
if (remaining <= 0 || remaining > wait) {
552+
// Clean up if there exist a timer otherwise it call twice callback
553+
if (timeout) {
554+
clearTimeout(timeout);
555+
timeout = null;
556+
}
557+
previous = now;
558+
result = func.apply(context, args);
559+
if (!timeout) context = args = null;
560+
} else if (!timeout && options.trailing !== false) {
561+
// Judgment if timer and trailing are set
562+
// Turn on a timer if not set
563+
// And you can't set leading and trailing at the same time
564+
timeout = setTimeout(later, remaining);
565+
}
566+
return result;
567+
};
568+
};
569+
```

0 commit comments

Comments
 (0)