# Frontend Interview
###### tags: `interview`
## Javascript
---
### Prototype
JS does not provide a class implementation, the class keyword is introduced in ES6, but is syntactical sugar, JavaScript remains prototype-based.
In JavaScript, there’s really **no difference between a “regular” function and a constructor function**.
After the ES6 updates, JavaScript allowed for **“prototypal inheritance”, meaning that objects and methods can be shared, extended, and copied.**
So, the inheritance is prototypal inheritance, not classic inheritance.
```
function iPho
```
newPhone.__proto__ is a reference to iPhone.prototype
---
> ### In JS, function is also object, as an object , it has property, one property of it is prototpye, which is also an object
We can use the following way to assign the object with a method, however, JS uses an inheritance model called “differential inheritance”, which means **methods aren’t copied from parent to child**. Instead, **children have an “invisible link” back to their parent object.**
```
function Dog() {
}
Dog.prototype.bark = function() {
console.log(‘woof!’);
};
var fido = new Dog();
fido.bark(); // ‘woof!’
```
When we run```fido.hasOwnProperty(‘bark’) === false```, what happens is:
1. The JS engine looks for a property called bark on our fido object.
2. It doesn’t find one, so it looks “up the prototype chain” to fido’s parent, which is Dog.prototype.
3. It finds Dog.prototype.bark, and calls it with this bound to fido.
**=> There’s no property as fido.bark**
---
* Initialize in class way
```
let Person = class {
constructor(nm, id) {
this.id = id
this.name = nm
}
getDetails() {
return `${this.name}::${this.id}`
}
}
let bob = new Person('Bob', 1)
console.log(bob.getDetails()) // print Bob::1
//Employee prototype links to Person prototype
let Employee = class extends Person {
constructor(nm, id, salary) {
super(nm, id)
this.salary = salary
}
emloyeeInfo() {
return `${this.name}::${this.id}::${this.salary}`
}
}
let coco = new Employee('Coco', 2, 1000)
console.log(coco.employeeInfo()) //print Coco::2::1000
```
* Initialize in functional way
**When ```new``` a function, it means call this function as a constructor**
**```super``` is only used inside constructor of a class**
```
let PersonF = function(nm, id) {
this.name = nm
this.id = id
}
PersonF.prototype.getDetails = function() {
return `${this.name}::${this.id}`
}
let Fred = new PersonF('Fred', 3)
//to do the same extension in function constructor
let EmployeeF = function(nm, id, salary) {
PersonF.call(this, nm, id)
this.salary = salary
}
```
The call() allows for a function/method belonging to one object to be assigned and called for a different object
> ## Explain how prototypal inheritance works.
### Closure
決定函式在 呼叫 時能夠存取的變數範疇
閉包能夠保存當中的能取得之變數,並且要在呼叫時才開始作用
閉包的好處有什麼?優點之一就是能把變數隱藏在裡面讓外部存取不到
### This
要看 this,就看這個函式「怎麽」被呼叫。
this 就是你call 一個函數時,傳入的第一個參數。(請務必背下來「this 就是call 的第一個參數」)
如果你的函數調用形式不是call 形式,請按照「轉換代碼」將其轉換為call 形式。
> ## Explain how this works in JavaScript
> 1. this in a Method
refers to the owner of this method
Ex. this in the fullName function refers to person object
```
var person = {
firstName: "John",
lastName : "Doe",
fullName : function() {
return this.firstName + " " + this.lastName;
}
}
```
> 2. this Alone
the owner is the gloal object, so ```this``` belongs to gloal object (in browser window: [object Window])
In **strict mode**, also refers to global object
> 3. this in a Function
**[deafult]**
the **owner** of the function **is the default binding** for this, so, in a function, this refers to the Global object [object Window]
```
function myFunction() {
return this // return [object Window]
}
```
**[strict mode]**
strict mode does not allow default binding, ```this``` is undefined
```
"use strict"
function myFunction() {
return this // undefined
}
```
> 4. this in Event Handlers
```this``` refers to the HTML element that received the event
```
<button onclick="this.style.display='none'">
Click to Remove Me!
</button>
```
#### Default Binding
4 types of binding ```this```
1. Default Binding
2. Implicit Binding
3. Explicit Binding
4. new binding
> ## Give an example of one of the ways that working with this has changed in ES6?
lexical scope of this, which means where the this is being called does not matter anymore, we only care about where it's defined.
Until arrow functions, every new function defined its own this value
ES5
```
var a = "outer";
function fn() {
return function() {
console.log(this.a);
}
}
var obj = {
a: "inner",
say: fn
}
obj.say()(); // outer
/*************************************/
var a = "outer";
function fn() {
var that = this; // 用一个that来使得this在函数声明时保存下来
return function() {
console.log(that.a);
}
}
var obj = {
a: "inner",
say: fn
}
obj.say()(); // inner
```
ES6
```
var a = "outer";
function fn() {
return () => {
console.log(this.a);
}
}
var obj = {
a: "inner",
say: fn
}
obj.say()(); // inner
```
### Scope
靜態作用域(static scope)(取決於程式語言),代表作用域跟這個 function 在哪裡被「呼叫」一點關係都沒有,靜態作用域是在 function 被「宣告」的時候就決定了,而不是 function 被「執行」的時候。
要看作用域,就看這個函式在程式碼的「哪裡」
lexical scope(static scope) v.s. dynamic scope
| scope | description |
| --------| -------|
| dynamic | search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call-stack. Where this function being **called** matters|
| static | based on where variables and blocks of scope are **declaired** |
### Hoisting
提升變數宣告,賦值不會提升
```
var a
console.log(a) // undefined
a = 5
```
### let, var, const
let 與 const 確實有 hoisting,與 var 的差別在於提升之後,var 宣告的變數會被初始化為 undefined,而 let 與 const 的宣告不會被初始化為 undefined,而且如果你在「賦值之前」就存取它,就會拋出錯誤。
在「提升之後」以及「賦值之前」這段「期間」,如果你存取它就會拋出錯誤,而這段期間就稱做是 TDZ
* var — function scope
* let and const — block scope
the area within if, switch conditions or for and while loops. Generally speaking, whenever you see {curly brackets}, it is a block
* const
使用 const 宣告的物件,其內層屬性依然可以做調整,因為物件是傳參考,所以在此依然可以修改屬性。(一家人的成員依然可以更動)
```
const family = {
mom: '老媽',
me: '小明',
sister: '小橙'
};
family.father = '爸爸';
family = jayFamily // 錯誤
```
### Array Methods
* filter
return an **!!array!!** of elements match with the condition
```
var obj = {
links: [
{name: 'fb', link: 'facebook.com'},
{name: 'twitter', link: 'twitter.com'}
]
}
obj.links.filter( el => el.name === 'fb')[0]['link']
```
* find
return the first element that matches with the condision
```
obj.links.find( el => el.name === 'fb')['link']
```
* reduce
### Promise
### IIFE
### debounce
## HTTP cache
> what is cache?
temporary storage kept on client’s machine to improve the users experience and performance
* difference between cookie?
1. both of them stores data on client’s machine
2. Cookie is used to store information to track different characteristics related to user, while cache is used to make the loading of web pages faster.


