chore: prettify contents
This commit is contained in:
parent
1ca0fc7f50
commit
8dafe097dd
|
|
@ -8,4 +8,4 @@ trim_trailing_whitespace = true
|
|||
[*.{js,py}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"bracketSpacing": false,
|
||||
"jsxBracketSameLine": true,
|
||||
"printWidth": 80,
|
||||
"proseWrap": "never",
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<br/>
|
||||
<p>
|
||||
<em>Credits: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Illustration</a> by <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
|
|
@ -31,7 +31,7 @@ You might be interested in the [Tech Interview Handbook](https://github.com/yang
|
|||
|
||||
<div align="center">
|
||||
<img src="assets/web-tech.svg" alt="Web Technologies illustration" width="400"/>
|
||||
<br>
|
||||
<br/>
|
||||
<p>
|
||||
<em>Credits: Illustration by <a href="https://undraw.co/">unDraw</a></em>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Credits: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Illustration</a> by <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## What is this?
|
||||
|
|
@ -31,7 +26,7 @@ You might be interested in the [Tech Interview Handbook](https://github.com/yang
|
|||
|
||||
<div align="center">
|
||||
<img src="assets/web-tech.svg" alt="Web Technologies illustration" width="400"/>
|
||||
<br>
|
||||
<br/>
|
||||
<p>
|
||||
<em>Credits: Illustration by <a href="https://undraw.co/">unDraw</a></em>
|
||||
</p>
|
||||
|
|
@ -72,7 +67,7 @@ Read our [contributing guide](/CONTRIBUTING.md) to learn about how you can contr
|
|||
|
||||
Many hours of hard work have gone into this project. Your support will be very appreciated!
|
||||
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;"/></a>
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ The `.clearfix` hack uses a clever CSS [pseudo selector](#describe-pseudo-elemen
|
|||
|
||||
```css
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
content: ' ';
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
|
@ -399,16 +399,16 @@ The box model has the following rules:
|
|||
|
||||
- `none`, `block`, `inline`, `inline-block`, `flex`, `grid`, `table`, `table-row`, `table-cell`, `list-item`.
|
||||
|
||||
| `display` | Description |
|
||||
| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `none` | Does not display an element (the elementv no longer affects the layout of the document). All child element are also no longer displayed. The document is rendered as if the element did not exist in the document tree |
|
||||
| `block` | The element consumes the whole line in the block direction (which is usually horizontal) |
|
||||
| `inline` | Elements can be laid out beside each other |
|
||||
| `inline-block` | Similar to `inline`, but allows some `block` properties like setting `width` and `height` |
|
||||
| `table` | Behaves like the `<table>` element |
|
||||
| `table-row` | Behaves like the `<tr>` element |
|
||||
| `table-cell` | Behaves like the `<td>` element |
|
||||
| `list-item` | Behaves like a `<li>` element which allows it to define `list-style-type` and `list-style-position` |
|
||||
| `display` | Description |
|
||||
| :-- | :-- |
|
||||
| `none` | Does not display an element (the elementv no longer affects the layout of the document). All child element are also no longer displayed. The document is rendered as if the element did not exist in the document tree |
|
||||
| `block` | The element consumes the whole line in the block direction (which is usually horizontal) |
|
||||
| `inline` | Elements can be laid out beside each other |
|
||||
| `inline-block` | Similar to `inline`, but allows some `block` properties like setting `width` and `height` |
|
||||
| `table` | Behaves like the `<table>` element |
|
||||
| `table-row` | Behaves like the `<tr>` element |
|
||||
| `table-cell` | Behaves like the `<td>` element |
|
||||
| `list-item` | Behaves like a `<li>` element which allows it to define `list-style-type` and `list-style-position` |
|
||||
|
||||
[[↑] Back to top](#css-questions)
|
||||
|
||||
|
|
@ -416,14 +416,14 @@ The box model has the following rules:
|
|||
|
||||
I shall throw in a comparison with `block` for good measure.
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Size | Fills up the width of its parent container. | Depends on content. | Depends on content. |
|
||||
| Positioning | Start on a new line and tolerates no HTML elements next to it (except when you add `float`) | Flows along with other content and allows other elements beside it. | Flows along with other content and allows other elements beside it. |
|
||||
| Can specify `width` and `height` | Yes | Yes | No. Will ignore if being set. |
|
||||
| Can be aligned with `vertical-align` | No | Yes | Yes |
|
||||
| Margins and paddings | All sides respected. | All sides respected. | Only horizontal sides respected. Vertical sides, if specified, do not affect layout. Vertical space it takes up depends on `line-height`, even though the `border` and `padding` appear visually around the content. |
|
||||
| Float | - | - | Becomes like a `block` element where you can set vertical margins and paddings. |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| Size | Fills up the width of its parent container. | Depends on content. | Depends on content. |
|
||||
| Positioning | Start on a new line and tolerates no HTML elements next to it (except when you add `float`) | Flows along with other content and allows other elements beside it. | Flows along with other content and allows other elements beside it. |
|
||||
| Can specify `width` and `height` | Yes | Yes | No. Will ignore if being set. |
|
||||
| Can be aligned with `vertical-align` | No | Yes | Yes |
|
||||
| Margins and paddings | All sides respected. | All sides respected. | Only horizontal sides respected. Vertical sides, if specified, do not affect layout. Vertical space it takes up depends on `line-height`, even though the `border` and `padding` appear visually around the content. |
|
||||
| Float | - | - | Becomes like a `block` element where you can set vertical margins and paddings. |
|
||||
|
||||
[[↑] Back to top](#css-questions)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,11 @@ Answers to [Front-end Job Interview Questions - HTML Questions](https://github.c
|
|||
|
||||
### What does a DOCTYPE do?
|
||||
|
||||
**DOCTYPE** is an abbreviation for **DOCument TYPE**.
|
||||
A DOCTYPE is always associated to a **DTD** - for **Document Type Definition**.
|
||||
**DOCTYPE** is an abbreviation for **DOCument TYPE**. A DOCTYPE is always associated to a **DTD** - for **Document Type Definition**.
|
||||
|
||||
A DTD defines how documents of a certain type should be structured (i.e. a `button` can contain a `span` but not a `div`), whereas a DOCTYPE declares what DTD a document _supposedly_ respects (i.e. this document respects the HTML DTD).
|
||||
|
||||
For webpages, the DOCTYPE declaration is required. It is used to tell user agents what version of the HTML specifications your document respects.
|
||||
Once a user agent has recognized a correct DOCTYPE, it will trigger the **no-quirks mode** matching this DOCTYPE for reading the document.
|
||||
If a user agent doesn't recognize a correct DOCTYPE, it will trigger the **quirks mode**.
|
||||
For webpages, the DOCTYPE declaration is required. It is used to tell user agents what version of the HTML specifications your document respects. Once a user agent has recognized a correct DOCTYPE, it will trigger the **no-quirks mode** matching this DOCTYPE for reading the document. If a user agent doesn't recognize a correct DOCTYPE, it will trigger the **quirks mode**.
|
||||
|
||||
The DOCTYPE declaration for the HTML5 standards is `<!DOCTYPE html>`.
|
||||
|
||||
|
|
@ -102,14 +99,14 @@ However, one perfectly valid use of data attributes, is to add a hook for _end t
|
|||
|
||||
All the above-mentioned technologies are key-value storage mechanisms on the client side. They are only able to store values as strings.
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| -------------------------------------- | -------------------------------------------------------- | -------------- | ---------------- |
|
||||
| Initiator | Client or server. Server can use `Set-Cookie` header | Client | Client |
|
||||
| Expiry | Manually set | Forever | On tab close |
|
||||
| Persistent across browser sessions | Depends on whether expiration is set | Yes | No |
|
||||
| Sent to server with every HTTP request | Cookies are automatically being sent via `Cookie` header | No | No |
|
||||
| Capacity (per domain) | 4kb | 5MB | 5MB |
|
||||
| Accessibility | Any window | Any window | Same tab |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| Initiator | Client or server. Server can use `Set-Cookie` header | Client | Client |
|
||||
| Expiry | Manually set | Forever | On tab close |
|
||||
| Persistent across browser sessions | Depends on whether expiration is set | Yes | No |
|
||||
| Sent to server with every HTTP request | Cookies are automatically being sent via `Cookie` header | No | No |
|
||||
| Capacity (per domain) | 4kb | 5MB | 5MB |
|
||||
| Accessibility | Any window | Any window | Same tab |
|
||||
|
||||
_Note: If the user decides to clear browsing data via whatever mechanism provided by the browser, this will clear out any `cookie`, `localStorage`, or `sessionStorage` stored. It's important to keep this in mind when designing for local persistance, especially when comparing to alternatives such as server side storing in a database or similar (which of course will persist despite user actions)._
|
||||
|
||||
|
|
|
|||
|
|
@ -104,26 +104,26 @@ This is an extremely common JavaScript interview question. All JavaScript object
|
|||
We already have a build-in `Object.create`, but if you were to provide a polyfill for it, that might look like:
|
||||
|
||||
```javascript
|
||||
if (typeof Object.create !== "function") {
|
||||
Object.create = function(parent) {
|
||||
if (typeof Object.create !== 'function') {
|
||||
Object.create = function (parent) {
|
||||
function Tmp() {}
|
||||
Tmp.prototype = parent;
|
||||
return new Tmp();
|
||||
};
|
||||
}
|
||||
|
||||
const Parent = function() {
|
||||
this.name = "Parent";
|
||||
const Parent = function () {
|
||||
this.name = 'Parent';
|
||||
};
|
||||
|
||||
Parent.prototype.greet = function() {
|
||||
console.log("hello from Parent");
|
||||
Parent.prototype.greet = function () {
|
||||
console.log('hello from Parent');
|
||||
};
|
||||
|
||||
const child = Object.create(Parent.prototype);
|
||||
|
||||
child.cry = function() {
|
||||
console.log("waaaaaahhhh!");
|
||||
child.cry = function () {
|
||||
console.log('waaaaaahhhh!');
|
||||
};
|
||||
|
||||
child.cry();
|
||||
|
|
@ -156,7 +156,7 @@ child.constructor.name
|
|||
```javascript
|
||||
function Child() {
|
||||
Parent.call(this);
|
||||
this.name = "child";
|
||||
this.name = 'child';
|
||||
}
|
||||
|
||||
Child.prototype = Parent.prototype;
|
||||
|
|
@ -240,7 +240,7 @@ A variable that is `undefined` is a variable that has been declared, but not ass
|
|||
var foo;
|
||||
console.log(foo); // undefined
|
||||
console.log(foo === undefined); // true
|
||||
console.log(typeof foo === "undefined"); // true
|
||||
console.log(typeof foo === 'undefined'); // true
|
||||
|
||||
console.log(foo == null); // true. Wrong, don't use this to check!
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ A variable that is `null` will have been explicitly assigned to the `null` value
|
|||
```js
|
||||
var foo = null;
|
||||
console.log(foo === null); // true
|
||||
console.log(typeof foo === "object"); // true
|
||||
console.log(typeof foo === 'object'); // true
|
||||
|
||||
console.log(foo == undefined); // true. Wrong, don't use this to check!
|
||||
```
|
||||
|
|
@ -310,7 +310,7 @@ const doubled = a.forEach((num, index) => {
|
|||
|
||||
```js
|
||||
const a = [1, 2, 3];
|
||||
const doubled = a.map(num => {
|
||||
const doubled = a.map((num) => {
|
||||
return num * 2;
|
||||
});
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ The main difference between `.forEach` and `.map()` is that `.map()` returns a n
|
|||
They can be used in IIFEs to encapsulate some code within a local scope so that variables declared in it do not leak to the global scope.
|
||||
|
||||
```js
|
||||
(function() {
|
||||
(function () {
|
||||
// Some code here.
|
||||
})();
|
||||
```
|
||||
|
|
@ -338,8 +338,8 @@ They can be used in IIFEs to encapsulate some code within a local scope so that
|
|||
As a callback that is used once and does not need to be used anywhere else. The code will seem more self-contained and readable when handlers are defined right inside the code calling them, rather than having to search elsewhere to find the function body.
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
console.log("Hello world!");
|
||||
setTimeout(function () {
|
||||
console.log('Hello world!');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ Arguments to functional programming constructs or Lodash (similar to callbacks).
|
|||
|
||||
```js
|
||||
const arr = [1, 2, 3];
|
||||
const double = arr.map(function(el) {
|
||||
const double = arr.map(function (el) {
|
||||
return el * 2;
|
||||
});
|
||||
console.log(double); // [2, 4, 6]
|
||||
|
|
@ -395,11 +395,11 @@ function Person(name) {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
var person = Person("John");
|
||||
var person = Person('John');
|
||||
console.log(person); // undefined
|
||||
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
||||
|
||||
var person = new Person("John");
|
||||
var person = new Person('John');
|
||||
console.log(person); // Person { name: "John" }
|
||||
console.log(person.name); // "john"
|
||||
```
|
||||
|
|
@ -459,7 +459,7 @@ There are some answers online that explain `document.write()` is being used in a
|
|||
Feature detection involves working out whether a browser supports a certain block of code, and running different code depending on whether it does (or doesn't), so that the browser can always provide a working experience rather crashing/erroring in some browsers. For example:
|
||||
|
||||
```js
|
||||
if ("geolocation" in navigator) {
|
||||
if ('geolocation' in navigator) {
|
||||
// Can use navigator.geolocation
|
||||
} else {
|
||||
// Handle lack of feature
|
||||
|
|
@ -543,7 +543,7 @@ JSONP works by making a request to a cross-origin domain via a `<script>` tag an
|
|||
|
||||
```js
|
||||
// File loaded from https://example.com?callback=printData
|
||||
printData({ name: "Yang Shun" });
|
||||
printData({name: 'Yang Shun'});
|
||||
```
|
||||
|
||||
The client has to have the `printData` function in its global scope and the function will be executed by the client when the response from the cross-origin domain is received.
|
||||
|
|
@ -589,15 +589,15 @@ Function declarations have the body hoisted while the function expressions (writ
|
|||
console.log(foo); // [Function: foo]
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
console.log(foo); // [Function: foo]
|
||||
|
||||
// Function Expression
|
||||
console.log(bar); // undefined
|
||||
bar(); // Uncaught TypeError: bar is not a function
|
||||
var bar = function() {
|
||||
console.log("BARRRR");
|
||||
var bar = function () {
|
||||
console.log('BARRRR');
|
||||
};
|
||||
console.log(bar); // [Function: bar]
|
||||
```
|
||||
|
|
@ -608,8 +608,8 @@ Variables declared via `let` and `const` are hoisted as well. However, unlike `v
|
|||
x; // undefined
|
||||
y; // Reference error: y is not defined
|
||||
|
||||
var x = "local";
|
||||
let y = "local";
|
||||
var x = 'local';
|
||||
let y = 'local';
|
||||
```
|
||||
|
||||
###### References
|
||||
|
|
@ -630,15 +630,15 @@ When an event triggers on a DOM element, it will attempt to handle the event if
|
|||
Attributes are defined on the HTML markup but properties are defined on the DOM. To illustrate the difference, imagine we have this text field in our HTML: `<input type="text" value="Hello">`.
|
||||
|
||||
```js
|
||||
const input = document.querySelector("input");
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
const input = document.querySelector('input');
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello
|
||||
```
|
||||
|
||||
But after you change the value of the text field by adding "World!" to it, this becomes:
|
||||
|
||||
```js
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -678,11 +678,11 @@ The `DOMContentLoaded` event is fired when the initial HTML document has been co
|
|||
`==` is the abstract equality operator while `===` is the strict equality operator. The `==` operator will compare for equality after doing any necessary type conversions. The `===` operator will not do type conversion, so if two values are not the same type `===` will simply return `false`. When using `==`, funky things can happen, such as:
|
||||
|
||||
```js
|
||||
1 == "1"; // true
|
||||
1 == '1'; // true
|
||||
1 == [1]; // true
|
||||
1 == true; // true
|
||||
0 == ""; // true
|
||||
0 == "0"; // true
|
||||
0 == ''; // true
|
||||
0 == '0'; // true
|
||||
0 == false; // true
|
||||
```
|
||||
|
||||
|
|
@ -727,7 +727,7 @@ duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
|||
Or with ES6:
|
||||
|
||||
```js
|
||||
const duplicate = arr => [...arr, ...arr];
|
||||
const duplicate = (arr) => [...arr, ...arr];
|
||||
|
||||
duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
||||
```
|
||||
|
|
@ -781,7 +781,7 @@ Check out this version of FizzBuzz by [Paul Irish](https://gist.github.com/jayso
|
|||
for (let i = 1; i <= 100; i++) {
|
||||
let f = i % 3 == 0,
|
||||
b = i % 5 == 0;
|
||||
console.log(f ? (b ? "FizzBuzz" : "Fizz") : b ? "Buzz" : i);
|
||||
console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -977,10 +977,10 @@ By combining `writable: false` and `configurable: false`, you can essentially cr
|
|||
|
||||
```js
|
||||
let myObject = {};
|
||||
Object.defineProperty(myObject, "number", {
|
||||
Object.defineProperty(myObject, 'number', {
|
||||
value: 42,
|
||||
writable: false,
|
||||
configurable: false
|
||||
configurable: false,
|
||||
});
|
||||
console.log(myObject.number); // 42
|
||||
myObject.number = 43;
|
||||
|
|
@ -1059,9 +1059,9 @@ const arr = [1, 2, 3];
|
|||
const newArr = [...arr, 4]; // [1, 2, 3, 4]
|
||||
|
||||
// Object Example
|
||||
const human = Object.freeze({ race: "human" });
|
||||
const john = { ...human, name: "John" }; // {race: "human", name: "John"}
|
||||
const alienJohn = { ...john, race: "alien" }; // {race: "alien", name: "John"}
|
||||
const human = Object.freeze({race: 'human'});
|
||||
const john = {...human, name: 'John'}; // {race: "human", name: "John"}
|
||||
const alienJohn = {...john, race: 'alien'}; // {race: "alien", name: "John"}
|
||||
```
|
||||
|
||||
###### References
|
||||
|
|
@ -1102,7 +1102,7 @@ The former is a function declaration while the latter is a function expression.
|
|||
```js
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -1110,8 +1110,8 @@ function foo() {
|
|||
|
||||
```js
|
||||
foo(); // Uncaught TypeError: foo is not a function
|
||||
var foo = function() {
|
||||
console.log("FOOOOO");
|
||||
var foo = function () {
|
||||
console.log('FOOOOO');
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -1128,9 +1128,9 @@ Variables declared using the `var` keyword are scoped to the function in which t
|
|||
```js
|
||||
function foo() {
|
||||
// All variables are accessible within functions.
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
|
||||
console.log(bar); // bar
|
||||
console.log(baz); // baz
|
||||
|
|
@ -1144,9 +1144,9 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
|
||||
```js
|
||||
if (true) {
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
}
|
||||
|
||||
// var declared variables are accessible anywhere in the function scope.
|
||||
|
|
@ -1161,38 +1161,38 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
```js
|
||||
console.log(foo); // undefined
|
||||
|
||||
var foo = "foo";
|
||||
var foo = 'foo';
|
||||
|
||||
console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization
|
||||
|
||||
let baz = "baz";
|
||||
let baz = 'baz';
|
||||
|
||||
console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization
|
||||
|
||||
const bar = "bar";
|
||||
const bar = 'bar';
|
||||
```
|
||||
|
||||
Redeclaring a variable with `var` will not throw an error, but 'let' and 'const' will.
|
||||
|
||||
```js
|
||||
var foo = "foo";
|
||||
var foo = "bar";
|
||||
var foo = 'foo';
|
||||
var foo = 'bar';
|
||||
console.log(foo); // "bar"
|
||||
|
||||
let baz = "baz";
|
||||
let baz = "qux"; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
let baz = 'baz';
|
||||
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
```
|
||||
|
||||
`let` and `const` differ in that `let` allows reassigning the variable's value while `const` does not.
|
||||
|
||||
```js
|
||||
// This is fine.
|
||||
let foo = "foo";
|
||||
foo = "bar";
|
||||
let foo = 'foo';
|
||||
foo = 'bar';
|
||||
|
||||
// This causes an exception.
|
||||
const baz = "baz";
|
||||
baz = "qux";
|
||||
const baz = 'baz';
|
||||
baz = 'qux';
|
||||
```
|
||||
|
||||
###### References
|
||||
|
|
@ -1267,9 +1267,9 @@ One obvious benefit of arrow functions is to simplify the syntax needed to creat
|
|||
The main advantage of using an arrow function as a method inside a constructor is that the value of `this` gets set at the time of the function creation and can't change after that. So, when the constructor is used to create a new object, `this` will always refer to that object. For example, let's say we have a `Person` constructor that takes a first name as an argument has two methods to `console.log` that name, one as a regular function and one as an arrow function:
|
||||
|
||||
```js
|
||||
const Person = function(firstName) {
|
||||
const Person = function (firstName) {
|
||||
this.firstName = firstName;
|
||||
this.sayName1 = function() {
|
||||
this.sayName1 = function () {
|
||||
console.log(this.firstName);
|
||||
};
|
||||
this.sayName2 = () => {
|
||||
|
|
@ -1277,8 +1277,8 @@ const Person = function(firstName) {
|
|||
};
|
||||
};
|
||||
|
||||
const john = new Person("John");
|
||||
const dave = new Person("Dave");
|
||||
const john = new Person('John');
|
||||
const dave = new Person('Dave');
|
||||
|
||||
john.sayName1(); // John
|
||||
john.sayName2(); // John
|
||||
|
|
@ -1320,13 +1320,13 @@ A higher-order function is any function that takes one or more functions as argu
|
|||
Let say we have an array of names which we need to transform each string to uppercase.
|
||||
|
||||
```js
|
||||
const names = ["irish", "daisy", "anna"];
|
||||
const names = ['irish', 'daisy', 'anna'];
|
||||
```
|
||||
|
||||
The imperative way will be as such:
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
const transformNamesToUppercase = function (names) {
|
||||
const results = [];
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
results.push(names[i].toUpperCase());
|
||||
|
|
@ -1339,8 +1339,8 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
Use `.map(transformerFn)` makes the code shorter and more declarative.
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
return names.map(name => name.toUpperCase());
|
||||
const transformNamesToUppercase = function (names) {
|
||||
return names.map((name) => name.toUpperCase());
|
||||
};
|
||||
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
||||
```
|
||||
|
|
@ -1361,7 +1361,7 @@ Destructuring is an expression available in ES6 which enables a succinct and con
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const foo = ["one", "two", "three"];
|
||||
const foo = ['one', 'two', 'three'];
|
||||
|
||||
const [one, two, three] = foo;
|
||||
console.log(one); // "one"
|
||||
|
|
@ -1383,8 +1383,8 @@ console.log(b); // 1
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const o = { p: 42, q: true };
|
||||
const { p, q } = o;
|
||||
const o = {p: 42, q: true};
|
||||
const {p, q} = o;
|
||||
|
||||
console.log(p); // 42
|
||||
console.log(q); // true
|
||||
|
|
@ -1402,9 +1402,9 @@ console.log(q); // true
|
|||
Template literals help make it simple to do string interpolation, or to include variables in a string. Before ES2015, it was common to do something like this:
|
||||
|
||||
```js
|
||||
var person = { name: "Tyler", age: 28 };
|
||||
var person = {name: 'Tyler', age: 28};
|
||||
console.log(
|
||||
"Hi, my name is " + person.name + " and I am " + person.age + " years old!"
|
||||
'Hi, my name is ' + person.name + ' and I am ' + person.age + ' years old!',
|
||||
);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1412,7 +1412,7 @@ console.log(
|
|||
With template literals, you can now create that same output like this instead:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1422,7 +1422,7 @@ Note that you use backticks, not quotes, to indicate that you are using a templa
|
|||
A second helpful use case is in creating multi-line strings. Before ES2015, you could create a multi-line string like this:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\nThis is line two.");
|
||||
console.log('This is line one.\nThis is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1430,7 +1430,7 @@ console.log("This is line one.\nThis is line two.");
|
|||
Or if you wanted to break it up into multiple lines in your code so you didn't have to scroll to the right in your text editor to read a long string, you could also write it like this:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\n" + "This is line two.");
|
||||
console.log('This is line one.\n' + 'This is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1447,7 +1447,7 @@ This is line two.`);
|
|||
Another use case of template literals would be to use as a substitute for templating libraries for simple variable interpolations:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
document.body.innerHTML = `
|
||||
<div>
|
||||
<p>Name: ${person.name}</p>
|
||||
|
|
@ -1475,7 +1475,7 @@ function curry(fn) {
|
|||
}
|
||||
|
||||
function _curried(depth, args) {
|
||||
return function(newArgument) {
|
||||
return function (newArgument) {
|
||||
if (depth - 1 === 0) {
|
||||
return fn(...args, newArgument);
|
||||
}
|
||||
|
|
@ -1508,35 +1508,35 @@ ES6's spread syntax is very useful when coding in a functional paradigm as we ca
|
|||
|
||||
```js
|
||||
function putDookieInAnyArray(arr) {
|
||||
return [...arr, "dookie"];
|
||||
return [...arr, 'dookie'];
|
||||
}
|
||||
|
||||
const result = putDookieInAnyArray(["I", "really", "don't", "like"]); // ["I", "really", "don't", "like", "dookie"]
|
||||
const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"]
|
||||
|
||||
const person = {
|
||||
name: "Todd",
|
||||
age: 29
|
||||
name: 'Todd',
|
||||
age: 29,
|
||||
};
|
||||
|
||||
const copyOfTodd = { ...person };
|
||||
const copyOfTodd = {...person};
|
||||
```
|
||||
|
||||
ES6's rest syntax offers a shorthand for including an arbitrary number of arguments to be passed to a function. It is like an inverse of the spread syntax, taking data and stuffing it into an array rather than unpacking an array of data, and it works in function arguments, as well as in array and object destructuring assignments.
|
||||
|
||||
```js
|
||||
function addFiveToABunchOfNumbers(...numbers) {
|
||||
return numbers.map(x => x + 5);
|
||||
return numbers.map((x) => x + 5);
|
||||
}
|
||||
|
||||
const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15]
|
||||
|
||||
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
|
||||
|
||||
const { e, f, ...others } = {
|
||||
const {e, f, ...others} = {
|
||||
e: 1,
|
||||
f: 2,
|
||||
g: 3,
|
||||
h: 4
|
||||
h: 4,
|
||||
}; // e: 1, f: 2, others: { g: 3, h: 4 }
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="https://cdn.rawgit.com/yangshun/front-end-interview-handbook/23d89c8/assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>クレジット: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">イラスト</a> by <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## これは何のリポジトリですか?
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ CSS の `clear` プロパティは、`left`/`right`/`both` フロート要素の
|
|||
|
||||
```css
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
content: ' ';
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
|
@ -371,14 +371,14 @@ TODO
|
|||
|
||||
比較のために `block` も並べます。
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| ------------------------------------ | --------------------------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| サイズ | 親要素の幅と同じになる。 | 要素によって変わる。 | 要素によって変わる。 |
|
||||
| ポジショニング | 新しい行から始まり、隣に要素を並べられない。(`float`を使う場合を除く) | 他の要素とフローし、隣に要素を並べることができる。 | 他の要素とフローし、隣に要素を並べることができる。 |
|
||||
| `width` と `height` の指定ができるか | はい | はい | いいえ、設定をしても無視される。 |
|
||||
| `vertical-align` を指定できるか | いいえ | はい | はい |
|
||||
| マージンとパディング | 上下左右に指定できる。 | 上下左右に指定できる。 | 左右のみ指定可能。上下に指定をしてもレイアウトに影響はない。 `border` と `padding` が要素の周りに視覚的に現れていても、上下のスペースは `line-height` によって決まる。 |
|
||||
| フロート | - | - | 上下の `margins` と `paddings` を設定できる `block` 要素のようになる。 |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| サイズ | 親要素の幅と同じになる。 | 要素によって変わる。 | 要素によって変わる。 |
|
||||
| ポジショニング | 新しい行から始まり、隣に要素を並べられない。(`float`を使う場合を除く) | 他の要素とフローし、隣に要素を並べることができる。 | 他の要素とフローし、隣に要素を並べることができる。 |
|
||||
| `width` と `height` の指定ができるか | はい | はい | いいえ、設定をしても無視される。 |
|
||||
| `vertical-align` を指定できるか | いいえ | はい | はい |
|
||||
| マージンとパディング | 上下左右に指定できる。 | 上下左右に指定できる。 | 左右のみ指定可能。上下に指定をしてもレイアウトに影響はない。 `border` と `padding` が要素の周りに視覚的に現れていても、上下のスペースは `line-height` によって決まる。 |
|
||||
| フロート | - | - | 上下の `margins` と `paddings` を設定できる `block` 要素のようになる。 |
|
||||
|
||||
[[↑] 先頭に戻る](#css-に関する質問)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,14 +94,14 @@ JavaScript フレームワークが普及する前に、フロントエンドの
|
|||
|
||||
これらの技術は、クライアント側の key-value ストレージメカニズムです。彼らは文字列として値を格納することだけができます。
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| ---------------------------------------- | -------------------------------------------------------- | -------------- | ---------------- |
|
||||
| イニシエータ | クライアントかサーバ。サーバは `Set-Cookie` ヘッダ使用可 | クライアント | クライアント |
|
||||
| 有効期限 | 手動で設定 | 永続 | タブを閉じるまで |
|
||||
| ブラウザセッション間で保持するか | 有効期限が設定されているかどうかによって異なります | はい | いいえ |
|
||||
| すべての HTTP リクエストでサーバーに送信 | クッキーは自動的に `Cookie` ヘッダ経由で送信されます | いいえ | いいえ |
|
||||
| ドメインごとの容量 | 4kB | 5MB | 5MB |
|
||||
| アクセシビリティ | ウィンドウ全て | ウィンドウ全て | 同じタブ |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| イニシエータ | クライアントかサーバ。サーバは `Set-Cookie` ヘッダ使用可 | クライアント | クライアント |
|
||||
| 有効期限 | 手動で設定 | 永続 | タブを閉じるまで |
|
||||
| ブラウザセッション間で保持するか | 有効期限が設定されているかどうかによって異なります | はい | いいえ |
|
||||
| すべての HTTP リクエストでサーバーに送信 | クッキーは自動的に `Cookie` ヘッダ経由で送信されます | いいえ | いいえ |
|
||||
| ドメインごとの容量 | 4kB | 5MB | 5MB |
|
||||
| アクセシビリティ | ウィンドウ全て | ウィンドウ全て | 同じタブ |
|
||||
|
||||
###### 参考
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="https://cdn.rawgit.com/yangshun/front-end-interview-handbook/23d89c8/assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Credits: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Illustration</a> by <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
<p>
|
||||
<em>번역: <a href="https://github.com/ysm0622">@양성민</a>, <a href="https://github.com/devjang">@장현석</a>, <a href="https://github.com/tuhbm">@김태균</a>, <a href="https://github.com/octave08">@황규정</a>
|
||||
</em>
|
||||
|
|
@ -57,7 +52,7 @@
|
|||
|
||||
이 프로젝트에 많은 시간과 노력을 들였습니다. 지원 부탁드립니다!
|
||||
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;"/></a>
|
||||
|
||||
## 라이센스
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ CSS `clear` 속성은 float 요소에 `left`/`right`/`both`에 위치하도록
|
|||
|
||||
```css
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
content: ' ';
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
|
@ -398,14 +398,14 @@ TODO
|
|||
|
||||
좋은 비교를 위해 `block` 과도 비교해 볼 것입니다.
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 크기 | 부모 컨테이너의 너비를 채웁니다. | 내용에 의존합니다. | 내용에 의존합니다. |
|
||||
| 위치 | 새 줄에서 시작하고, 그 옆에 HTML 요소를 허용하지 않습니다 (`float`을 추가 할 때 제외). | 다른 콘텐츠와 함께 흐르고, 다른 요소가 옆에 있는 것을 허용합니다. | 다른 콘텐츠와 함께 흐르고, 다른 요소가 옆에 있는 것을 허용합니다. |
|
||||
| `width`, `height` 지정 가능 여부 | 가능 | 가능 | 불가능. 설정되면 무시됩니다. |
|
||||
| `vertical-align` 정렬 가능 여부 | 불가능 | 가능 | 가능 |
|
||||
| margin 과 padding | 모든 방향에서 가능. | 모든 방향에서 가능. | 수평방향만 가능. 세로방향을 지정하면, 레이아웃에 영향을 주지 않습니다. `border`와 `padding`이 콘텐츠 주위에 시각적으로 나타나는 경우에도, 수직영역은 `line-height`에 의존합니다. |
|
||||
| Float | - | - | 수직 margin과 padding을 설정할 수 있는 `block` 요소와 같아집니다. |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| 크기 | 부모 컨테이너의 너비를 채웁니다. | 내용에 의존합니다. | 내용에 의존합니다. |
|
||||
| 위치 | 새 줄에서 시작하고, 그 옆에 HTML 요소를 허용하지 않습니다 (`float`을 추가 할 때 제외). | 다른 콘텐츠와 함께 흐르고, 다른 요소가 옆에 있는 것을 허용합니다. | 다른 콘텐츠와 함께 흐르고, 다른 요소가 옆에 있는 것을 허용합니다. |
|
||||
| `width`, `height` 지정 가능 여부 | 가능 | 가능 | 불가능. 설정되면 무시됩니다. |
|
||||
| `vertical-align` 정렬 가능 여부 | 불가능 | 가능 | 가능 |
|
||||
| margin 과 padding | 모든 방향에서 가능. | 모든 방향에서 가능. | 수평방향만 가능. 세로방향을 지정하면, 레이아웃에 영향을 주지 않습니다. `border`와 `padding`이 콘텐츠 주위에 시각적으로 나타나는 경우에도, 수직영역은 `line-height`에 의존합니다. |
|
||||
| Float | - | - | 수직 margin과 padding을 설정할 수 있는 `block` 요소와 같아집니다. |
|
||||
|
||||
[[↑] Back to top](#css-질문)
|
||||
|
||||
|
|
@ -505,8 +505,7 @@ Grid는 그리드 기반의 레이아웃을 생성하기 위한 가장 직관적
|
|||
|
||||
### 레티나 그래픽으로 작업 해본 적이 있나요? 그렇다면, 언제, 어떤 기술을 사용하였나요?
|
||||
|
||||
_레티나_ 는 픽셀 비율이 1보다 큰 고해상도 화면을 나타내는 마케팅 용어 일뿐입니다. 중요하게 알아야할 것은 픽셀 비율을 사용하면 이러한 디스플레이가 동일한 크기의 요소를 표시하기 위해 더 저해상도의 화면으로 표현한다는 것입니다.
|
||||
요즘에는 모든 모바일 디바이스를 _레티나_ 디스플레이로 간주합니다.
|
||||
_레티나_ 는 픽셀 비율이 1보다 큰 고해상도 화면을 나타내는 마케팅 용어 일뿐입니다. 중요하게 알아야할 것은 픽셀 비율을 사용하면 이러한 디스플레이가 동일한 크기의 요소를 표시하기 위해 더 저해상도의 화면으로 표현한다는 것입니다. 요즘에는 모든 모바일 디바이스를 _레티나_ 디스플레이로 간주합니다.
|
||||
|
||||
브라우저는 기본적으로 이미지들을 제외하고 디바이스의 해상도에 따라 DOM 요소를 렌더링합니다.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,11 @@
|
|||
|
||||
### `DOCTYPE`은 무엇을 하나요?
|
||||
|
||||
**DOCTYPE**은 **document type**의 약어입니다.
|
||||
**DOCTYPE**은 항상 **DTD(Document Type Definition)**와 관련됩니다.
|
||||
**DOCTYPE**은 **document type**의 약어입니다. **DOCTYPE**은 항상 **DTD(Document Type Definition)**와 관련됩니다.
|
||||
|
||||
**DTD**는 특정 문서가 어떻게 구성되어야 하는지 정의합니다(예시: `button`은 `span`을 포함할 수 있지만, `div`는 그럴 수 없다.), 반면, **DOCTYPE**은 문서가 _대략_ 존중할만한 **DTD**를 선언합니다. (예시: 이 문서는 HTML DTD를 존중한다.)
|
||||
|
||||
웹 페이지의는 DOCTYPE 선언이 필요합니다. 유저 에이전트에게 문서가 존중하는 HTML 사양의 버전을 알리는데 사용됩니다.
|
||||
유저 에이전트가 올바른 DOCTYPE을 인식하면, 문서를 읽는데에 DOCTYPE과 일치하는 **no-quirks mode**를 트리거합니다.
|
||||
유저 에이전트가 올바른 DOCTYPE을 인식하지 못하면, **quirks mode**를 트리거합니다.
|
||||
웹 페이지의는 DOCTYPE 선언이 필요합니다. 유저 에이전트에게 문서가 존중하는 HTML 사양의 버전을 알리는데 사용됩니다. 유저 에이전트가 올바른 DOCTYPE을 인식하면, 문서를 읽는데에 DOCTYPE과 일치하는 **no-quirks mode**를 트리거합니다. 유저 에이전트가 올바른 DOCTYPE을 인식하지 못하면, **quirks mode**를 트리거합니다.
|
||||
|
||||
HTML5 표준에 대한 DOCTYPE 선언은 `<!DOCTYPE html>`입니다.
|
||||
|
||||
|
|
@ -100,14 +97,14 @@ JavaScript 프레임워크가 인기있기 전에, 프론트엔드 개발자는
|
|||
|
||||
위 세 가지 기술은 모두 클라이언트 측에서 값을 저장하는 key-value 저장소 매커니즘입니다. 모두 문자열로만 값을 저장할 수 있습니다.
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --------------------------------- | ---------------------------------------------------------------- | -------------- | ---------------- |
|
||||
| 생성자 | 클라이언트나 서버. 서버는 `Set-Cookie` 헤더를 사용할 수 있습니다 | 클라이언트 | 클라이언트 |
|
||||
| 만료 | 수동으로 설정 | 영구적 | 탭을 닫을 때 |
|
||||
| 브라우저 세션 전체에서 지속 | 만료 설정 여부에 따라 다름 | O | X |
|
||||
| 모든 HTTP 요청과 함께 서버로 보냄 | 쿠키는 `Cookie` 헤더를 통해 자동 전송됨 | X | X |
|
||||
| 용량 (도메인당) | 4kb | 5MB | 5MB |
|
||||
| 접근성 | 모든 윈도우 | 모든 윈도우 | 같은 탭 |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| 생성자 | 클라이언트나 서버. 서버는 `Set-Cookie` 헤더를 사용할 수 있습니다 | 클라이언트 | 클라이언트 |
|
||||
| 만료 | 수동으로 설정 | 영구적 | 탭을 닫을 때 |
|
||||
| 브라우저 세션 전체에서 지속 | 만료 설정 여부에 따라 다름 | O | X |
|
||||
| 모든 HTTP 요청과 함께 서버로 보냄 | 쿠키는 `Cookie` 헤더를 통해 자동 전송됨 | X | X |
|
||||
| 용량 (도메인당) | 4kb | 5MB | 5MB |
|
||||
| 접근성 | 모든 윈도우 | 모든 윈도우 | 같은 탭 |
|
||||
|
||||
###### 참고자료
|
||||
|
||||
|
|
|
|||
|
|
@ -73,8 +73,7 @@
|
|||
|
||||
### `this`가 JavaScript에서 어떻게 작동하는지 설명하세요.
|
||||
|
||||
`this`는 간단하게 설명하기 어렵습니다. JavaScript에서 가장 혼란스러운 개념 중 하나입니다. 대략 설명하면 `this`의 값은 함수가 호출되는 방식에 따라 달라집니다. 온라인에 많은 설명을 읽었는데, [Arnav Aggrawal](https://medium.com/@arnav_aggarwal)의 설명이 가장 명확했습니다.
|
||||
다음 규칙과 같습니다.
|
||||
`this`는 간단하게 설명하기 어렵습니다. JavaScript에서 가장 혼란스러운 개념 중 하나입니다. 대략 설명하면 `this`의 값은 함수가 호출되는 방식에 따라 달라집니다. 온라인에 많은 설명을 읽었는데, [Arnav Aggrawal](https://medium.com/@arnav_aggarwal)의 설명이 가장 명확했습니다. 다음 규칙과 같습니다.
|
||||
|
||||
1. 함수를 호출할 때 `new` 키워드를 사용하는 경우, 함수 내부에 있는 `this`는 완전히 새로운 객체입니다.
|
||||
2. `apply`, `call`, `bind`가 함수의 호출/생성에 사용되는 경우, 함수 내의 `this`는 인수로 전달된 객체입니다.
|
||||
|
|
@ -129,7 +128,7 @@ IIFE는 즉시 함수 호출 표현식(Immediately Invoked Function Expressions)
|
|||
```js
|
||||
// Don't add JS syntax to this code block to prevent Prettier from formatting it.
|
||||
const foo = void (function bar() {
|
||||
return "foo";
|
||||
return 'foo';
|
||||
})();
|
||||
|
||||
console.log(foo); // undefined
|
||||
|
|
@ -161,7 +160,7 @@ console.log(x); // 1
|
|||
var foo;
|
||||
console.log(foo); // undefined
|
||||
console.log(foo === undefined); // true
|
||||
console.log(typeof foo === "undefined"); // true
|
||||
console.log(typeof foo === 'undefined'); // true
|
||||
|
||||
console.log(foo == null); // true. 옳지않습니다. 이렇게 사용하지 마세요.
|
||||
|
||||
|
|
@ -230,7 +229,7 @@ const doubled = a.forEach((num, index) => {
|
|||
|
||||
```js
|
||||
const a = [1, 2, 3];
|
||||
const doubled = a.map(num => {
|
||||
const doubled = a.map((num) => {
|
||||
return num * 2;
|
||||
});
|
||||
|
||||
|
|
@ -250,7 +249,7 @@ const doubled = a.map(num => {
|
|||
익명함수는 IIFE로 사용되어 지역 범위 내에서 일부 코드를 캡슐화하므로 선언된 변수가 전역 범위로 누출되지 않습니다.
|
||||
|
||||
```js
|
||||
(function() {
|
||||
(function () {
|
||||
// 코드
|
||||
})();
|
||||
```
|
||||
|
|
@ -258,8 +257,8 @@ const doubled = a.map(num => {
|
|||
한 번 사용되고 다른 곳에서는 사용할 필요가 없는 콜백으로 사용됩니다. 함수 본체를 찾기 위해 다른 곳을 찾아볼 필요 없이 코드를 호출하는 코드 바로 안에 핸들러가 정의되어 있으면 코드가 보다 독립적이고 읽기 쉽게 보일 것입니다.
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
console.log("Hello world!");
|
||||
setTimeout(function () {
|
||||
console.log('Hello world!');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
|
@ -267,7 +266,7 @@ setTimeout(function() {
|
|||
|
||||
```js
|
||||
const arr = [1, 2, 3];
|
||||
const double = arr.map(function(el) {
|
||||
const double = arr.map(function (el) {
|
||||
return el * 2;
|
||||
});
|
||||
console.log(double); // [2, 4, 6]
|
||||
|
|
@ -315,11 +314,11 @@ function Person(name) {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
var person = Person("John");
|
||||
var person = Person('John');
|
||||
console.log(person); // undefined
|
||||
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
||||
|
||||
var person = new Person("John");
|
||||
var person = new Person('John');
|
||||
console.log(person); // Person { name: "John" }
|
||||
console.log(person.name); // "john"
|
||||
```
|
||||
|
|
@ -379,7 +378,7 @@ console.log(add.apply(null, [1, 2])); // 3
|
|||
Feature Detection은 브라우저가 특정 코드 블록을 지원하는지에 따라 다른 코드를 실행하도록 하여, 일부 브라우저에서 항상 오류 대신 무언가 작동하도록 합니다. 예:
|
||||
|
||||
```js
|
||||
if ("geolocation" in navigator) {
|
||||
if ('geolocation' in navigator) {
|
||||
// navigator.geolocation를 사용할 수 있습니다
|
||||
} else {
|
||||
// 부족한 기능 핸들링
|
||||
|
|
@ -462,7 +461,7 @@ JSONP는 `<script>`태그를 통해 cross-origin 도메인에 요청하고 보
|
|||
|
||||
```js
|
||||
// https://example.com?callback=printData 에서 로드된 파일
|
||||
printData({ name: "Yang Shun" });
|
||||
printData({name: 'Yang Shun'});
|
||||
```
|
||||
|
||||
클라이언트는 전역 범위에 있는 `printData` 함수를 가져야만 하고, cross-origin domain으로부터의 응답이 수신될 때 함수가 클라이언트에 의해 실행됩니다.
|
||||
|
|
@ -514,15 +513,15 @@ console.log(bar); // 2
|
|||
console.log(foo); // [Function: foo]
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
console.log(foo); // [Function: foo]
|
||||
|
||||
// 함수 표현식
|
||||
console.log(bar); // undefined
|
||||
bar(); // Uncaught TypeError: bar is not a function
|
||||
var bar = function() {
|
||||
console.log("BARRRR");
|
||||
var bar = function () {
|
||||
console.log('BARRRR');
|
||||
};
|
||||
console.log(bar); // [Function: bar]
|
||||
```
|
||||
|
|
@ -540,15 +539,15 @@ DOM 요소에서 이벤트가 트리거되면 리스너가 연결되어 있는
|
|||
attribute는 HTML 마크업에 정의되지만 property는 DOM에 정의됩니다. 차이점을 설명하기 위해 HTML에 다음 텍스트 필드가 있다고 가정해 봅시다: `<input type="text" value="Hello">`.
|
||||
|
||||
```js
|
||||
const input = document.querySelector("input");
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
const input = document.querySelector('input');
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello
|
||||
```
|
||||
|
||||
그러나 텍스트 필드에 "World!"를 추가하면 이렇게 될것입니다.
|
||||
|
||||
```js
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -588,11 +587,11 @@ console.log(input.value); // Hello World!
|
|||
`==`는 추상 동등 연산자이고 `===`는 완전 동등 연산자입니다. `==`연산자는 타입 변환이 필요한 경우 타입 변환을 한 후에 동등한지 비교할 것입니다. `===`연산자는 타입 변환을 하지 않으므로 두 값이 같은 타입이 아닌 경우 `===`는 `false`를 반환합니다. `==`를 사용하면 다음과 같은 무서운 일이 발생할 수 있습니다.
|
||||
|
||||
```js
|
||||
1 == "1"; // true
|
||||
1 == '1'; // true
|
||||
1 == [1]; // true
|
||||
1 == true; // true
|
||||
0 == ""; // true
|
||||
0 == "0"; // true
|
||||
0 == ''; // true
|
||||
0 == '0'; // true
|
||||
0 == false; // true
|
||||
```
|
||||
|
||||
|
|
@ -683,7 +682,7 @@ duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
|||
for (let i = 1; i <= 100; i++) {
|
||||
let f = i % 3 == 0,
|
||||
b = i % 5 == 0;
|
||||
console.log(f ? (b ? "FizzBuzz" : "Fizz") : b ? "Buzz" : i);
|
||||
console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -733,8 +732,7 @@ TODO.
|
|||
|
||||
- 여러 페이지에 필요한 프레임워크, 앱 코드, 애셋로드로 인해 초기 페이지로드가 무거워집니다.
|
||||
- 모든 요청을 단일 진입점으로 라우트하고 클라이언트 측 라우팅이 그 한곳에서 인계받을 수 있도록 서버를 구성하는 추가 단계가 필요합니다.
|
||||
- SPA는 콘텐츠를 렌더링하기 위해 JavaScript에 의존하지만 모든 검색 엔진이 크롤링 중에 JavaScript를 실행하지는 않으며 페이지에 빈 콘텐츠가 표시될 수 있습니다. 이로 인해 의도치 않게 앱의 검색 엔진 최적화(SEO)가 어려워집니다.
|
||||
그러나 대부분의 경우 앱을 제작할 때 검색 엔진에서 모든 콘텐츠 색인할 필요는 없으므로 SEO가 가장 중요한 요소는 아닙니다. 이를 극복하기 위해, 앱을 서버 측 렌더링하거나 [Prerender](https://prerender.io/)와 같은 서비스를 사용하여 "브라우저에서 JavaScript를 렌더링하고, 정적 HTML을 저장한 다음, 크롤러에게 반환합니다".
|
||||
- SPA는 콘텐츠를 렌더링하기 위해 JavaScript에 의존하지만 모든 검색 엔진이 크롤링 중에 JavaScript를 실행하지는 않으며 페이지에 빈 콘텐츠가 표시될 수 있습니다. 이로 인해 의도치 않게 앱의 검색 엔진 최적화(SEO)가 어려워집니다. 그러나 대부분의 경우 앱을 제작할 때 검색 엔진에서 모든 콘텐츠 색인할 필요는 없으므로 SEO가 가장 중요한 요소는 아닙니다. 이를 극복하기 위해, 앱을 서버 측 렌더링하거나 [Prerender](https://prerender.io/)와 같은 서비스를 사용하여 "브라우저에서 JavaScript를 렌더링하고, 정적 HTML을 저장한 다음, 크롤러에게 반환합니다".
|
||||
|
||||
###### 참고자료
|
||||
|
||||
|
|
@ -846,10 +844,10 @@ JavaScript로 컴파일되는 언어의 예로 CoffeeScript, Elm, ClojureScript,
|
|||
또한, `for-of` 루프를 사용할 때 각 배열 요소의 인덱스와 값에 모두 접근해야하는 경우 ES6 Array의 `entries()` 메소드와 destructuring을 사용하면됩니다.
|
||||
|
||||
```js
|
||||
const arr = ["a", "b", "c"];
|
||||
const arr = ['a', 'b', 'c'];
|
||||
|
||||
for (let [index, elem] of arr.entries()) {
|
||||
console.log(index, ": ", elem);
|
||||
console.log(index, ': ', elem);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -900,7 +898,7 @@ Philip Robert의 [talk on the Event Loop](https://2014.jsconf.eu/speakers/philip
|
|||
```js
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -908,8 +906,8 @@ function foo() {
|
|||
|
||||
```js
|
||||
foo(); // Uncaught TypeError: foo는 함수가 아닙니다
|
||||
var foo = function() {
|
||||
console.log("FOOOOO");
|
||||
var foo = function () {
|
||||
console.log('FOOOOO');
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -926,9 +924,9 @@ var foo = function() {
|
|||
```js
|
||||
function foo() {
|
||||
// 함수 내에서 모든 변수에 접근할 수 있습니다.
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
|
||||
console.log(bar); // "bar"
|
||||
console.log(baz); // "baz"
|
||||
|
|
@ -942,9 +940,9 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
|
||||
```js
|
||||
if (true) {
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
}
|
||||
|
||||
// var로 선언된 변수는 함수 스코프의 어디에서나 접근할 수 있습니다.
|
||||
|
|
@ -959,38 +957,38 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
```js
|
||||
console.log(foo); // undefined
|
||||
|
||||
var foo = "foo";
|
||||
var foo = 'foo';
|
||||
|
||||
console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization
|
||||
|
||||
let baz = "baz";
|
||||
let baz = 'baz';
|
||||
|
||||
console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization
|
||||
|
||||
const bar = "bar";
|
||||
const bar = 'bar';
|
||||
```
|
||||
|
||||
`var`을 사용하여 변수를 다시 선언해도 에러가 발생하지 않지만, `let`과 `const`는 에러를 발생시킵니다.
|
||||
|
||||
```js
|
||||
var foo = "foo";
|
||||
var foo = "bar";
|
||||
var foo = 'foo';
|
||||
var foo = 'bar';
|
||||
console.log(foo); // "bar"
|
||||
|
||||
let baz = "baz";
|
||||
let baz = "qux"; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
let baz = 'baz';
|
||||
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
```
|
||||
|
||||
`let`은 변수의 값을 재할당할 수 있지만, `const`는 재할당할 수 없다는 점이 다릅니다.
|
||||
|
||||
```js
|
||||
// 괜찮습니다
|
||||
let foo = "foo";
|
||||
foo = "bar";
|
||||
let foo = 'foo';
|
||||
foo = 'bar';
|
||||
|
||||
// 예외가 발생합니다
|
||||
const baz = "baz";
|
||||
baz = "qux";
|
||||
const baz = 'baz';
|
||||
baz = 'qux';
|
||||
```
|
||||
|
||||
###### 참고자료
|
||||
|
|
@ -1073,9 +1071,9 @@ ES5에서 상속을 사용하는 것이 훨씬 더 불편하며, ES6 버전이
|
|||
예를 들어, 우리가 인수로 first name을 받고, 그 이름을 `console.log`로 출력하는 `Person` 생성자가 있다고 해봅시다. 하나는 일반 함수이고, 다른 하나는 화살표 함수일 때,
|
||||
|
||||
```js
|
||||
const Person = function(firstName) {
|
||||
const Person = function (firstName) {
|
||||
this.firstName = firstName;
|
||||
this.sayName1 = function() {
|
||||
this.sayName1 = function () {
|
||||
console.log(this.firstName);
|
||||
};
|
||||
this.sayName2 = () => {
|
||||
|
|
@ -1083,8 +1081,8 @@ const Person = function(firstName) {
|
|||
};
|
||||
};
|
||||
|
||||
const john = new Person("John");
|
||||
const dave = new Person("Dave");
|
||||
const john = new Person('John');
|
||||
const dave = new Person('Dave');
|
||||
|
||||
john.sayName1(); // John
|
||||
john.sayName2(); // John
|
||||
|
|
@ -1130,13 +1128,13 @@ sayNameFromWindow2(); // John
|
|||
각 요소를 대문자 문자열로 변환해야하는 이름들을 가진 배열이 있다고 가정해 보겠습니다.
|
||||
|
||||
```js
|
||||
const names = ["irish", "daisy", "anna"];
|
||||
const names = ['irish', 'daisy', 'anna'];
|
||||
```
|
||||
|
||||
일반적인 방법은 다음과 같습니다.
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
const transformNamesToUppercase = function (names) {
|
||||
const results = [];
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
results.push(names[i].toUpperCase());
|
||||
|
|
@ -1149,8 +1147,8 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
`.map(transformerFn)`을 사용하면 코드가 더 짧아지고 선언적이어집니다.
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
return names.map(name => name.toUpperCase());
|
||||
const transformNamesToUppercase = function (names) {
|
||||
return names.map((name) => name.toUpperCase());
|
||||
};
|
||||
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
||||
```
|
||||
|
|
@ -1171,7 +1169,7 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
|
||||
```js
|
||||
// 변수 할당.
|
||||
const foo = ["one", "two", "three"];
|
||||
const foo = ['one', 'two', 'three'];
|
||||
|
||||
const [one, two, three] = foo;
|
||||
console.log(one); // "one"
|
||||
|
|
@ -1193,8 +1191,8 @@ console.log(b); // 1
|
|||
|
||||
```js
|
||||
// 변수 할당.
|
||||
const o = { p: 42, q: true };
|
||||
const { p, q } = o;
|
||||
const o = {p: 42, q: true};
|
||||
const {p, q} = o;
|
||||
|
||||
console.log(p); // 42
|
||||
console.log(q); // true
|
||||
|
|
@ -1212,9 +1210,9 @@ console.log(q); // true
|
|||
템플릿 리터럴을 사용하면 문자열 보간을 하거나 문자열에 변수를 포함하는 작업을 간단하게 수행할 수 있습니다. ES2015 이전에는 아래와 같이하는 것이 일반적이었습니다.
|
||||
|
||||
```js
|
||||
var person = { name: "Tyler", age: 28 };
|
||||
var person = {name: 'Tyler', age: 28};
|
||||
console.log(
|
||||
"Hi, my name is " + person.name + " and I am " + person.age + " years old!"
|
||||
'Hi, my name is ' + person.name + ' and I am ' + person.age + ' years old!',
|
||||
);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1222,7 +1220,7 @@ console.log(
|
|||
템플릿 리터럴을 사용하면, 대신 이렇게해도 같은 출력을 만들 수 있습니다.
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1232,7 +1230,7 @@ console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
|||
두번째 유용한 사용사례는 다중행 문자열을 만드는 것입니다. ES2015 이전에는 아래와 같이 다행의 문자열을 만들 수 있었습니다.
|
||||
|
||||
```js
|
||||
console.log("This is line one.\nThis is line two.");
|
||||
console.log('This is line one.\nThis is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1240,7 +1238,7 @@ console.log("This is line one.\nThis is line two.");
|
|||
또는 코드에서 여러 줄로 나눠진 긴 문자열을 읽기 위해 텍스트 편집기에서 오른쪽으로 스크롤 할 필요가 없도록하려면 다음과 같이 작성할 수 있습니다.
|
||||
|
||||
```js
|
||||
console.log("This is line one.\n" + "This is line two.");
|
||||
console.log('This is line one.\n' + 'This is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1257,7 +1255,7 @@ This is line two.`);
|
|||
템플릿 리터럴의 또 다른 사용사례는 간단한 변수 보간을 위한 템플릿 라이브러리의 대체품으로 사용하는 것입니다.
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
document.body.innerHTML = `
|
||||
<div>
|
||||
<p>Name: ${person.name}</p>
|
||||
|
|
@ -1285,7 +1283,7 @@ function curry(fn) {
|
|||
}
|
||||
|
||||
function _curried(depth, args) {
|
||||
return function(newArgument) {
|
||||
return function (newArgument) {
|
||||
if (depth - 1 === 0) {
|
||||
return fn(...args, newArgument);
|
||||
}
|
||||
|
|
@ -1318,35 +1316,35 @@ ES6의 spread 문법은 함수형 패러다임에서 코딩할 때 매우 유용
|
|||
|
||||
```js
|
||||
function putDookieInAnyArray(arr) {
|
||||
return [...arr, "dookie"];
|
||||
return [...arr, 'dookie'];
|
||||
}
|
||||
|
||||
var result = putDookieInAnyArray(["I", "really", "don't", "like"]); // ["I", "really", "don't", "like", "dookie"]
|
||||
var result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"]
|
||||
|
||||
var person = {
|
||||
name: "Todd",
|
||||
age: 29
|
||||
name: 'Todd',
|
||||
age: 29,
|
||||
};
|
||||
|
||||
var copyOfTodd = { ...person };
|
||||
var copyOfTodd = {...person};
|
||||
```
|
||||
|
||||
ES6의 rest 구문은 함수에 전달할 임의의 수의 인수를 포함하는 약식을 제공합니다. 이는 데이터의 배열을 채우기보다는 데이터를 가져와서 배열로 채우는 spread 구문의 반대와 비슷하며, 배열이나 객체 디스트럭쳐링 할당뿐만 아니라 함수 인수에서도 작동합니다.
|
||||
|
||||
```js
|
||||
function addFiveToABunchOfNumbers(...numbers) {
|
||||
return numbers.map(x => x + 5);
|
||||
return numbers.map((x) => x + 5);
|
||||
}
|
||||
|
||||
const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15]
|
||||
|
||||
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
|
||||
|
||||
const { e, f, ...others } = {
|
||||
const {e, f, ...others} = {
|
||||
e: 1,
|
||||
f: 2,
|
||||
g: 3,
|
||||
h: 4
|
||||
h: 4,
|
||||
}; // e: 1, f: 2, others: { g: 3, h: 4 }
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Credits: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Rysunek</a> od <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Co to jest?
|
||||
|
|
@ -31,7 +26,7 @@ Możesz być zainteresowany [Tech Interview Handbook](https://github.com/yangshu
|
|||
|
||||
<div align="center">
|
||||
<img src="assets/web-tech.svg" alt="Web Technologies illustration" width="400"/>
|
||||
<br>
|
||||
<br/>
|
||||
<p>
|
||||
<em>Credits: Rysunek od <a href="https://undraw.co/">unDraw</a></em>
|
||||
</p>
|
||||
|
|
@ -71,7 +66,7 @@ Przeczytaj nasz [contributing guide](/CONTRIBUTING.md), aby dowiedzieć się, ja
|
|||
|
||||
Wiele godzin ciężkiej pracy poświęcono temu projektowi. Wasze wsparcie będzie bardzo mile widziane!
|
||||
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;"/></a>
|
||||
|
||||
## Licencja
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ Hack `.clearfix` używa sprytnego CSS [pseudo selektora](#describe-pseudo-elemen
|
|||
|
||||
```css
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
content: ' ';
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
|
@ -399,16 +399,16 @@ Model pudełkowy ma następujące zasady:
|
|||
|
||||
- `none`, `block`, `inline`, `inline-block`, `flex`, `grid`, `table`, `table-row`, `table-cell`, `list-item`.
|
||||
|
||||
| `display` | Description |
|
||||
| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `none` | Does not display an element (the elementv no longer affects the layout of the document). All child element are also no longer displayed. The document is rendered as if the element did not exist in the document tree |
|
||||
| `block` | The element consumes the whole line in the block direction (which is usually horizontal) |
|
||||
| `inline` | Elements can be laid out beside each other |
|
||||
| `inline-block` | Similar to `inline`, but allows some `block` properties like setting `width` and `height` |
|
||||
| `table` | Behaves like the `<table>` element |
|
||||
| `table-row` | Behaves like the `<tr>` element |
|
||||
| `table-cell` | Behaves like the `<td>` element |
|
||||
| `list-item` | Behaves like a `<li>` element which allows it to define `list-style-type` and `list-style-position` |
|
||||
| `display` | Description |
|
||||
| :-- | :-- |
|
||||
| `none` | Does not display an element (the elementv no longer affects the layout of the document). All child element are also no longer displayed. The document is rendered as if the element did not exist in the document tree |
|
||||
| `block` | The element consumes the whole line in the block direction (which is usually horizontal) |
|
||||
| `inline` | Elements can be laid out beside each other |
|
||||
| `inline-block` | Similar to `inline`, but allows some `block` properties like setting `width` and `height` |
|
||||
| `table` | Behaves like the `<table>` element |
|
||||
| `table-row` | Behaves like the `<tr>` element |
|
||||
| `table-cell` | Behaves like the `<td>` element |
|
||||
| `list-item` | Behaves like a `<li>` element which allows it to define `list-style-type` and `list-style-position` |
|
||||
|
||||
[[↑] Powrót na górę](#pytania-z-css)
|
||||
|
||||
|
|
@ -416,14 +416,14 @@ Model pudełkowy ma następujące zasady:
|
|||
|
||||
Dla dobrego porównania wrzucę porównanie z `block`.
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Size | Fills up the width of its parent container. | Depends on content. | Depends on content. |
|
||||
| Positioning | Start on a new line and tolerates no HTML elements next to it (except when you add `float`) | Flows along with other content and allows other elements beside it. | Flows along with other content and allows other elements beside it. |
|
||||
| Can specify `width` and `height` | Yes | Yes | No. Will ignore if being set. |
|
||||
| Can be aligned with `vertical-align` | No | Yes | Yes |
|
||||
| Margins and paddings | All sides respected. | All sides respected. | Only horizontal sides respected. Vertical sides, if specified, do not affect layout. Vertical space it takes up depends on `line-height`, even though the `border` and `padding` appear visually around the content. |
|
||||
| Float | - | - | Becomes like a `block` element where you can set vertical margins and paddings. |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| Size | Fills up the width of its parent container. | Depends on content. | Depends on content. |
|
||||
| Positioning | Start on a new line and tolerates no HTML elements next to it (except when you add `float`) | Flows along with other content and allows other elements beside it. | Flows along with other content and allows other elements beside it. |
|
||||
| Can specify `width` and `height` | Yes | Yes | No. Will ignore if being set. |
|
||||
| Can be aligned with `vertical-align` | No | Yes | Yes |
|
||||
| Margins and paddings | All sides respected. | All sides respected. | Only horizontal sides respected. Vertical sides, if specified, do not affect layout. Vertical space it takes up depends on `line-height`, even though the `border` and `padding` appear visually around the content. |
|
||||
| Float | - | - | Becomes like a `block` element where you can set vertical margins and paddings. |
|
||||
|
||||
[[↑] Powrót na górę](#pytania-z-css)
|
||||
|
||||
|
|
@ -583,5 +583,6 @@ Kiedy używasz `translate ()`, element nadal zajmuje swoją pierwotną przestrze
|
|||
- https://quizlet.com/28293152/front-end-interview-questions-css-flash-cards/
|
||||
- http://peterdoes.it/2015/12/03/a-personal-exercise-front-end-job-interview-questions-and-my-answers-all/
|
||||
|
||||
___________________________
|
||||
---
|
||||
|
||||
Stworzone przez @[yangshun](https://github.com/yangshun) polska wersja od @[mbiesiad](https://github.com/mbiesiad)
|
||||
|
|
|
|||
|
|
@ -16,14 +16,11 @@ Odpowiedzi do [Front-end Job Interview Questions - HTML Questions](https://githu
|
|||
|
||||
### Co robi DOCTYPE?
|
||||
|
||||
**DOCTYPE** to skrót od **DOCument TYPE**.
|
||||
DOCTYPE jest zawsze powiązany z **DTD** - tzn z **Document Type Definition**.
|
||||
**DOCTYPE** to skrót od **DOCument TYPE**. DOCTYPE jest zawsze powiązany z **DTD** - tzn z **Document Type Definition**.
|
||||
|
||||
DTD określa, w jaki sposób powinny być uporządkowane dokumenty określonego rodzaju (np. `button` może zawierać `span` ale nie `div`), podczas gdy DOCTYPE deklaruje to, co DTD _jakoby_ respektuje (np. ten dokument jest zgodny z DTD HTML).
|
||||
|
||||
W przypadku stron internetowych wymagana jest deklaracja DOCTYPE. Służy do informowania agentów użytkownika (user agents), jakiej wersji specyfikacji HTML dotyczy twój dokument.
|
||||
Gdy user agent rozpozna prawidłowy DOCTYPE, uruchomi **tryb no-quirks** pasujący do tego DOCTYPE do odczytu dokumentu.
|
||||
Jeśli user agent nie rozpozna prawidłowego DOCTYPE, uruchomi **tryb quirks**.
|
||||
W przypadku stron internetowych wymagana jest deklaracja DOCTYPE. Służy do informowania agentów użytkownika (user agents), jakiej wersji specyfikacji HTML dotyczy twój dokument. Gdy user agent rozpozna prawidłowy DOCTYPE, uruchomi **tryb no-quirks** pasujący do tego DOCTYPE do odczytu dokumentu. Jeśli user agent nie rozpozna prawidłowego DOCTYPE, uruchomi **tryb quirks**.
|
||||
|
||||
Deklaracja DOCTYPE dla standardów HTML5 to `<!DOCTYPE html>`.
|
||||
|
||||
|
|
@ -102,14 +99,14 @@ Jednakże, jednym całkowicie poprawnym zastosowaniem atrybutów danych jest dod
|
|||
|
||||
Wszystkie wyżej wymienione technologie są kluczowymi mechanizmami przechowywania po stronie klienta. Są w stanie przechowywać wartości tylko jako ciągi znaków (strings).
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| -------------------------------------- | -------------------------------------------------------- | -------------- | ---------------- |
|
||||
| Initiator | Client or server. Server can use `Set-Cookie` header | Client | Client |
|
||||
| Expiry | Manually set | Forever | On tab close |
|
||||
| Persistent across browser sessions | Depends on whether expiration is set | Yes | No |
|
||||
| Sent to server with every HTTP request | Cookies are automatically being sent via `Cookie` header | No | No |
|
||||
| Capacity (per domain) | 4kb | 5MB | 5MB |
|
||||
| Accessibility | Any window | Any window | Same tab |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| Initiator | Client or server. Server can use `Set-Cookie` header | Client | Client |
|
||||
| Expiry | Manually set | Forever | On tab close |
|
||||
| Persistent across browser sessions | Depends on whether expiration is set | Yes | No |
|
||||
| Sent to server with every HTTP request | Cookies are automatically being sent via `Cookie` header | No | No |
|
||||
| Capacity (per domain) | 4kb | 5MB | 5MB |
|
||||
| Accessibility | Any window | Any window | Same tab |
|
||||
|
||||
_Uwaga: Jeśli użytkownik zdecyduje się wyczyścić dane przeglądania za pomocą dowolnego mechanizmu zapewnianego przez przeglądarkę, spowoduje to usunięcie dowolnego zebranego `cookie`, `localStorage`, czy `sessionStorage`. Należy o tym pamiętać przy projektowaniu pod kątem trwałości lokalnej, zwłaszcza w porównaniu z alternatywami, takimi jak przechowywanie po stronie serwera w bazie danych lub podobnym (które oczywiście będzie się utrzymywać pomimo działań użytkownika)._
|
||||
|
||||
|
|
@ -207,5 +204,6 @@ Tak, Pug (formalnie Jade), ERB, Slim, Handlebars, Jinja, Liquid, żeby wymienić
|
|||
- https://neal.codes/blog/front-end-interview-questions-html/
|
||||
- http://peterdoes.it/2015/12/03/a-personal-exercise-front-end-job-interview-questions-and-my-answers-all/
|
||||
|
||||
___________________________
|
||||
---
|
||||
|
||||
Stworzone przez @[yangshun](https://github.com/yangshun) polska wersja od @[mbiesiad](https://github.com/mbiesiad)
|
||||
|
|
|
|||
|
|
@ -104,26 +104,26 @@ To jest bardzo częste pytanie dotyczące rozmowy rekrutacyjnej w JavaScript. Ws
|
|||
Mamy już wbudowane `Object.create`, ale gdybyś dostarczył dla niego polyfill, mogłoby to wyglądać:
|
||||
|
||||
```javascript
|
||||
if (typeof Object.create !== "function") {
|
||||
Object.create = function(parent) {
|
||||
if (typeof Object.create !== 'function') {
|
||||
Object.create = function (parent) {
|
||||
function Tmp() {}
|
||||
Tmp.prototype = parent;
|
||||
return new Tmp();
|
||||
};
|
||||
}
|
||||
|
||||
const Parent = function() {
|
||||
this.name = "Parent";
|
||||
const Parent = function () {
|
||||
this.name = 'Parent';
|
||||
};
|
||||
|
||||
Parent.prototype.greet = function() {
|
||||
console.log("hello from Parent");
|
||||
Parent.prototype.greet = function () {
|
||||
console.log('hello from Parent');
|
||||
};
|
||||
|
||||
const child = Object.create(Parent.prototype);
|
||||
|
||||
child.cry = function() {
|
||||
console.log("waaaaaahhhh!");
|
||||
child.cry = function () {
|
||||
console.log('waaaaaahhhh!');
|
||||
};
|
||||
|
||||
child.cry();
|
||||
|
|
@ -156,7 +156,7 @@ child.constructor.name
|
|||
```javascript
|
||||
function Child() {
|
||||
Parent.call(this);
|
||||
this.name = "child";
|
||||
this.name = 'child';
|
||||
}
|
||||
|
||||
Child.prototype = Parent.prototype;
|
||||
|
|
@ -205,7 +205,7 @@ IIFE oznacza Immediately Invoked Function Expressions. Parser JavaScript czyta `
|
|||
|
||||
Oto dwa sposoby rozwiązania tego problemu, polegające na dodaniu większej liczby nawiasów: `(function foo(){ })()` oraz `(function foo(){ }())`. Deklaracje zaczynające się od `function` są uważane za _deklaracji funkcji_; poprzez zawinięcie tej funkcji wewnątrz `()`, staje się _wyrażeniem funkcji_ które mogą być następnie wykonane z kolejnym `()`. Funkcje te nie są ujawniane w zakresie globalnym i można nawet pominąć jego nazwę, jeśli nie trzeba odwoływać się do ciała.
|
||||
|
||||
Możesz także użyć operatora `void`: `void function foo(){ }();`. Niestety istnieje jeden problem związany z takim podejściem. Ocena danego wyrażenia jest zawsze `undefined`, więc jeśli funkcja IIFE zwraca cokolwiek, nie możesz jej użyć. Przykład:
|
||||
Możesz także użyć operatora `void`: `void function foo(){ }();`. Niestety istnieje jeden problem związany z takim podejściem. Ocena danego wyrażenia jest zawsze `undefined`, więc jeśli funkcja IIFE zwraca cokolwiek, nie możesz jej użyć. Przykład:
|
||||
|
||||
```
|
||||
// Don't add JS syntax to this code block to prevent Prettier from formatting it.
|
||||
|
|
@ -240,7 +240,7 @@ Zmienna `undefined` jest zmienną, która została zadeklarowana, ale nie ma prz
|
|||
var foo;
|
||||
console.log(foo); // undefined
|
||||
console.log(foo === undefined); // true
|
||||
console.log(typeof foo === "undefined"); // true
|
||||
console.log(typeof foo === 'undefined'); // true
|
||||
|
||||
console.log(foo == null); // true. Wrong, don't use this to check!
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ Zmienna która jest `null` zostanie wyraźnie przypisana do wartości `null`. Ni
|
|||
```js
|
||||
var foo = null;
|
||||
console.log(foo === null); // true
|
||||
console.log(typeof foo === "object"); // true
|
||||
console.log(typeof foo === 'object'); // true
|
||||
|
||||
console.log(foo == undefined); // true. Wrong, don't use this to check!
|
||||
```
|
||||
|
|
@ -310,7 +310,7 @@ const doubled = a.forEach((num, index) => {
|
|||
|
||||
```js
|
||||
const a = [1, 2, 3];
|
||||
const doubled = a.map(num => {
|
||||
const doubled = a.map((num) => {
|
||||
return num * 2;
|
||||
});
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ Główna różnica między `.forEach` i `.map()` to to, że `.map()` zwraca now
|
|||
Można ich użyć w IIFE do enkapsulacji części kodu w zakresie lokalnym, tak aby zmienne zadeklarowane w nim nie przenikały do zakresu globalnego.
|
||||
|
||||
```js
|
||||
(function() {
|
||||
(function () {
|
||||
// Some code here.
|
||||
})();
|
||||
```
|
||||
|
|
@ -338,8 +338,8 @@ Można ich użyć w IIFE do enkapsulacji części kodu w zakresie lokalnym, tak
|
|||
Jako callback, które jest używane raz i nie musi być używane nigdzie indziej. Kod będzie wydawał się bardziej samodzielny i czytelny, gdy procedury obsługi zostaną zdefiniowane bezpośrednio w kodzie wywołującym je, zamiast konieczności szukania gdzie indziej w celu znalezienia w ciele funkcji.
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
console.log("Hello world!");
|
||||
setTimeout(function () {
|
||||
console.log('Hello world!');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ Argumenty do konstrukcji funkcjonalnego programowania lub Lodasha (podobne do ca
|
|||
|
||||
```js
|
||||
const arr = [1, 2, 3];
|
||||
const double = arr.map(function(el) {
|
||||
const double = arr.map(function (el) {
|
||||
return el * 2;
|
||||
});
|
||||
console.log(double); // [2, 4, 6]
|
||||
|
|
@ -395,11 +395,11 @@ function Person(name) {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
var person = Person("John");
|
||||
var person = Person('John');
|
||||
console.log(person); // undefined
|
||||
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
||||
|
||||
var person = new Person("John");
|
||||
var person = new Person('John');
|
||||
console.log(person); // Person { name: "John" }
|
||||
console.log(person.name); // "john"
|
||||
```
|
||||
|
|
@ -459,7 +459,7 @@ Istnieje kilka odpowiedzi online, które wyjaśniają, że w kodzie analitycznym
|
|||
Wykrywanie funkcji polega na sprawdzeniu, czy przeglądarka obsługuje określony blok kodu, i uruchomieniu innego kodu w zależności od tego, czy to robi (czy nie), tak aby przeglądarka zawsze zapewniała działanie w przypadku awarii/błędów w niektórych przeglądarkach. Na przykład:
|
||||
|
||||
```js
|
||||
if ("geolocation" in navigator) {
|
||||
if ('geolocation' in navigator) {
|
||||
// Can use navigator.geolocation
|
||||
} else {
|
||||
// Handle lack of feature
|
||||
|
|
@ -543,7 +543,7 @@ JSONP działa poprzez wysłanie żądania do domeny cross-origin za pomocą znac
|
|||
|
||||
```js
|
||||
// File loaded from https://example.com?callback=printData
|
||||
printData({ name: "Yang Shun" });
|
||||
printData({name: 'Yang Shun'});
|
||||
```
|
||||
|
||||
Klient musi mieć funkcję `printData` w swoim globalnym zasięgu, a funkcja zostanie wykonana przez klienta po otrzymaniu odpowiedzi z domeny cross-origin.
|
||||
|
|
@ -589,15 +589,15 @@ W deklaracjach funkcji podnoszone jest ciało, podczas gdy w wyrażeniach funkcj
|
|||
console.log(foo); // [Function: foo]
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
console.log(foo); // [Function: foo]
|
||||
|
||||
// Function Expression
|
||||
console.log(bar); // undefined
|
||||
bar(); // Uncaught TypeError: bar is not a function
|
||||
var bar = function() {
|
||||
console.log("BARRRR");
|
||||
var bar = function () {
|
||||
console.log('BARRRR');
|
||||
};
|
||||
console.log(bar); // [Function: bar]
|
||||
```
|
||||
|
|
@ -608,8 +608,8 @@ Windowane są również zmienne zadeklarowane za pomocą `let` i `const`. Jednak
|
|||
x; // undefined
|
||||
y; // Reference error: y is not defined
|
||||
|
||||
var x = "local";
|
||||
let y = "local";
|
||||
var x = 'local';
|
||||
let y = 'local';
|
||||
```
|
||||
|
||||
###### Bibliografia
|
||||
|
|
@ -630,15 +630,15 @@ Kiedy zdarzenie zostanie wyzwolone na elemencie DOM, spróbuje obsłużyć to zd
|
|||
Atrybuty są zdefiniowane w znacznikach HTML, ale właściwości są zdefiniowane w DOM. Aby zilustrować różnicę, wyobraź sobie, że mamy to pole tekstowe w naszym HTML: `<input type="text" value="Hello">`.
|
||||
|
||||
```js
|
||||
const input = document.querySelector("input");
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
const input = document.querySelector('input');
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello
|
||||
```
|
||||
|
||||
Ale po zmianie wartości pola tekstowego przez dodanie "World!" staje się to:
|
||||
|
||||
```js
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -678,11 +678,11 @@ Zdarzenie `DOMContentLoaded` jest uruchamiane, gdy początkowy dokument HTML zos
|
|||
`==` jest abstrakcyjnym operatorem równości, podczas gdy `===` jest operatorem ścisłej równości. Operator `==` porówna pod kątem równości po wykonaniu niezbędnych konwersji typu. Operator `===` nie dokona konwersji typu, więc jeśli dwie wartości nie są tego samego typu, `===` po prostu zwróci `false`. Gdy używasz `==`, mogą się zdarzyć dziwne rzeczy, takie jak:
|
||||
|
||||
```js
|
||||
1 == "1"; // true
|
||||
1 == '1'; // true
|
||||
1 == [1]; // true
|
||||
1 == true; // true
|
||||
0 == ""; // true
|
||||
0 == "0"; // true
|
||||
0 == ''; // true
|
||||
0 == '0'; // true
|
||||
0 == false; // true
|
||||
```
|
||||
|
||||
|
|
@ -727,7 +727,7 @@ duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
|||
Lub z ES6:
|
||||
|
||||
```js
|
||||
const duplicate = arr => [...arr, ...arr];
|
||||
const duplicate = (arr) => [...arr, ...arr];
|
||||
|
||||
duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
||||
```
|
||||
|
|
@ -781,7 +781,7 @@ Sprawdź tę wersję FizzBuzz od [Paul Irish](https://gist.github.com/jaysonrowe
|
|||
for (let i = 1; i <= 100; i++) {
|
||||
let f = i % 3 == 0,
|
||||
b = i % 5 == 0;
|
||||
console.log(f ? (b ? "FizzBuzz" : "Fizz") : b ? "Buzz" : i);
|
||||
console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -862,11 +862,11 @@ Niektóre wspólne polyfills są `$.deferred`, Q oraz Bluebird ale nie wszystkie
|
|||
- Ułatwia pisanie sekwencyjnego kodu asynchronicznego, który można odczytać za pomocą `.then()`.
|
||||
- Ułatwia pisanie równoległego kodu asynchronicznego za pomocą `Promise.all()`.
|
||||
- W przypadku obietnic te scenariusze występujące w kodowaniu callbacks-only nie wystąpią:
|
||||
- wywołanie callback za wcześnie
|
||||
- wywołanie callback za późno (lub nigdy)
|
||||
- wywołanie callback za mało lub zbyt wiele razy
|
||||
- nieprzekazanie niezbędnego środowiska/parametrów
|
||||
- Połknięcie ewentualnych błędów/wyjątków
|
||||
- wywołanie callback za wcześnie
|
||||
- wywołanie callback za późno (lub nigdy)
|
||||
- wywołanie callback za mało lub zbyt wiele razy
|
||||
- nieprzekazanie niezbędnego środowiska/parametrów
|
||||
- Połknięcie ewentualnych błędów/wyjątków
|
||||
|
||||
**Wady**
|
||||
|
||||
|
|
@ -977,10 +977,10 @@ Oto kilka sposobów dodania / symulacji niezmienności prostych obiektów JavaSc
|
|||
|
||||
```js
|
||||
let myObject = {};
|
||||
Object.defineProperty(myObject, "number", {
|
||||
Object.defineProperty(myObject, 'number', {
|
||||
value: 42,
|
||||
writable: false,
|
||||
configurable: false
|
||||
configurable: false,
|
||||
});
|
||||
console.log(myObject.number); // 42
|
||||
myObject.number = 43;
|
||||
|
|
@ -1059,9 +1059,9 @@ const arr = [1, 2, 3];
|
|||
const newArr = [...arr, 4]; // [1, 2, 3, 4]
|
||||
|
||||
// Object Example
|
||||
const human = Object.freeze({ race: "human" });
|
||||
const john = { ...human, name: "John" }; // {race: "human", name: "John"}
|
||||
const alienJohn = { ...john, race: "alien" }; // {race: "alien", name: "John"}
|
||||
const human = Object.freeze({race: 'human'});
|
||||
const john = {...human, name: 'John'}; // {race: "human", name: "John"}
|
||||
const alienJohn = {...john, race: 'alien'}; // {race: "alien", name: "John"}
|
||||
```
|
||||
|
||||
###### Bibliografia
|
||||
|
|
@ -1102,7 +1102,7 @@ Pierwsza jest deklaracją funkcji, a druga jest wyrażeniem funkcji. Kluczową r
|
|||
```js
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -1110,8 +1110,8 @@ function foo() {
|
|||
|
||||
```js
|
||||
foo(); // Uncaught TypeError: foo is not a function
|
||||
var foo = function() {
|
||||
console.log("FOOOOO");
|
||||
var foo = function () {
|
||||
console.log('FOOOOO');
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -1128,9 +1128,9 @@ Zmienne zadeklarowane przy użyciu słowa kluczowego `var` mają zasięg do funk
|
|||
```js
|
||||
function foo() {
|
||||
// All variables are accessible within functions.
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
|
||||
console.log(bar); // bar
|
||||
console.log(baz); // baz
|
||||
|
|
@ -1144,9 +1144,9 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
|
||||
```js
|
||||
if (true) {
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
}
|
||||
|
||||
// var declared variables are accessible anywhere in the function scope.
|
||||
|
|
@ -1161,38 +1161,38 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
```js
|
||||
console.log(foo); // undefined
|
||||
|
||||
var foo = "foo";
|
||||
var foo = 'foo';
|
||||
|
||||
console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization
|
||||
|
||||
let baz = "baz";
|
||||
let baz = 'baz';
|
||||
|
||||
console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization
|
||||
|
||||
const bar = "bar";
|
||||
const bar = 'bar';
|
||||
```
|
||||
|
||||
Ponowne zadeklarowanie zmiennej za pomocą `var` nie spowoduje błędu, ale 'let' oraz 'const', tak.
|
||||
|
||||
```js
|
||||
var foo = "foo";
|
||||
var foo = "bar";
|
||||
var foo = 'foo';
|
||||
var foo = 'bar';
|
||||
console.log(foo); // "bar"
|
||||
|
||||
let baz = "baz";
|
||||
let baz = "qux"; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
let baz = 'baz';
|
||||
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
```
|
||||
|
||||
`let` i `const` różnią się tym, że `let` pozwala na ponowne przypisanie wartości zmiennej, podczas gdy `const` nie.
|
||||
|
||||
```js
|
||||
// This is fine.
|
||||
let foo = "foo";
|
||||
foo = "bar";
|
||||
let foo = 'foo';
|
||||
foo = 'bar';
|
||||
|
||||
// This causes an exception.
|
||||
const baz = "baz";
|
||||
baz = "qux";
|
||||
const baz = 'baz';
|
||||
baz = 'qux';
|
||||
```
|
||||
|
||||
###### Bibliografia
|
||||
|
|
@ -1267,9 +1267,9 @@ Jedną oczywistą zaletą funkcji strzałek jest uproszczenie składni potrzebne
|
|||
Główną zaletą używania funkcji strzałkowej jako metody w konstruktorze jest to, że wartość `this` jest ustawiana w momencie tworzenia funkcji i nie może się później zmienić. Tak więc, gdy konstruktor jest używany do utworzenia nowego obiektu, `this` zawsze będzie odnosić się do tego obiektu. Na przykład, powiedzmy, że mamy konstruktor `Person`, który bierze imię jako argument i ma dwie metody `console.log` o tej nazwie, jedną jako funkcję zwykłą, a drugą jako funkcję strzałkową:
|
||||
|
||||
```js
|
||||
const Person = function(firstName) {
|
||||
const Person = function (firstName) {
|
||||
this.firstName = firstName;
|
||||
this.sayName1 = function() {
|
||||
this.sayName1 = function () {
|
||||
console.log(this.firstName);
|
||||
};
|
||||
this.sayName2 = () => {
|
||||
|
|
@ -1277,8 +1277,8 @@ const Person = function(firstName) {
|
|||
};
|
||||
};
|
||||
|
||||
const john = new Person("John");
|
||||
const dave = new Person("Dave");
|
||||
const john = new Person('John');
|
||||
const dave = new Person('Dave');
|
||||
|
||||
john.sayName1(); // John
|
||||
john.sayName2(); // John
|
||||
|
|
@ -1320,13 +1320,13 @@ Funkcja wyższego rzędu to dowolna funkcja, która przyjmuje jedną lub więcej
|
|||
Powiedzmy, że mamy tablicę nazw, których potrzebujemy do przekształcenia każdego stringa na wielkie litery.
|
||||
|
||||
```js
|
||||
const names = ["irish", "daisy", "anna"];
|
||||
const names = ['irish', 'daisy', 'anna'];
|
||||
```
|
||||
|
||||
Imperatywnym sposobem będzie tak:
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
const transformNamesToUppercase = function (names) {
|
||||
const results = [];
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
results.push(names[i].toUpperCase());
|
||||
|
|
@ -1339,8 +1339,8 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
Użycie `.map(transformerFn)`sprawia, że kod jest krótszy i bardziej deklaratywny.
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
return names.map(name => name.toUpperCase());
|
||||
const transformNamesToUppercase = function (names) {
|
||||
return names.map((name) => name.toUpperCase());
|
||||
};
|
||||
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
||||
```
|
||||
|
|
@ -1361,7 +1361,7 @@ Destrukturyzacja to wyrażenie dostępne w ES6, które umożliwia zwięzły i wy
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const foo = ["one", "two", "three"];
|
||||
const foo = ['one', 'two', 'three'];
|
||||
|
||||
const [one, two, three] = foo;
|
||||
console.log(one); // "one"
|
||||
|
|
@ -1383,8 +1383,8 @@ console.log(b); // 1
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const o = { p: 42, q: true };
|
||||
const { p, q } = o;
|
||||
const o = {p: 42, q: true};
|
||||
const {p, q} = o;
|
||||
|
||||
console.log(p); // 42
|
||||
console.log(q); // true
|
||||
|
|
@ -1402,9 +1402,9 @@ console.log(q); // true
|
|||
Literały szablonów ułatwiają interpolację stringów lub uwzględnianie zmiennych w stringach. Przed ES2015 było coś takiego:
|
||||
|
||||
```js
|
||||
var person = { name: "Tyler", age: 28 };
|
||||
var person = {name: 'Tyler', age: 28};
|
||||
console.log(
|
||||
"Hi, my name is " + person.name + " and I am " + person.age + " years old!"
|
||||
'Hi, my name is ' + person.name + ' and I am ' + person.age + ' years old!',
|
||||
);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1412,7 +1412,7 @@ console.log(
|
|||
With template literals, you can now create that same output like this instead:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1422,7 +1422,7 @@ Zauważ, że używasz odwrotnych znaków, a nie cudzysłowów, aby wskazać, że
|
|||
Drugim pomocnym przypadkiem użycia jest tworzenie ciągów wieloliniowych. Przed ES2015 można było utworzyć ciąg wielu wierszy, taki jak ten:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\nThis is line two.");
|
||||
console.log('This is line one.\nThis is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1430,7 +1430,7 @@ console.log("This is line one.\nThis is line two.");
|
|||
Lub jeśli chcesz podzielić go na wiele wierszy w kodzie, abyś nie musiał przewijać w edytorze tekstu w prawo, aby odczytać długi ciąg, możesz również napisać w następujący sposób:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\n" + "This is line two.");
|
||||
console.log('This is line one.\n' + 'This is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1447,7 +1447,7 @@ This is line two.`);
|
|||
Innym przykładem użycia literałów szablonów byłoby użycie jako zamiennika bibliotek szablonów dla prostych interpolacji zmiennych:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
document.body.innerHTML = `
|
||||
<div>
|
||||
<p>Name: ${person.name}</p>
|
||||
|
|
@ -1475,7 +1475,7 @@ function curry(fn) {
|
|||
}
|
||||
|
||||
function _curried(depth, args) {
|
||||
return function(newArgument) {
|
||||
return function (newArgument) {
|
||||
if (depth - 1 === 0) {
|
||||
return fn(...args, newArgument);
|
||||
}
|
||||
|
|
@ -1508,35 +1508,35 @@ Spread syntax z ES6 jest bardzo przydatna podczas kodowania w funkcjonalnym para
|
|||
|
||||
```js
|
||||
function putDookieInAnyArray(arr) {
|
||||
return [...arr, "dookie"];
|
||||
return [...arr, 'dookie'];
|
||||
}
|
||||
|
||||
const result = putDookieInAnyArray(["I", "really", "don't", "like"]); // ["I", "really", "don't", "like", "dookie"]
|
||||
const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"]
|
||||
|
||||
const person = {
|
||||
name: "Todd",
|
||||
age: 29
|
||||
name: 'Todd',
|
||||
age: 29,
|
||||
};
|
||||
|
||||
const copyOfTodd = { ...person };
|
||||
const copyOfTodd = {...person};
|
||||
```
|
||||
|
||||
Rest syntax z ES6 oferuje skrót do włączenia dowolnej liczby argumentów, które należy przekazać do funkcji. To jest jak odwrotność spread syntax, biorąc dane i upychając je do tablicy, zamiast rozpakowywać tablicę danych, i działa w argumentach funkcyjnych, a także w przypisaniach destrukturyzacji tablicy i obiektów.
|
||||
|
||||
```js
|
||||
function addFiveToABunchOfNumbers(...numbers) {
|
||||
return numbers.map(x => x + 5);
|
||||
return numbers.map((x) => x + 5);
|
||||
}
|
||||
|
||||
const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15]
|
||||
|
||||
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
|
||||
|
||||
const { e, f, ...others } = {
|
||||
const {e, f, ...others} = {
|
||||
e: 1,
|
||||
f: 2,
|
||||
g: 3,
|
||||
h: 4
|
||||
h: 4,
|
||||
}; // e: 1, f: 2, others: { g: 3, h: 4 }
|
||||
```
|
||||
|
||||
|
|
@ -1580,5 +1580,6 @@ Statyczne elementy klasy (właściwości / metody) nie są powiązane z konkretn
|
|||
|
||||
- http://flowerszhong.github.io/2013/11/20/javascript-questions.html
|
||||
|
||||
___________________________
|
||||
---
|
||||
|
||||
Stworzone przez @[yangshun](https://github.com/yangshun) polska wersja od @[mbiesiad](https://github.com/mbiesiad)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="https://cdn.rawgit.com/yangshun/front-end-interview-handbook/23d89c8/assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Creditos: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Ilustração</a> por <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## O que é isto?
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ Moral da história - apenas adiciona `<!DOCTYPE html>` no início da sua página
|
|||
|
||||
A questão é um pouco vaga, eu vou assumir que está a perguntar sobre o caso mais comum, que é como servir uma página com conteúdo disponível em vários idiomas, mas o conteúdo dentro da página deve ser exibido somente num idioma consistente.
|
||||
|
||||
Quando uma solicitação HTTP é feita para um servidor, o agente de utilizador pedido geralmente envia informações sobre as preferências de idioma, como no cabeçalho `Aceitar-Idioma'. O servidor pode então usar estas informações para retornar uma versão do documento no idioma apropriado, caso tal alternativa esteja disponível. O documento HTML retornado também deve declarar o atributo`lang`na marca`<html> `, como`<html lang="en">...</html>`.
|
||||
Quando uma solicitação HTTP é feita para um servidor, o agente de utilizador pedido geralmente envia informações sobre as preferências de idioma, como no cabeçalho `Aceitar-Idioma`. O servidor pode então usar estas informações para retornar uma versão do documento no idioma apropriado, caso tal alternativa esteja disponível. O documento HTML retornado também deve declarar o atributo`lang`na marca`<html>`, como`<html lang="en">...</html>`.
|
||||
|
||||
Na parte de trás, a marcação HTML irá conter espaços reservados `i18n` e conteúdo para o idioma específico armazenado nos formatos YML ou JSON. O servidor, em seguida, gera dinamicamente a página HTML com conteúdo nesse idioma específico, geralmente com a ajuda de uma estrutura de back-end.
|
||||
|
||||
|
|
@ -93,15 +93,15 @@ Atualmente, o uso dos atributos `data-` não é encorajado. Uma das razões é q
|
|||
|
||||
Todas as tecnologias acima mencionadas são mecanismos de armazenamento de valor-chave do lado do cliente. Eles só conseguem armazenar valores como strings.
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| ----------------------------------------------- | --------------------------------------------------------------------- | --------------- | ---------------- |
|
||||
| Iniciador | Cliente ou servidor. Pode usar cabeçalho `Set-Cookie` | Cliente | Cliente |
|
||||
| Expira | Definir manualmente | Para sempre | Na aba fechar |
|
||||
| Persiste em todas sessões do navegador | Depende de se o tempo de validade está configurado | Sim | Não |
|
||||
| Tem um domínio associado | Sim | Não | Não |
|
||||
| Enviado para servidor com cada solicitação HTTP | Os cookies são automaticamente enviados através do cabeçalho `Cookie` | Não | Não |
|
||||
| Capacidade (por domínio) | 4kb | 5MB | 5MB |
|
||||
| Acessibilidade | Qualquer janela | Qualquer janela | A mesma aba |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| Iniciador | Cliente ou servidor. Pode usar cabeçalho `Set-Cookie` | Cliente | Cliente |
|
||||
| Expira | Definir manualmente | Para sempre | Na aba fechar |
|
||||
| Persiste em todas sessões do navegador | Depende de se o tempo de validade está configurado | Sim | Não |
|
||||
| Tem um domínio associado | Sim | Não | Não |
|
||||
| Enviado para servidor com cada solicitação HTTP | Os cookies são automaticamente enviados através do cabeçalho `Cookie` | Não | Não |
|
||||
| Capacidade (por domínio) | 4kb | 5MB | 5MB |
|
||||
| Acessibilidade | Qualquer janela | Qualquer janela | A mesma aba |
|
||||
|
||||
###### Referências
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ Todas as tecnologias acima mencionadas são mecanismos de armazenamento de valor
|
|||
- `<script>` - A análise HTML é bloqueada, o script é executado e executado imediatamente, a análise HTML é retomada após o script ser executado.
|
||||
- `<script async>` - O script será procurado em paralelo com a análise HTML e executado assim que estiver disponível (potencialmente antes da análise HTML). Usa `async` quando o script for independente de qualquer outro script na página, por exemplo, analítica.
|
||||
|
||||
* `<script defer>` - O script será procurado em paralelo com a análise de HTML e executado quando a página terminar de analisar. Se houver vários deles, cada script diferido é executado na ordem em que foram encontrados no documento. Se um script depende de um DOM totalmente analisado, o atributo ` defer`` será útil para garantir que o HTML seja totalmente analisado antes de o executar. Não há muita diferença em colocar um `<script>`normal no final de`<body>`. Um script diferido não deve conter`document.write`.
|
||||
* `<script defer>` - O script será procurado em paralelo com a análise de HTML e executado quando a página terminar de analisar. Se houver vários deles, cada script diferido é executado na ordem em que foram encontrados no documento. Se um script depende de um DOM totalmente analisado, o atributo `defer` será útil para garantir que o HTML seja totalmente analisado antes de o executar. Não há muita diferença em colocar um `<script>`normal no final de`<body>`. Um script diferido não deve conter`document.write`.
|
||||
|
||||
Nota: Os atributos `async` e` defer`` são ignorados para scripts que não possuem atributo `src`.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="../../assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Автор иллюстрации:</a> <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Что это такое?
|
||||
|
|
@ -23,7 +18,7 @@
|
|||
|
||||
<div align="center">
|
||||
<img src="../../assets/web-tech.svg" alt="Web Technologies illustration" width="400"/>
|
||||
<br>
|
||||
<br/>
|
||||
<p>
|
||||
<em>Автор иллюстрации: <a href="https://undraw.co/">unDraw</a></em>
|
||||
</p>
|
||||
|
|
@ -62,7 +57,7 @@
|
|||
|
||||
Много часов упорной работы было потрачено на этот проект. Буду признателен за вашу поддержку!
|
||||
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
||||
<a href="https://www.buymeacoffee.com/yangshun" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;"/>></a>
|
||||
|
||||
## Лицензия
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,11 @@
|
|||
|
||||
### Для чего нужен DOCTYPE?
|
||||
|
||||
**DOCTYPE** — это сокращение от **DOCument TYPE** (тип документа).
|
||||
DOCTYPE всегда связан с **DTD** — **Document Type Definition** (определение типа документа).
|
||||
**DOCTYPE** — это сокращение от **DOCument TYPE** (тип документа). DOCTYPE всегда связан с **DTD** — **Document Type Definition** (определение типа документа).
|
||||
|
||||
DTD определяет как должны быть структурированы документы определенного типа (т.е. тег `button` может содержать в себе тег `span`, но не `div`), в то время как DOCTYPE объявляет, к какому DTD _предположительно_ относится документ.
|
||||
|
||||
Для веб-страниц объявление DOCTYPE необходимо. Он используется для того, чтобы сообщить пользовательскому агенту, к какой версии спецификаций HTML принадлежит ваш документ.
|
||||
Как только пользовательский агент распознал правильный DOCTYPE, он запустит режим **no-quirks**, соответствующий этому DOCTYPE, для чтения документа.
|
||||
Если пользовательский агент не распознает правильный DOCTYPE, он активирует режим **quirks**.
|
||||
Для веб-страниц объявление DOCTYPE необходимо. Он используется для того, чтобы сообщить пользовательскому агенту, к какой версии спецификаций HTML принадлежит ваш документ. Как только пользовательский агент распознал правильный DOCTYPE, он запустит режим **no-quirks**, соответствующий этому DOCTYPE, для чтения документа. Если пользовательский агент не распознает правильный DOCTYPE, он активирует режим **quirks**.
|
||||
|
||||
DOCTYPE для стандарта HTML5 определяется как `<!DOCTYPE html>`.
|
||||
|
||||
|
|
@ -100,14 +97,14 @@ DOCTYPE для стандарта HTML5 определяется как `<!DOCTY
|
|||
|
||||
Все вышеупомянутые технологии являются механизмами хранения типа ключ-значение на клиентской стороне. Они могут хранить данные только как строки.
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| ----------------------------------------- | ------------------------------------------------------------------- | -------------- | ------------------- |
|
||||
| Инициатор | Клиент или сервер. Сервер может использовать заголовок `Set-Cookie` | Клиент | Клиент |
|
||||
| Срок хранения | Устанавливается вручную | Всегда | До закрытия вкладки |
|
||||
| Хранение между сессиями | Зависит от установки срока хранения | Да | Нет |
|
||||
| Отправка на сервер с каждым HTTP-запросом | автоматически, с помощью заголовка `Cookie` | Нет | Нет |
|
||||
| Емкость (на один домен) | 4 КБ | 5 МБ | 5 МБ |
|
||||
| Доступность | В любом окне | В любом окне | В той же вкладке |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| Инициатор | Клиент или сервер. Сервер может использовать заголовок `Set-Cookie` | Клиент | Клиент |
|
||||
| Срок хранения | Устанавливается вручную | Всегда | До закрытия вкладки |
|
||||
| Хранение между сессиями | Зависит от установки срока хранения | Да | Нет |
|
||||
| Отправка на сервер с каждым HTTP-запросом | автоматически, с помощью заголовка `Cookie` | Нет | Нет |
|
||||
| Емкость (на один домен) | 4 КБ | 5 МБ | 5 МБ |
|
||||
| Доступность | В любом окне | В любом окне | В той же вкладке |
|
||||
|
||||
###### Ссылки
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ console.log(x); // 1
|
|||
var foo;
|
||||
console.log(foo); // undefined
|
||||
console.log(foo === undefined); // true
|
||||
console.log(typeof foo === "undefined"); // true
|
||||
console.log(typeof foo === 'undefined'); // true
|
||||
|
||||
console.log(foo == null); // true. Неправильно, не используйте это для проверки!
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ console.log(baz); // undefined
|
|||
```js
|
||||
var foo = null;
|
||||
console.log(foo === null); // true
|
||||
console.log(typeof foo === "object"); // true
|
||||
console.log(typeof foo === 'object'); // true
|
||||
|
||||
console.log(foo == undefined); // true. Неправильно, не используйте это для проверки!
|
||||
```
|
||||
|
|
@ -256,7 +256,7 @@ const doubled = a.map((num) => {
|
|||
|
||||
```js
|
||||
setTimeout(function () {
|
||||
console.log("Hello world!");
|
||||
console.log('Hello world!');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
|
@ -312,11 +312,11 @@ function Person(name) {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
var person = Person("John");
|
||||
var person = Person('John');
|
||||
console.log(person); // undefined
|
||||
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
||||
|
||||
var person = new Person("John");
|
||||
var person = new Person('John');
|
||||
console.log(person); // Person { name: "John" }
|
||||
console.log(person.name); // "john"
|
||||
```
|
||||
|
|
@ -376,7 +376,7 @@ console.log(add.apply(null, [1, 2])); // 3
|
|||
Определение возможностей браузера заключается в определении, поддерживает ли браузер определенный блок кода - и если нет, то будет выполняться другой код, так что браузер всегда сможет обеспечить работоспособность и предотвратить сбои/ошибки в некоторых браузерах. Например:
|
||||
|
||||
```js
|
||||
if ("geolocation" in navigator) {
|
||||
if ('geolocation' in navigator) {
|
||||
// Можно использовать navigator.geolocation
|
||||
} else {
|
||||
// Обработка отсутствия возможности
|
||||
|
|
@ -459,7 +459,7 @@ JSONP работает, отправляя запрос к серверу в д
|
|||
|
||||
```js
|
||||
// Файл загружен с https://example.com?callback=printData
|
||||
printData({ name: "Yang Shun" });
|
||||
printData({name: 'Yang Shun'});
|
||||
```
|
||||
|
||||
У клиента должна быть функция `printData` в своей глобальной области видимости, и эта функция будет выполнена клиентом, когда будет получен ответ с сервера из другого домена.
|
||||
|
|
@ -511,7 +511,7 @@ console.log(bar); // 2
|
|||
console.log(foo); // [Function: foo]
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
console.log(foo); // [Function: foo]
|
||||
|
||||
|
|
@ -519,7 +519,7 @@ console.log(foo); // [Function: foo]
|
|||
console.log(bar); // undefined
|
||||
bar(); // Uncaught TypeError: bar is not a function
|
||||
var bar = function () {
|
||||
console.log("BARRRR");
|
||||
console.log('BARRRR');
|
||||
};
|
||||
console.log(bar); // [Function: bar]
|
||||
```
|
||||
|
|
@ -537,15 +537,15 @@ console.log(bar); // [Function: bar]
|
|||
Атрибуты определены в разметке HTML, а свойства определены в DOM. Чтобы проиллюстрировать разницу, представьте, что у нас есть это текстовое поле в HTML: `<input type="text" value="Hello">`.
|
||||
|
||||
```js
|
||||
const input = document.querySelector("input");
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
const input = document.querySelector('input');
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello
|
||||
```
|
||||
|
||||
Но после того, как вы измените значение текстового поля, добавив к нему "World!", будет:
|
||||
|
||||
```js
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -585,11 +585,11 @@ console.log(input.value); // Hello World!
|
|||
`==` - это оператор абстрактного сравнения, а `===` - оператор строгого сравнения. Оператор `==` будет сравнивать на равенство после выполнения любых необходимых преобразований типов. Оператор `===` не будет выполнять преобразование типов, поэтому, если два значения не одного типа, `===` просто вернет `false`. При использовании `==` могут происходить такие странные вещи, как:
|
||||
|
||||
```js
|
||||
1 == "1"; // true
|
||||
1 == '1'; // true
|
||||
1 == [1]; // true
|
||||
1 == true; // true
|
||||
0 == ""; // true
|
||||
0 == "0"; // true
|
||||
0 == ''; // true
|
||||
0 == '0'; // true
|
||||
0 == false; // true
|
||||
```
|
||||
|
||||
|
|
@ -680,7 +680,7 @@ duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
|
|||
for (let i = 1; i <= 100; i++) {
|
||||
let f = i % 3 == 0,
|
||||
b = i % 5 == 0;
|
||||
console.log(f ? (b ? "FizzBuzz" : "Fizz") : b ? "Buzz" : i);
|
||||
console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -894,7 +894,7 @@ for (let [index, elem] of arr.entries()) {
|
|||
```js
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -903,7 +903,7 @@ function foo() {
|
|||
```js
|
||||
foo(); // Uncaught TypeError: foo is not a function
|
||||
var foo = function () {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -920,9 +920,9 @@ var foo = function () {
|
|||
```js
|
||||
function foo() {
|
||||
// Все переменные доступны внутри функции.
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
|
||||
console.log(bar); // bar
|
||||
console.log(baz); // baz
|
||||
|
|
@ -936,9 +936,9 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
|
||||
```js
|
||||
if (true) {
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
}
|
||||
|
||||
// переменные, объявленные при помощи var, доступны в любом месте функции.
|
||||
|
|
@ -953,38 +953,38 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
```js
|
||||
console.log(foo); // undefined
|
||||
|
||||
var foo = "foo";
|
||||
var foo = 'foo';
|
||||
|
||||
console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization
|
||||
|
||||
let baz = "baz";
|
||||
let baz = 'baz';
|
||||
|
||||
console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization
|
||||
|
||||
const bar = "bar";
|
||||
const bar = 'bar';
|
||||
```
|
||||
|
||||
Переопределение переменной с помощью `var` не вызовет ошибку, в отличие от `let` и `const`.
|
||||
|
||||
```js
|
||||
var foo = "foo";
|
||||
var foo = "bar";
|
||||
var foo = 'foo';
|
||||
var foo = 'bar';
|
||||
console.log(foo); // "bar"
|
||||
|
||||
let baz = "baz";
|
||||
let baz = "qux"; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
let baz = 'baz';
|
||||
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
```
|
||||
|
||||
`let` отличается от `const` тем, что изменять значение `const` нельзя.
|
||||
|
||||
```js
|
||||
// Это нормально.
|
||||
let foo = "foo";
|
||||
foo = "bar";
|
||||
let foo = 'foo';
|
||||
foo = 'bar';
|
||||
|
||||
// Это вызывает исключение.
|
||||
const baz = "baz";
|
||||
baz = "qux";
|
||||
const baz = 'baz';
|
||||
baz = 'qux';
|
||||
```
|
||||
|
||||
###### Ссылки
|
||||
|
|
@ -1069,8 +1069,8 @@ const Person = function (firstName) {
|
|||
};
|
||||
};
|
||||
|
||||
const john = new Person("John");
|
||||
const dave = new Person("Dave");
|
||||
const john = new Person('John');
|
||||
const dave = new Person('Dave');
|
||||
|
||||
john.sayName1(); // John
|
||||
john.sayName2(); // John
|
||||
|
|
@ -1112,7 +1112,7 @@ sayNameFromWindow2(); // John
|
|||
Допустим, у нас есть массив с именами, которые нам нужны о преобразовать в верхний регистр.
|
||||
|
||||
```js
|
||||
const names = ["irish", "daisy", "anna"];
|
||||
const names = ['irish', 'daisy', 'anna'];
|
||||
```
|
||||
|
||||
Императивное решение будет выглядеть так:
|
||||
|
|
@ -1153,7 +1153,7 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
|
||||
```js
|
||||
// Присваивание переменной
|
||||
const foo = ["one", "two", "three"];
|
||||
const foo = ['one', 'two', 'three'];
|
||||
|
||||
const [one, two, three] = foo;
|
||||
console.log(one); // "one"
|
||||
|
|
@ -1175,8 +1175,8 @@ console.log(b); // 1
|
|||
|
||||
```js
|
||||
// Присваивание переменной
|
||||
const o = { p: 42, q: true };
|
||||
const { p, q } = o;
|
||||
const o = {p: 42, q: true};
|
||||
const {p, q} = o;
|
||||
|
||||
console.log(p); // 42
|
||||
console.log(q); // true
|
||||
|
|
@ -1194,9 +1194,9 @@ console.log(q); // true
|
|||
Шаблонные строки помогают упростить строковую строк или включение переменных в строку. До ES2015 писали так:
|
||||
|
||||
```js
|
||||
var person = { name: "Tyler", age: 28 };
|
||||
var person = {name: 'Tyler', age: 28};
|
||||
console.log(
|
||||
"Hi, my name is " + person.name + " and I am " + person.age + " years old!"
|
||||
'Hi, my name is ' + person.name + ' and I am ' + person.age + ' years old!',
|
||||
);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1204,7 +1204,7 @@ console.log(
|
|||
С приходом шаблонных строк в ES6 стало намного проще:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
||||
// 'Hi, my name is Tyler and I am 28 years old!'
|
||||
```
|
||||
|
|
@ -1214,7 +1214,7 @@ console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
|
|||
Второй пример использования заключается в создании многострочных литералов. До ES2015 перенос осуществлялся следующим образом:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\nThis is line two.");
|
||||
console.log('This is line one.\nThis is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1222,7 +1222,7 @@ console.log("This is line one.\nThis is line two.");
|
|||
Или же, чтобы не приходилось прокручивать длинную строку в текстовом редакторе, можно было разбить код на несколько строк в коде, таким образом:
|
||||
|
||||
```js
|
||||
console.log("This is line one.\n" + "This is line two.");
|
||||
console.log('This is line one.\n' + 'This is line two.');
|
||||
// This is line one.
|
||||
// This is line two.
|
||||
```
|
||||
|
|
@ -1239,7 +1239,7 @@ This is line two.`);
|
|||
Еще одним вариантом использования шаблонных строк будет использование в качестве замены библиотек шаблонизации для интерполяции переменных:
|
||||
|
||||
```js
|
||||
const person = { name: "Tyler", age: 28 };
|
||||
const person = {name: 'Tyler', age: 28};
|
||||
document.body.innerHTML = `
|
||||
<div>
|
||||
<p>Name: ${person.name}</p>
|
||||
|
|
@ -1300,17 +1300,17 @@ Spread оператор синтаксиса ES6 очень полезен пр
|
|||
|
||||
```js
|
||||
function putDookieInAnyArray(arr) {
|
||||
return [...arr, "dookie"];
|
||||
return [...arr, 'dookie'];
|
||||
}
|
||||
|
||||
const result = putDookieInAnyArray(["I", "really", "don't", "like"]); // ["I", "really", "don't", "like", "dookie"]
|
||||
const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"]
|
||||
|
||||
const person = {
|
||||
name: "Todd",
|
||||
name: 'Todd',
|
||||
age: 29,
|
||||
};
|
||||
|
||||
const copyOfTodd = { ...person };
|
||||
const copyOfTodd = {...person};
|
||||
```
|
||||
|
||||
В свою очередь, rest оператор синтаксиса ES6 позволяет в сокращенном виде указывать неопределенное количество аргументов, передаваемых в функцию. Можно сказать, что он противоположен spread оператору: собирает данные и добавляет их в массив, вместо разделения массива данных. Он используется в аргументах функций, а также при деструктуризации массивов и объектов.
|
||||
|
|
@ -1324,7 +1324,7 @@ const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12
|
|||
|
||||
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
|
||||
|
||||
const { e, f, ...others } = {
|
||||
const {e, f, ...others} = {
|
||||
e: 1,
|
||||
f: 2,
|
||||
g: 3,
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
## Sa Pag-aambag
|
||||
|
||||
Sa pag-aambag sa imbakang ito, kung ito ay isang di-maliit na pagbabago, pakiusap ay talakayin muna ang pagbabago na nais mong gawin Sa pamamagitan ng paggawa ng isyu sa imbakang ito.
|
||||
|
||||
Hangga't maari, subukan na sundin ang umiiral na format ng markdown at code. Ang JavaScript na code ay dapat pagtibayan ng [Standard style](https://standardjs.com/).
|
||||
|
||||
Paalala lang na meron tayong Code of Conduct, mangyaring sundin ito sa lahat ng iyong mga pakikipag-ugnayan sa proyekto.
|
||||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="https://cdn.rawgit.com/yangshun/front-end-interview-handbook/23d89c8/assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>Kredito: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">Ilustrasyon</a> ni <a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Ano ito?
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ Ang `.clearfix` na hack ay gumagamit ng isang wais na CSS pseudo na selector na
|
|||
|
||||
```css
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
content: ' ';
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
|
|
@ -117,8 +117,7 @@ Ang bawat kontekstong nakasalansan ay nakatimpi - matapos ang mga nilalaman ng e
|
|||
|
||||
### Ilarawan ang BFK (Block Formatting na Konteksto) at papaaano ito gumagana.
|
||||
|
||||
Ang Block Formatting na Konteksto (BFK) ay parte ng biswal na pagrender ng css ng isang pahina ng web na kung saan ang mga bloke na kahon ay inilatag. Ang mga floats, ganap na mga nakaposisyon na mga elemento, `inline-blocks`, `table-cells`, mga `table-caption`, at mga elemento na may `overflow` maliban sa `visible` (maliban kung ang halaga na ito ay pinalaganap sa viewport) na magtatag ng mga bagong konteksto sa pag-format ng bloke
|
||||
.
|
||||
Ang Block Formatting na Konteksto (BFK) ay parte ng biswal na pagrender ng css ng isang pahina ng web na kung saan ang mga bloke na kahon ay inilatag. Ang mga floats, ganap na mga nakaposisyon na mga elemento, `inline-blocks`, `table-cells`, mga `table-caption`, at mga elemento na may `overflow` maliban sa `visible` (maliban kung ang halaga na ito ay pinalaganap sa viewport) na magtatag ng mga bagong konteksto sa pag-format ng bloke .
|
||||
|
||||
Ang BFK ay isang HTML na kahon na natutugunan ng hindi bababa sa isa sa mga sumusunod na kondisyon:
|
||||
|
||||
|
|
@ -127,8 +126,7 @@ Ang BFK ay isang HTML na kahon na natutugunan ng hindi bababa sa isa sa mga sumu
|
|||
- Ang halaga ng `display` ay `table-cell`, `table-caption`, `inline-block`, `flex`, o `inline-flex`.
|
||||
- Ang halaga ng `overflow` ay hindi `visible`.
|
||||
|
||||
Sa isang BFK, hinawakan ang kaliwang panlabas na gilid ng bawat kahon ang kaliwang gilid ng bloke na naglalaman
|
||||
(for right-to-left formatting, right edges touch).
|
||||
Sa isang BFK, hinawakan ang kaliwang panlabas na gilid ng bawat kahon ang kaliwang gilid ng bloke na naglalaman (for right-to-left formatting, right edges touch).
|
||||
|
||||
Ang mga bertikal na margin sa pagitan ng mga katabing kahon ng block-level sa isang pagbagsak ng BFK. Magpasa pa sa [Mga margin na bumabagsak](https://www.sitepoint.com/web-foundations/collapsing-margins/).
|
||||
|
||||
|
|
@ -318,8 +316,7 @@ Halimbawa ay sa tagapiling `p span` na ito, unang hahanapin ng mga browser ang l
|
|||
|
||||
Ang CSS pseudo-element ay isang keyword na dinadagdag sa tagapili na nagbibigay-daan sa iyo ng pag-eestilo ng isang tiyak na bahagi ng piniling elemento(s). Maaari silang magamit para sa dekorasyon (`:first-line`, `:first-letter`) o pagdaragdag ng mga elemento sa markup (kasama ng `content: ...`) na hindi na kailangang baguhin pa ang markup (`:before`, `:after`).
|
||||
|
||||
- `:first-line` at `:first-letter` ay magagamit para lagyan ng dekorasyon ang teksto.
|
||||
\*Ginamit sa `.clearfix` na hack na ipinakita sa itaas upang magdagdag ng zero-space na elemento kasabay ang `clear: both`.
|
||||
- `:first-line` at `:first-letter` ay magagamit para lagyan ng dekorasyon ang teksto. \*Ginamit sa `.clearfix` na hack na ipinakita sa itaas upang magdagdag ng zero-space na elemento kasabay ang `clear: both`.
|
||||
- Mala-tatsulok na mga arrow sa tooltips ay gumagamit ng `:before` at `:after`. Hinihikayat ang paghihiwalay ng mga alalahanin dahil ang tatsulok ay itinuturing na bahagi ng estilo at hindi talaga ang DOM. Hindi talaga posible na gumuhit ng isang tatsulok na may mga estilo lamang ng CSS nang hindi gumagamit ng karagdagang elemento ng HTML.
|
||||
|
||||
###### RMga Reperensiya
|
||||
|
|
@ -374,14 +371,14 @@ TODO
|
|||
|
||||
Ako ay magbibigay ng isang paghahambing sa `block` para sa mahusay na panukalang.
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Sukat | Pinupunan ang lapad ng lalagyan ng magulang nito. | Nakadepende sa nilalaman. | Depende sa nilalaman |
|
||||
| Pagpoposisyon | Magsimula sa isang bagong linya at hindi papayagan ang mga elemento ng HTML sa tabi nito (maliban nalang kapag nagdadagdag ka ng `float`) | Sumasabay kasama ang iba pang nilalaman at nagbibigay-daan sa iba pang mga elemento sa tabi nito. | Sumasabay kasama ang iba pang nilalaman at nagbibigay-daan sa iba pang mga elemento sa tabi nito. |
|
||||
| Maaaring tukuyin ang `lapad` at`taas` | Oo | Oo | Hindi. Huwag pansinin kung itinakda. |
|
||||
| Maaaring nakahanay sa `vertical-align` | Hindi | Oo | Oo |
|
||||
| Mga margin at paddings | Iginagalang ang lahat ng panig. | Iginagalang ang lahat ng panig. | Iginagalang lamang ang mga pahalang na panig. Ang mga bertikal na gilid, kung tinukoy, ito ay hindi nakakaapekto sa layout. Ang bertikal na puwang na kinukuha ay depende sa `line-height`, kahit na ang`border` at `padding` ay mukhang biswal na nakikita sa paligid ng nilalaman. |
|
||||
| Float | - | - | Nagiging katulad ng isang elemento ng 'block' kung saan maaari kang magtakda ng mga bertikal na margin at paddings. |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| Sukat | Pinupunan ang lapad ng lalagyan ng magulang nito. | Nakadepende sa nilalaman. | Depende sa nilalaman |
|
||||
| Pagpoposisyon | Magsimula sa isang bagong linya at hindi papayagan ang mga elemento ng HTML sa tabi nito (maliban nalang kapag nagdadagdag ka ng `float`) | Sumasabay kasama ang iba pang nilalaman at nagbibigay-daan sa iba pang mga elemento sa tabi nito. | Sumasabay kasama ang iba pang nilalaman at nagbibigay-daan sa iba pang mga elemento sa tabi nito. |
|
||||
| Maaaring tukuyin ang `lapad` at`taas` | Oo | Oo | Hindi. Huwag pansinin kung itinakda. |
|
||||
| Maaaring nakahanay sa `vertical-align` | Hindi | Oo | Oo |
|
||||
| Mga margin at paddings | Iginagalang ang lahat ng panig. | Iginagalang ang lahat ng panig. | Iginagalang lamang ang mga pahalang na panig. Ang mga bertikal na gilid, kung tinukoy, ito ay hindi nakakaapekto sa layout. Ang bertikal na puwang na kinukuha ay depende sa `line-height`, kahit na ang`border` at `padding` ay mukhang biswal na nakikita sa paligid ng nilalaman. |
|
||||
| Float | - | - | Nagiging katulad ng isang elemento ng 'block' kung saan maaari kang magtakda ng mga bertikal na margin at paddings. |
|
||||
|
||||
[[↑] Bumalik sa taas](#mga-katanungan-sa-css)
|
||||
|
||||
|
|
|
|||
|
|
@ -93,14 +93,14 @@ These days, using `data-` attributes is not encouraged. One reason is that users
|
|||
|
||||
Ang lahat ng nabanggit na mga teknolohiya ay ang mahahalagang mekanismo ng imbakan sa parte ng kliyente. Ang mga ito ay maaari lamang mag-imbak ng mga halaga bilang mga string.
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| ----------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------- | ---------------- |
|
||||
| Tagasimula | Kliyente o serber. Ang serber ay pwedeng gumamit ng `Set-Cookie` na header | Kliyente | Kliyente |
|
||||
| Pag-expire | Mano-manong pag-set | Habang buhay | Nasa tab malapit |
|
||||
| Patuloy sa lahat ng mga sesyon ng browser | Depende sa kung ang panahon nng pag-expire ay itinakda | Oo | Hindi |
|
||||
| Ipinadala sa server sa bawat kahilingan ng HTTP | Ang mga cookies ay awtomatikong ipinadala sa pamamagitan ng `Cookie`na header | Hindi | Hindi |
|
||||
| Kapasidad (kada domain) | 4kb | 5MB | 5MB |
|
||||
| kayang i-aakses | Kahit na anong bintana | Kahit na anong bintana | Parehong tab |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| Tagasimula | Kliyente o serber. Ang serber ay pwedeng gumamit ng `Set-Cookie` na header | Kliyente | Kliyente |
|
||||
| Pag-expire | Mano-manong pag-set | Habang buhay | Nasa tab malapit |
|
||||
| Patuloy sa lahat ng mga sesyon ng browser | Depende sa kung ang panahon nng pag-expire ay itinakda | Oo | Hindi |
|
||||
| Ipinadala sa server sa bawat kahilingan ng HTTP | Ang mga cookies ay awtomatikong ipinadala sa pamamagitan ng `Cookie`na header | Hindi | Hindi |
|
||||
| Kapasidad (kada domain) | 4kb | 5MB | 5MB |
|
||||
| kayang i-aakses | Kahit na anong bintana | Kahit na anong bintana | Parehong tab |
|
||||
|
||||
###### Mga Reperensiya
|
||||
|
||||
|
|
@ -170,8 +170,7 @@ TODO
|
|||
|
||||
### Nakagamit ka na ba ng ibang lenggwahe sa pag-template ng HTML?
|
||||
|
||||
Oo, Pug (dating Jade), ERB, Slim, Handlebars, Jinja, Liquid, upang pangalanan lamang ang ilan. Sa palagay ko, ang mga ito ay higit pa o mas mababa na parehong nagbibigay ng katulad na pag-andar ng nilalamang tumatakas at kapaki-pakinabang na mga pag-sala para sa pagmamanipula ng datos na ipapakita. Ang karamihan sa mga engine sa pag-template ay magpapahintulot din sa iyo na mag-inject ng iyong sariling mga pag-sala sa kaganapan na kailangan mo ng pasadyang pagproseso bago ipakita.
|
||||
[[↑] Bumalik sa taas](#mga-tanong-sa-html)
|
||||
Oo, Pug (dating Jade), ERB, Slim, Handlebars, Jinja, Liquid, upang pangalanan lamang ang ilan. Sa palagay ko, ang mga ito ay higit pa o mas mababa na parehong nagbibigay ng katulad na pag-andar ng nilalamang tumatakas at kapaki-pakinabang na mga pag-sala para sa pagmamanipula ng datos na ipapakita. Ang karamihan sa mga engine sa pag-template ay magpapahintulot din sa iyo na mag-inject ng iyong sariling mga pag-sala sa kaganapan na kailangan mo ng pasadyang pagproseso bago ipakita. [[↑] Bumalik sa taas](#mga-tanong-sa-html)
|
||||
|
||||
### Mga Ibang Sagot
|
||||
|
||||
|
|
|
|||
|
|
@ -108,8 +108,7 @@ Ang dalawa ay parehong mga paraan upang ipatupad ang isang sistema ng module, na
|
|||
|
||||
Nakikita ko ang sintaks ng AMD na parang masyadong malubha at ang CommonJS ay mas malapit sa estilo na nais mong ng pagsulat ng mga pahayag ng pag-import sa iba pang mga wika. halos kada, nakikita kong hindi kailangang AMD, dahil kung napagsilbihan mo ang lahat ng iyong JavaScript sa isang pinagdugtong na bugkos na, hindi ka makikinabang mula sa mga propyedad ng pag-load sa paraang async. Gayundin, ang sintaks ng CommonJS ay mas malapit sa estilo ng Node ng pagsusulat ng mga module at mayroong mas kaunting konteksto na lumilipat sa itaas kapag lumipat sa pagitan ng panig sa kliyente at panig sa serber na pag-develop ng JavaScript.
|
||||
|
||||
Natutuwa ako na may mga ES2015 na module, na may suporta para sa parehong kasabay at di sinkronisado na paglo-load, maaari na sa wakas na tayo ay mananatili lamang sa isang diskarte. Kahit na hindi ito ganap na pinagsama sa mga browser at sa Node, maaari tayong gumamit lagi ng mga transpiler upang i-convert ang ating code.
|
||||
.
|
||||
Natutuwa ako na may mga ES2015 na module, na may suporta para sa parehong kasabay at di sinkronisado na paglo-load, maaari na sa wakas na tayo ay mananatili lamang sa isang diskarte. Kahit na hindi ito ganap na pinagsama sa mga browser at sa Node, maaari tayong gumamit lagi ng mga transpiler upang i-convert ang ating code. .
|
||||
|
||||
###### Mga Reperensiya
|
||||
|
||||
|
|
@ -149,7 +148,7 @@ Ang isang variable na `undefined` ay isang variable na ipinahayag na, ngunit hin
|
|||
var foo;
|
||||
console.log(foo); // undefined
|
||||
console.log(foo === undefined); // true
|
||||
console.log(typeof foo === "undefined"); // true
|
||||
console.log(typeof foo === 'undefined'); // true
|
||||
|
||||
console.log(foo == null); // true. Mali, wag itong gamitin para sumuri!
|
||||
|
||||
|
|
@ -218,7 +217,7 @@ const doubled = a.forEach((num, index) => {
|
|||
|
||||
```js
|
||||
const a = [1, 2, 3];
|
||||
const doubled = a.map(num => {
|
||||
const doubled = a.map((num) => {
|
||||
return num * 2;
|
||||
});
|
||||
|
||||
|
|
@ -238,7 +237,7 @@ Ang pangunahing pagkakaiba sa pagitan ng `.forEach` at `.map ()` ay ang `.map ()
|
|||
Maaari silang gamitin sa mga IIFE upang ipaloob ang ilang mga code sa loob ng isang lokal na saklaw upang ang mga variable na ipinahayag dito ay hindi mag-leak sa pandaigdigang saklaw.
|
||||
|
||||
```js
|
||||
(function() {
|
||||
(function () {
|
||||
// Ibang mga code dito.
|
||||
})();
|
||||
```
|
||||
|
|
@ -246,8 +245,8 @@ Maaari silang gamitin sa mga IIFE upang ipaloob ang ilang mga code sa loob ng is
|
|||
Bilang isang callback na ginagamit minsan at hindi na kailangang magamit kahit saan pa. Ang code ay mukhang mas self-contained at nababasa kapag ang mga handler ay tinukoy sa loob ng code na tinatawag ang mga ito, sa halip na maghanap sa ibang lugar upang mahanap ang punksyon na katawan.
|
||||
|
||||
```js
|
||||
setTimeout(function() {
|
||||
console.log("Hello world!");
|
||||
setTimeout(function () {
|
||||
console.log('Hello world!');
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
|
|
@ -255,7 +254,7 @@ Mga argumento sa mga punksyonal na mga konstruktura na pag-program o Lodash (kat
|
|||
|
||||
```js
|
||||
const arr = [1, 2, 3];
|
||||
const double = arr.map(function(el) {
|
||||
const double = arr.map(function (el) {
|
||||
return el * 2;
|
||||
});
|
||||
console.log(double); // [2, 4, 6]
|
||||
|
|
@ -303,11 +302,11 @@ function Person(name) {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
var person = Person("John");
|
||||
var person = Person('John');
|
||||
console.log(person); // undefined
|
||||
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
||||
|
||||
var person = new Person("John");
|
||||
var person = new Person('John');
|
||||
console.log(person); // Person { name: "John" }
|
||||
console.log(person.name); // "john"
|
||||
```
|
||||
|
|
@ -364,11 +363,10 @@ Mayroong ilang mga sagot na makikita online na nagpapaliwanag na ang `document.w
|
|||
|
||||
**Pagtuklas ng Tampok**
|
||||
|
||||
Ang pagtuklas ng tampok ay kinasasangkutan ng pagtatrabaho kung ang isang browser ay sumusuporta sa isang tiyak na bloke ng code, at nagpapatakbo ng ibang code na nakasalalay sa kung ito (o hindi), upang ang browser ay maaaring makapagbigay kahit kailan ng isang gumaganang karanasan sa halip na mag-crash o magka-error sa ilang mga browser.
|
||||
Halimbawa:
|
||||
Ang pagtuklas ng tampok ay kinasasangkutan ng pagtatrabaho kung ang isang browser ay sumusuporta sa isang tiyak na bloke ng code, at nagpapatakbo ng ibang code na nakasalalay sa kung ito (o hindi), upang ang browser ay maaaring makapagbigay kahit kailan ng isang gumaganang karanasan sa halip na mag-crash o magka-error sa ilang mga browser. Halimbawa:
|
||||
|
||||
```js
|
||||
if ("geolocation" in navigator) {
|
||||
if ('geolocation' in navigator) {
|
||||
// Pwedeng gamitin ang navigator.geolocation
|
||||
} else {
|
||||
// Ang handle ay kulang sa tampok
|
||||
|
|
@ -450,7 +448,7 @@ Gumagana ang JSONP sa pamamagitan ng paggawa ng isang kahilingan sa isang cross-
|
|||
|
||||
```js
|
||||
// Ang file ay naload galing sa https://example.com?callback=printData
|
||||
printData({ name: "Yang Shun" });
|
||||
printData({name: 'Yang Shun'});
|
||||
```
|
||||
|
||||
Ang kliyente ay dapat magkaroon ng punksyon na `printData` sa pandaigdigang saklaw nito at ang punksyon ay isasagawa ng kliyente kapag ang tugon mula sa cross-origin na domain ay natanggap na.
|
||||
|
|
@ -500,15 +498,15 @@ Ang mga deklarasyon ng punksyon ay may na-hoist katawan habang ang mga ekspresyo
|
|||
console.log(foo); // [Function: foo]
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
console.log(foo); // [Function: foo]
|
||||
|
||||
// Ekspresyon ng Punksyon
|
||||
console.log(bar); // undefined
|
||||
bar(); // Uncaught TypeError: ang bar ay hindi isang punksyon
|
||||
var bar = function() {
|
||||
console.log("BARRRR");
|
||||
var bar = function () {
|
||||
console.log('BARRRR');
|
||||
};
|
||||
console.log(bar); // [Function: bar]
|
||||
```
|
||||
|
|
@ -526,15 +524,15 @@ Kapag ang isang kaganapan ay nag-trigger sa isang elemento ng DOM, susubukan nit
|
|||
Ang mga katangian ay tinukoy sa markup ng HTML ngunit ang mga propyedad ay tinukoy sa DOM. Upang ilarawan ang pagkakaiba, isipin na mayroon kaming field na ito sa aming HTML: `<input type ="text"value ="Hello">`.
|
||||
|
||||
```js
|
||||
const input = document.querySelector("input");
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
const input = document.querySelector('input');
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello
|
||||
```
|
||||
|
||||
Ngunit pagkatapos mong baguhin ang halaga ng patlang ng teksto sa pamamagitan ng pagdaragdag ng "World!" dito, ito ay nagiging:
|
||||
|
||||
```js
|
||||
console.log(input.getAttribute("value")); // Hello
|
||||
console.log(input.getAttribute('value')); // Hello
|
||||
console.log(input.value); // Hello World!
|
||||
```
|
||||
|
||||
|
|
@ -572,11 +570,11 @@ Ang `DOMContentLoaded` na kaganapan ay pinapaputok kapag ang unang HTML na dokum
|
|||
Ang `==` ay ang abstraktong pagkakapantay-pantay na operator habang ang `===` ay ang mahigpit na pagkakapantay-pantay na operator. Ang `==` ay ang abstraktong pagkakapantay-pantay na operator habang ang `===` ay ang mahigpit na pagkakapantay-pantay na operator. Ang `== operator ay maghahambing para sa pagkakapantay-pantay matapos gawin ang anumang kinakailangang mga conversion na uri. Ang operator ng`===`ay hindi gagawin ang uri ng conversion, kaya kung ang dalawang halaga ay hindi magkatulad na uri`=== `ay babalik lamang` false`. Kapag gumagamit ng`==`, ang mga funky bagay ay maaaring mangyari, tulad ng: na operator ay maghahambing para sa pagkakapantay-pantay matapos gawin ang anumang kinakailangang mga pagpapalit na uri. Ang operator ng`===`ay hindi gagawin ang uri ng pagpapalit, kaya kung ang dalawang halaga ay hindi magkatulad na uri` === `ay babalik lamang sa`false`. Kapag gumagamit ng`==`, ang mga kaiba-ibang mga bagay ay maaaring mangyari, tulad ng:
|
||||
|
||||
```js
|
||||
1 == "1"; // true
|
||||
1 == '1'; // true
|
||||
1 == [1]; // true
|
||||
1 == true; // true
|
||||
0 == ""; // true
|
||||
0 == "0"; // true
|
||||
0 == ''; // true
|
||||
0 == '0'; // true
|
||||
0 == false; // true
|
||||
```
|
||||
|
||||
|
|
@ -667,7 +665,7 @@ Check out this version of FizzBuzz by [Paul Irish](https://gist.github.com/jayso
|
|||
for (let i = 1; i <= 100; i++) {
|
||||
let f = i % 3 == 0,
|
||||
b = i % 5 == 0;
|
||||
console.log(f ? (b ? "FizzBuzz" : "Fizz") : b ? "Buzz" : i);
|
||||
console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -857,7 +855,7 @@ The former is a function declaration while the latter is a function expression.
|
|||
```js
|
||||
foo(); // 'FOOOOO'
|
||||
function foo() {
|
||||
console.log("FOOOOO");
|
||||
console.log('FOOOOO');
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -865,8 +863,8 @@ function foo() {
|
|||
|
||||
```js
|
||||
foo(); // Uncaught TypeError: foo is not a function
|
||||
var foo = function() {
|
||||
console.log("FOOOOO");
|
||||
var foo = function () {
|
||||
console.log('FOOOOO');
|
||||
};
|
||||
```
|
||||
|
||||
|
|
@ -883,9 +881,9 @@ Variables declared using the `var` keyword are scoped to the function in which t
|
|||
```js
|
||||
function foo() {
|
||||
// All variables are accessible within functions.
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
|
||||
console.log(bar); // bar
|
||||
console.log(baz); // baz
|
||||
|
|
@ -899,9 +897,9 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
|
||||
```js
|
||||
if (true) {
|
||||
var bar = "bar";
|
||||
let baz = "baz";
|
||||
const qux = "qux";
|
||||
var bar = 'bar';
|
||||
let baz = 'baz';
|
||||
const qux = 'qux';
|
||||
}
|
||||
|
||||
// var declared variables are accessible anywhere in the function scope.
|
||||
|
|
@ -916,38 +914,38 @@ console.log(qux); // ReferenceError: qux is not defined
|
|||
```js
|
||||
console.log(foo); // undefined
|
||||
|
||||
var foo = "foo";
|
||||
var foo = 'foo';
|
||||
|
||||
console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization
|
||||
|
||||
let baz = "baz";
|
||||
let baz = 'baz';
|
||||
|
||||
console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization
|
||||
|
||||
const bar = "bar";
|
||||
const bar = 'bar';
|
||||
```
|
||||
|
||||
Redeclaring a variable with `var` will not throw an error, but 'let' and 'const' will.
|
||||
|
||||
```js
|
||||
var foo = "foo";
|
||||
var foo = "bar";
|
||||
var foo = 'foo';
|
||||
var foo = 'bar';
|
||||
console.log(foo); // "bar"
|
||||
|
||||
let baz = "baz";
|
||||
let baz = "qux"; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
let baz = 'baz';
|
||||
let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared
|
||||
```
|
||||
|
||||
`let` and `const` differ in that `let` allows reassigning the variable's value while `const` does not.
|
||||
|
||||
```js
|
||||
// This is fine.
|
||||
let foo = "foo";
|
||||
foo = "bar";
|
||||
let foo = 'foo';
|
||||
foo = 'bar';
|
||||
|
||||
// This causes an exception.
|
||||
const baz = "baz";
|
||||
baz = "qux";
|
||||
const baz = 'baz';
|
||||
baz = 'qux';
|
||||
```
|
||||
|
||||
###### References
|
||||
|
|
@ -985,13 +983,13 @@ A higher-order function is any function that takes one or more functions as argu
|
|||
Let say we have an array of names which we need to transform each string to uppercase.
|
||||
|
||||
```js
|
||||
const names = ["irish", "daisy", "anna"];
|
||||
const names = ['irish', 'daisy', 'anna'];
|
||||
```
|
||||
|
||||
The imperative way will be as such:
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
const transformNamesToUppercase = function (names) {
|
||||
const results = [];
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
results.push(names[i].toUpperCase());
|
||||
|
|
@ -1004,8 +1002,8 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
|||
Use `.map(transformerFn)` makes the code shorter and more declarative.
|
||||
|
||||
```js
|
||||
const transformNamesToUppercase = function(names) {
|
||||
return names.map(name => name.toUpperCase());
|
||||
const transformNamesToUppercase = function (names) {
|
||||
return names.map((name) => name.toUpperCase());
|
||||
};
|
||||
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
|
||||
```
|
||||
|
|
@ -1026,7 +1024,7 @@ Destructuring is an expression available in ES6 which enables a succinct and con
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const foo = ["one", "two", "three"];
|
||||
const foo = ['one', 'two', 'three'];
|
||||
|
||||
const [one, two, three] = foo;
|
||||
console.log(one); // "one"
|
||||
|
|
@ -1048,8 +1046,8 @@ console.log(b); // 1
|
|||
|
||||
```js
|
||||
// Variable assignment.
|
||||
const o = { p: 42, q: true };
|
||||
const { p, q } = o;
|
||||
const o = {p: 42, q: true};
|
||||
const {p, q} = o;
|
||||
|
||||
console.log(p); // 42
|
||||
console.log(q); // true
|
||||
|
|
@ -1079,7 +1077,7 @@ function curry(fn) {
|
|||
}
|
||||
|
||||
function _curried(depth, args) {
|
||||
return function(newArgument) {
|
||||
return function (newArgument) {
|
||||
if (depth - 1 === 0) {
|
||||
return fn(...args, newArgument);
|
||||
}
|
||||
|
|
@ -1112,35 +1110,35 @@ ES6's spread syntax is very useful when coding in a functional paradigm as we ca
|
|||
|
||||
```js
|
||||
function putDookieInAnyArray(arr) {
|
||||
return [...arr, "dookie"];
|
||||
return [...arr, 'dookie'];
|
||||
}
|
||||
|
||||
const result = putDookieInAnyArray(["I", "really", "don't", "like"]); // ["I", "really", "don't", "like", "dookie"]
|
||||
const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"]
|
||||
|
||||
const person = {
|
||||
name: "Todd",
|
||||
age: 29
|
||||
name: 'Todd',
|
||||
age: 29,
|
||||
};
|
||||
|
||||
const copyOfTodd = { ...person };
|
||||
const copyOfTodd = {...person};
|
||||
```
|
||||
|
||||
ES6's rest syntax offers a shorthand for including an arbitrary number of arguments to be passed to a function. It is like an inverse of the spread syntax, taking data and stuffing it into an array rather than unpacking an array of data, and it works in function arguments, as well as in array and object destructuring assignments.
|
||||
|
||||
```js
|
||||
function addFiveToABunchOfNumbers(...numbers) {
|
||||
return numbers.map(x => x + 5);
|
||||
return numbers.map((x) => x + 5);
|
||||
}
|
||||
|
||||
const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15]
|
||||
|
||||
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
|
||||
|
||||
const { e, f, ...others } = {
|
||||
const {e, f, ...others} = {
|
||||
e: 1,
|
||||
f: 2,
|
||||
g: 3,
|
||||
h: 4
|
||||
h: 4,
|
||||
}; // e: 1, f: 2, others: { g: 3, h: 4 }
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
<div align="center">
|
||||
<a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">
|
||||
<img src="https://cdn.rawgit.com/yangshun/front-end-interview-handbook/23d89c8/assets/scroll.svg" alt="Front End Interview Handbook" width="400"/>
|
||||
</a>
|
||||
<br>
|
||||
<p>
|
||||
<em>鸣谢: <a href="https://dribbble.com/shots/4263961-Front-End-Interview-Scroll">插图</a>出自<a href="https://dribbble.com/yangheng">@yangheng</a>
|
||||
</em>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## 这是什么?
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ CSS 的`clear`属性通过使用`left`、`right`、`both`,让该元素向下
|
|||
|
||||
```css
|
||||
.clearfix::after {
|
||||
content: "";
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
|
@ -260,8 +260,7 @@ CSS 中的`z-index`属性控制重叠元素的垂直叠加顺序。`z-index`只
|
|||
|
||||
首先,浏览器从最右边的选择器,即关键选择器(key selector),向左依次匹配。根据关键选择器,浏览器从 DOM 中筛选出元素,然后向上遍历被选元素的父元素,判断是否匹配。选择器匹配语句链越短,浏览器的匹配速度越快。避免使用标签和通用选择器作为关键选择器,因为它们会匹配大量的元素,浏览器必须要进行大量的工作,去判断这些元素的父元素们是否匹配。
|
||||
|
||||
[BEM (Block Element Modifier)](https://bem.info/) methodology recommends that everything has a single class, and, where you need hierarchy, that gets baked into the name of the class as well, this naturally makes the selector efficient and easy to override.
|
||||
[BEM (Block Element Modifier)](https://bem.info/)原则上建议为独立的 CSS 类命名,并且在需要层级关系时,将关系也体现在命名中,这自然会使选择器高效且易于覆盖。
|
||||
[BEM (Block Element Modifier)](https://bem.info/) methodology recommends that everything has a single class, and, where you need hierarchy, that gets baked into the name of the class as well, this naturally makes the selector efficient and easy to override. [BEM (Block Element Modifier)](https://bem.info/)原则上建议为独立的 CSS 类命名,并且在需要层级关系时,将关系也体现在命名中,这自然会使选择器高效且易于覆盖。
|
||||
|
||||
搞清楚哪些 CSS 属性会触发重新布局(reflow)、重绘(repaint)和合成(compositing)。在写样式时,避免触发重新布局的可能。
|
||||
|
||||
|
|
@ -314,7 +313,7 @@ CSS 中的`z-index`属性控制重叠元素的垂直叠加顺序。`z-index`只
|
|||
|
||||
这部分与上面关于编写高效的 CSS 有关。浏览器从最右边的选择器(关键选择器)根据关键选择器,浏览器从 DOM 中筛选出元素,然后向上遍历被选元素的父元素,判断是否匹配。选择器匹配语句链越短,浏览器的匹配速度越快。
|
||||
|
||||
例如,对于形如`p span`的选择器,浏览器首先找到所有`<span>`元素,并遍历它的父元素直到根元素以找到`<p>`元素。对于特定的`<span>`,只要找到一个`<p>`,就知道'<span>`已经匹配并停止继续匹配。
|
||||
例如,对于形如`p span`的选择器,浏览器首先找到所有`<span>`元素,并遍历它的父元素直到根元素以找到`<p>`元素。对于特定的`<span>`,只要找到一个`<p>`,就知道`<span>`已经匹配并停止继续匹配。
|
||||
|
||||
###### 参考
|
||||
|
||||
|
|
@ -382,14 +381,14 @@ TODO
|
|||
|
||||
我把`block`也加入其中,为了获得更好的比较。
|
||||
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| ------------------------------- | ----------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| 大小 | 填充其父容器的宽度。 | 取决于内容。 | 取决于内容。 |
|
||||
| 定位 | 从新的一行开始,并且不允许旁边有 HTML 元素(除非是`float`) | 与其他内容一起流动,并允许旁边有其他元素。 | 与其他内容一起流动,并允许旁边有其他元素。 |
|
||||
| 能否设置`width`和`height` | 能 | 能 | 不能。 设置会被忽略。 |
|
||||
| 可以使用`vertical-align`对齐 | 不可以 | 可以 | 可以 |
|
||||
| 边距(margin)和填充(padding) | 各个方向都存在 | 各个方向都存在 | 只有水平方向存在。垂直方向会被忽略。 尽管`border`和`padding`在`content`周围,但垂直方向上的空间取决于'line-height' |
|
||||
| 浮动(float) | - | - | 就像一个`block`元素,可以设置垂直边距和填充。 |
|
||||
| | `block` | `inline-block` | `inline` |
|
||||
| --- | --- | --- | --- |
|
||||
| 大小 | 填充其父容器的宽度。 | 取决于内容。 | 取决于内容。 |
|
||||
| 定位 | 从新的一行开始,并且不允许旁边有 HTML 元素(除非是`float`) | 与其他内容一起流动,并允许旁边有其他元素。 | 与其他内容一起流动,并允许旁边有其他元素。 |
|
||||
| 能否设置`width`和`height` | 能 | 能 | 不能。 设置会被忽略。 |
|
||||
| 可以使用`vertical-align`对齐 | 不可以 | 可以 | 可以 |
|
||||
| 边距(margin)和填充(padding) | 各个方向都存在 | 各个方向都存在 | 只有水平方向存在。垂直方向会被忽略。 尽管`border`和`padding`在`content`周围,但垂直方向上的空间取决于'line-height' |
|
||||
| 浮动(float) | - | - | 就像一个`block`元素,可以设置垂直边距和填充。 |
|
||||
|
||||
[[↑] 回到顶部](#css-问题)
|
||||
|
||||
|
|
|
|||
|
|
@ -93,14 +93,14 @@
|
|||
|
||||
上面提到的技术名词,都是在客户端以键值对存储的存储机制,并且只能将值存储为字符串。
|
||||
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| -------------------------------------------------- | -------------------------------------------------- | -------------- | ---------------- |
|
||||
| 由谁初始化 | 服务器,服务器可以使用`Set-Cookie`请求头。 | 客户端 | 客户端 |
|
||||
| 过期时间 | 手动设置 | 永不过期 | 当前页面关闭时 |
|
||||
| 在当前浏览器会话(browser sessions)中是否保持不变 | 取决于是否设置了过期时间 | 是 | 否 |
|
||||
| 是否随着每个 HTTP 请求发送给服务器 | 是,Cookies 会通过`Cookie`请求头,自动发送给服务器 | 否 | 否 |
|
||||
| 容量(每个域名) | 4kb | 5MB | 5MB |
|
||||
| 访问权限 | 任意窗口 | 任意窗口 | 当前页面窗口 |
|
||||
| | `cookie` | `localStorage` | `sessionStorage` |
|
||||
| --- | --- | --- | --- |
|
||||
| 由谁初始化 | 服务器,服务器可以使用`Set-Cookie`请求头。 | 客户端 | 客户端 |
|
||||
| 过期时间 | 手动设置 | 永不过期 | 当前页面关闭时 |
|
||||
| 在当前浏览器会话(browser sessions)中是否保持不变 | 取决于是否设置了过期时间 | 是 | 否 |
|
||||
| 是否随着每个 HTTP 请求发送给服务器 | 是,Cookies 会通过`Cookie`请求头,自动发送给服务器 | 否 | 否 |
|
||||
| 容量(每个域名) | 4kb | 5MB | 5MB |
|
||||
| 访问权限 | 任意窗口 | 任意窗口 | 当前页面窗口 |
|
||||
|
||||
###### 参考
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue