立刻又到年末了,跳槽的季節。javascript
我又想起來曾經準備面試
的情景, 各類蒐集資料, 整理, 面試, 再整理, 十分的辛苦。前端
其實,不管面試哪家公司, 基礎
都是免不了的.java
以前就有整理一下這些資料的想法,不過本身比較懶, 一隻沒有動手。面試
最近在作公衆號,就想着乾脆搞一搞,把這些基礎知識整理一下,之後本身也能看。segmentfault
恰好國慶在家看了ES6
相關的東西, 這一篇就從ES6
開始吧。微信
var, let, const
這三個東西, 常常會被問到。 模塊化
彙總一下,基本上就是:函數
var, let, const
有什麼區別
?變量提高
(hosting) ?TDZ
?首先, 咱們先總體的看下區別
:學習
針對這幾點, 咱們一個個看。ui
首先, 咱們仍是先了解一下變量提高
.
看個例子:
console.log(a) // undefined var a = 1
這裏咱們能夠看到, 第一行中的a雖然還沒聲明, 可是咱們用起來卻不會報錯。 這種狀況, 就是聲明的提高。
其實也就是:
var a console.log(a) // undefined a = 1
可是, 若是是換成let
, 狀況就不同了:
要理解這個現象, 首先須要搞清楚提高的本質, 理解建立 javascript 變量的三個步驟
:
建立
初始化
賦值
爲了便於理解, 咱們先看看var
的 建立、初始化和賦值
過程:
function foo(){ var x = 1 var y = 2 } foo()
執行foo 時, 會有一些過程(部分過程):
也就是說 va
聲明, 會在代碼執行以前就將 建立變量
,並將其初始化爲 undefined
。
這就解釋了爲何在 var x = 1 以前 console.log(x) 會獲得 undefined
。
接下來看 let 聲明的「建立、初始化和賦值」過程
// ... { let x = 1; x = 2 }
咱們看一下過程:
let
聲明的變量,在環境中建立
這些變量這就解釋了爲何在 let x 以前使用 x 會報錯:
let x = 'global' { console.log(x) // Uncaught ReferenceError: x is not defined let x = 1 }
緣由有兩個
TDZ
, tempory dead zone, 暫時死區)說到這裏, 就都清楚了:
function 也是相似的,並且function 的「建立」「初始化」和「賦值」都被提高了。
這一點, 感興趣的朋友能夠本身實驗一下。
算了, 直接給個例子吧:
<script> bar() function bar(){ console.log(2) } </script>
JS 引擎會有一下過程:
function(){ console.log(2) }
。也就是說 function 聲明會在代碼執行以前就「建立、初始化並賦值」。
這裏作一下簡單的總結:
函數提高優先於變量提高
. 函數提高
會把整個函數挪到做用域頂部
,變量提高
只會把聲明
挪到做用域頂部
。var
存在提高
,咱們能在聲明以前
使用。let
, const
由於存在暫時性死區
,不能在聲明前使用
。var
在全局做用域
下聲明變量, 會致使變量掛載在window
上, 而另外二者不會
。let
和 const
的做用基本一致,可是後者聲明的變量不能再次賦值。這個也是 ES6 裏比較好用的feature, 咱們天天也都會用到。
箭頭函數是 ES6 中新的函數定義形式:
function name(arg1, arg2) {} // 可使用 (arg1, arg2) => {} // 來定義。
箭頭函數, 一方面看起來比較簡潔, 另外一方面, 之解決ES5時代,this
的問題.
看個例子:
function fn() { console.log(this) // {a: 100} ,該做用域下的 this 的真實的值 var arr = [1, 2, 3] // ES5 arr.map(function (item) { console.log(this) // window }) // 箭頭函數 arr.map(item => { console.log(this) // {a: 100} 這裏打印的就是父做用域的 this }) } fn.call({a: 100})
模塊化的好處是十分明顯的:
解決命名衝突
提供複用性
提升代碼可維護性
ES6 以前也有模塊化的方案: AMD, CMD
, 就簡單的提一下, 不是本文討論的主要內容。
// AMD define(['./a', './b'], function(a, b) { a.do() b.do() }) // CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() })
也有一種IIFE
的 形式:
(function(globalVariable){ // 造成一個獨立的做用域,不會污染全局 // ... })(globalVariable)
CommonJS 最先是 Node.js 在使用,目前也仍然普遍使用。
看個例子:
// a.js module.exports = { a: 1 } // b.js var module = require('./a.js') module.a // 1
ES Module 是原生實現的模塊化方案, 提供了一種新的, 能夠文件做爲模塊的開發方式。
使用方式就是咱們常見的:
// a.js export function a() {} export default function() {} //b.js import XXX from './a.js' import { XXX } from './a.js'
若是隻是輸出一個惟一的對象,使用export default便可:
// util1.js export default { a: 100 } // index.js 文件 import obj from './util1.js' console.log(obj) // { a: 100 }
若是想要輸出許多個對象,就不能用 default了,並且 import 時候要加 { ... },代碼以下:
// foo.js export function fn1() { alert('fn1') } export function fn2() { alert('fn2') } // index.js import { fn1, fn2 } from './foo.js' fn1() fn2()
class 其實一直是js的保留字,直到 ES6 才正式用到。
(js中並不存在類,class 只是個語法糖。本質上仍是函數, 其實就是要模擬面向對象的語法, 你懂的)
ES6 的 class 就是取代以前構造函數
初始化對象的形式,從語法
上更加接近面向對象
的寫法。
例如:
// ES5 function MathHandle(x, y) { this.x = x; this.y = y; } MathHandle.prototype.add = function () { return this.x + this.y; }; var method = new MathHandle(1, 2); console.log(method.add())
ES6 class 的寫法:
class MathHandle { constructor(x, y) { this.x = x; this.y = y; } add() { return this.x + this.y; } } const method = new MathHandle(1, 2); console.log(method.add())
注意如下幾點:
class Name {...}
這種形式,和函數的寫法徹底不同.constructor
函數中,constructor
即構造器,初始化實例時默認執行.add() {...}
這種形式,並無function
關鍵字.使用 Class 來實現繼承就更加簡單了,至少比構造函數實現繼承簡單不少:
// 動物 function Animal() { this.eat = function () { console.log('animal eat') } } // 狗 function Dog() { this.bark = function () { console.log('dog bark') } } Dog.prototype = new Animal() var husky = new Dog() husky.bark() // dog bark
ES6 寫法:
class Animal { constructor(name) { this.name = name } eat() { console.log(`${this.name} eat`) } } class Dog extends Animal { constructor(name) { super(name) this.name = name } bark() { console.log(`${this.name} say`) } } const husky = new Dog('哈士奇') husky.bark()
注意如下兩點:
extends
便可實現繼承,更加符合經典面嚮對象語言的語法.constructor
必定要執行super()
,調用父類的constructor
.以上這幾個方面都是面試中常常問的,ES6的內容遠遠不知這些, 好用的特性還有不少, 好比:
...
」 操做符這裏就不一一介紹了。
「 ...
」 操做符 這個能夠參考個人這篇文章:
ES6 面試問的比較多的
大概就是以上這幾點, 可能有所紕漏, 後面再作補充吧。
但願對你們有所幫助。
今天是樓主節後第一天上班, 不在狀態。
說個最尷尬的事情吧, 今天要填2019的績效自評, 其中有一項:
公司在哪些方面能幫助你成長?
原本是一個很正常的問題:
我是這麼寫的:
寫完笑了笑, 跟同事調侃了一下, 可不得加薪嗎。 說完回頭我就直接點了提交。
提交完感受哪裏不大對?
就這麼提交了 ???
臥, 懼怕, 臥, 我幹了什麼
反正也不能改了, 就這樣吧。
文中如有紕漏, 還請各位大佬指正。
若是你以爲內容有幫助能夠關注下個人公衆號 「 前端e進階 」,一塊兒學習成長
能夠經過公衆號菜單欄的聯繫我
, 加入咱們的微信羣
, 一塊兒愉快的玩耍。