* Expires
* Cache-Control, max-age
* Last-Modified 與 If-Modified-Since
解決問題:過期但其實資料不需更新
使用方法:
第一次request時,收到response有Last-Modified,並以此判斷是否過期
如果過期,對server送request,GET包含If-Modified-Since的header,瀏覽器會和server確認在Last-Modified後資料是否更新,若未更新,返回304,否則返回200與新資料
* Etag 與 If-None-Match
解決問題:資料更新但其實內容沒變
使用方法:
第一次request時,收到response帶有etag的header,過期後,在request header上夾帶If-None-Match: etag,跟server確認是不是同一個etag
* Cache-Control: no-store
完全不要快取,用於有機密資料時
* Cache-Control: no-cache
解決問題:希望只要一變動,使用者就能夠馬上看到變化,但又不希望沒有變動時就一直更新
| Status code | data from | meaning |
| -------- | -------- | -------- |
| 200 | memory cache | Text |
| 304 | | Not Modified
ref:
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers
### XSS
* 表單驗證
在mouseout後做驗證
1. input type
2. input required
3. email, phone number -> pattern regular expression
4. security
* 防止XSS
1. HTML Escape Before Inserting Untrusted Data into HTML Element Content
2. JavaScript Escape
## Optimize
1. 靜態資源優化:progrssive image(LQIP), lazy load, Brotli文本壓縮
2. css animation, 少用js
3. cache
4. service worker
5. cdn靜態資源
6. webpack
7. 异步加载 JavaScript
### Lazy-Loaded
intersectionObserver
### Progressive images
* Non-progressive JPEGs: from top to bottom
* Progressive JPEGs: from blur to clear
### polyfill
寫一些程式來填補某些瀏覽器不支援的情況,我們把這些程式稱做 polyfill
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
```
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n ≥ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
if (sameValueZero(o[k], searchElement)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}
```
### CDN
decrease latency, SEO Advantages (google love fast website)
When you deploy a CDN it automatically copies parts of your website, like your images and scripts, and stores them across a bunch of different servers in different data centers around the globe. When people visit your website, it is now loading from different countries, like France, Australia, the USA, etc. It automatically loads from the server that is physically closest to them.
https://cloudinary.com/visualweb/display/IMMC/Image+Manipulation+Techniques
## React
## Browser
### Cookie, Session, LocalStorage
