前端面试系列-ES6
生活随笔
收集整理的這篇文章主要介紹了
前端面试系列-ES6
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
什么是提升?什么是暫時性死區(qū)?var、let 及 const 區(qū)別?
- 當(dāng)我們在一個作用域使用var聲明一個變量的時候,會首先聲明這個變量在當(dāng)前作用域(undefined)的最上面,然后在進行賦值。
- var 聲明的變量會發(fā)生提升的情況,其實不僅變量會提升函數(shù)也會被提升。并且函數(shù)提升(聲明加定義同時完成)優(yōu)先于變量提升。
- let 和 const 聲明變量,變量并不會被掛載到 window 上。
- 使用let、const聲明變量的時候,會存在暫時性死區(qū) 也就是說聲明之前是無法使用變量的 會報錯。
原型如何實現(xiàn)繼承?Class 如何實現(xiàn)繼承?Class 本質(zhì)是什么?
組合繼承(call+原型繼承)
子類會存在父類的公有屬性和私有屬性。
function Parent(value) {this.val = value}Parent.prototype.getValue = function() {console.log(this.val)}function Child(value) {Parent.call(this, value)}Child.prototype = new Parent()const child = new Child(1)child.getValue() // 1child instanceof Parent // true 復(fù)制代碼寄生組合式繼承
父類的原型賦值給了子類,并且將構(gòu)造函數(shù)設(shè)置為子類,這樣既解決了無用的父類屬性問題,還能正確的找到子類的構(gòu)造函數(shù)
function Parent(value) {this.val = value}Parent.prototype.getValue = function() {console.log(this.val)}function Child(value) {Parent.call(this, value)}Child.prototype = Object.create(Parent.prototype, {constructor: {value: Child,enumerable: false,writable: true,configurable: true}})const child = new Child(1)child.getValue() // 1child instanceof Parent // true 復(fù)制代碼class 繼承(class的本質(zhì)就是函數(shù))
class 實現(xiàn)繼承的核心在于使用 extends 表明繼承自哪個父類,并且在子類構(gòu)造函數(shù)中必須調(diào)用 super(super相當(dāng)于調(diào)用父類的構(gòu)造函數(shù))
class Parent {constructor(value) {this.val = value}getValue() {console.log(this.val)}}class Child extends Parent {constructor(value) {super(value)this.val = value}}let child = new Child(1)child.getValue() // 1child instanceof Parent // true 復(fù)制代碼為什么要使用模塊化?都有哪幾種方式可以實現(xiàn)模塊化,各有什么特點?
模塊化的好處
- 解決命名沖突
- 提供復(fù)用性
- 提高代碼可維護性
立即執(zhí)行函數(shù)
(function(globalVariable){globalVariable.test = function() {}// ... 聲明各種變量、函數(shù)都不會污染全局作用域})(globalVariable) 復(fù)制代碼AMD(requireJs)和CMD(seaJs)
// AMD 依賴前置define(['./a', './b'], function(a, b) {// 加載模塊完畢可以使用a.do()b.do()})// CMD 依賴就近define(function(require, exports, module) {// 加載模塊// 可以把 require 寫在函數(shù)體的任意地方實現(xiàn)延遲加載var a = require('./a')a.doSomething()}) 復(fù)制代碼CommonJs(modele.exports require)
exports = module.exports ,并且require默認(rèn)導(dǎo)出的是module.exports,所以對兩者賦值要特別小心。
// a.jsmodule.exports = {a:1}// b.jslet module = require('./a.js')module.a // 1 復(fù)制代碼ES Module
- CommonJS 支持動態(tài)導(dǎo)入,也就是 require(${path}/xx.js),后者目前不支持,但是已有提案
- CommonJS 是同步導(dǎo)入,因為用于服務(wù)端,文件都在本地,同步導(dǎo)入即使卡住主線程影響也不大。而后者是異步導(dǎo)入,因為用于瀏覽器,需要下載文件,如果也采用同步導(dǎo)入會對渲染有很大影響
- CommonJS 在導(dǎo)出時都是值拷貝,就算導(dǎo)出的值變了,導(dǎo)入的值也不會改變,所以如果想更新值,必須重新導(dǎo)入一次。但是 ES Module 采用實時綁定的方式,導(dǎo)入導(dǎo)出的值都指向同一個內(nèi)存地址,所以導(dǎo)入值會跟隨導(dǎo)出值變化
- ES Module 會編譯成 require/exports 來執(zhí)行的
Proxy 可以實現(xiàn)什么功能?(vue3.0實現(xiàn)響應(yīng)式完全是采用了proxy,而不是原來的Object.defineProperty)
// target 代表需要添加代理的對象,handler 用來自定義對象中的操作let p = new Proxy(target, handler) 復(fù)制代碼 // Proxy 來實現(xiàn)一個數(shù)據(jù)響應(yīng)式let onWatch = (obj, setBind, getLogger) => {let handler = {get(target, property, receiver) {getLogger(target, property)return Reflect.get(target, property, receiver)},set(target, property, value, receiver) {setBind(value, property)return Reflect.set(target, property, value)}}return new Proxy(obj, handler)}let obj = { a: 1 }let p = onWatch(obj,(v, property) => {console.log(`監(jiān)聽到屬性${property}改變?yōu)?span id="ozvdkddzhkzd" class="hljs-variable">${v}`)},(target, property) => {console.log(`'${property}' = ${target[property]}`)})p.a = 2 // 監(jiān)聽到屬性a改變p.a // 'a' = 2 復(fù)制代碼轉(zhuǎn)載于:https://juejin.im/post/5c74006d6fb9a049e232a69a
總結(jié)
以上是生活随笔為你收集整理的前端面试系列-ES6的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于函数的调用是否加括号的问题
- 下一篇: 关于js禁止浏览器缩放