JavaScript高级面试题(1)

笔记只是部分摘录

1.课程概述

包括:高级基础,框架原理,app混合开发

技术:JS、ES6、虚拟DOM、vue、React、hybrid

知识点介绍:

JavaScript高级面试题(1)_第1张图片

高级基础:
ES6常用语法:Class、Module、Promise等
原型高级应用:结合jQuery和zepto源码
异步全面讲解:从原理到jQuery再到Promise

框架原理:
虚拟DOM:存在价值,如何使用,diff算法
vue:MVVM,vue响应式,模板解析,渲染
React:组件化,JSX,vdom,setState
对比:有主见,自圆其说

涉及知识点:es6、异步、原型、vdom、mvvm、组件化、hybrid和其他

es6:模块化的使用和编译环境、Class和JS构造函数的区别、Promise的用法、ES6其他常用功能

异步:什么是单线程和异步有何关系、什么是event-loop、目前JS解决异步的方案有哪些、如果只用jQuery如何解决异步、Promise的标准、async/await的使用

原型:原型如何实际应用、原型如何满足扩展

vdom:什么是vdom为何要用vdom、vdom如何使用核心函数有哪些、了解diff算法吗

MVVM:之前使用jQuery和现在使用vue或React框架的区别、你如何理解MVVM、vue如何实现响应式、vue如何解析模板、介绍vue的实现流程

组件化:对组件化的理解、JSX是什么、JSX和vdom什么关系、简述React和setState、简述自己如何比较React和vue

其他:如何写博客、如何做开源

2.ES6

问题

ES6模块化如何使用,开发环境如何打包
Class和普通构造函数有何区别
Promise的基本使用和原理
总结一下ES6其他常用功能

3.ES6模块化

export和import

//export
export default{
	a:100
}

export function fn1(){
	console.log('fn1');
}
export function fn2(){
	console.log('fn2');
}

let myName="laowang";
let myAge=90;
let myfn=function(){
    return "我是"+myName+"!今年"+myAge+"岁了"
}
export {
    myName,
    myAge,
    myfn
}

//import
import util1 from './util1.js'
console.log(util1)

import {fn1,fn2} from './util2.js'
fn1()
fn2()

import {myfn,myAge,myName} from "./test.js";
console.log(myfn());//我是laowang!今年90岁了
console.log(myAge);//90
console.log(myName);//laowang

babel使用

参考之前文章:https://blog.csdn.net/u014465934/article/details/85306244


下面介绍两种方式使用babel:

1.直接使用.babelrc文件和package.json配置babel环境

开发环境:
1.电脑有node环境,运行npm init
2.安装bable中的一些依赖

npm install babel-core babel-present-es2015 babel-preset-latest --save-dev

3.创建.baberrc文件

{
	"presets":["es2015","latest"],
	"plugins":[]
}

4.安装babel-cli

npm install --global babel-cli

5.创建./src/index.js

[1,2,3].map(item => item+1);

6.运行 babel ./src/index.js。

再说明下,我们经常看见到babel src -d lib的意思是把src文件夹下的文件都转译,转译后的文件放到lib目录下。

附注说明:如果你不想生成.babelrc文件,你可以在你的package.json文件中对babel进行配置。

看下面代码:

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "arrow.js",
  "scripts": {
    "build": "babel src -d lib --comments=true"
  },
  "babel":{
    //babel选项
    "presets":["es2015"],
    "comments":false
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-loader": "^7.1.1",
    "babel-preset-env": "^1.6.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^3.2.0"
  }
}​

2.Webpack中使用babel

1.安装Webpack插件

npm install webpack babel-loader --save-dev

2.配置webpack.config.js

3.配置package.json中的scripts

4.运行 npm start

webpack 模块化开发
1.模块化打包,减少网络请求
2.配合 babel,转换 es6 语法
3.配合 less、sass等,对 css 进行预处理
4.可处理、压缩图片
5.代码压缩
6.代码检查
7. 等等

package.json文件主要是描述description信息和配置,webpack.config.js是说明使用方法。

package.json

{
  "name": "es6-webpack",
  "version": "1.0.0",
  "description": "es6 webpack init project",
  "main": "index.js",
  "scripts": {
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/cucygh/es6-webpack.git"
  },
  "author": "",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/cucygh/es6-webpack/issues"
  },
  "eslintConfig": {
    "root": true,
    "parserOptions": {
      "ecmaVersion": 2017
    },
    "extends": [
      "mysticatea",
      "mysticatea/modules"
    ],
    "plugins": [
      "html"
    ],
    "env": {
      "browser": false
    },
    "globals": {
      "applicationCache": false,
      "atob": false,
      "btoa": false,
      "console": false,
      "document": false,
      "location": false,
      "window": false
    },
    "parser": "babel-eslint"
  },
  "eslintIgnore": [
    "node_modules",
    "webpack.config.js"
  ],
  "babel": {
    "presets": [
      "env"
    ]
  },
  "homepage": "https://github.com/cucygh/es6-webpack#readme",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.0.3",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "clean-webpack-plugin": "^0.1.17",
    "eslint": "^3.19.0",
    "eslint-plugin-babel": "^4.1.2",
    "eslint-plugin-html": "^4.0.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "html-loader": "^0.5.1",
    "html-webpack-plugin": "^2.30.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.9.5"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0",
    "eslint-config-mysticatea": "^12.0.0"
  }
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
  entry: ['babel-polyfill','./index.js'],
  devServer: {
    contentBase: './dist',
    hot: true,
    compress: true,
    port: 9000,
    clientLogLevel: "none",
    quiet: true
  },
  module: {
    loaders: [
      {
        test: /\.html$/,
        loader: 'html-loader'
      }, {
        test: /\.js$/,
        loader: 'babel-loader'
      }]
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({template: './index.html'}),
      new webpack.NamedModulesPlugin(),
      new webpack.HotModuleReplacementPlugin()
    ],
    output: {
      filename: 'index.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

总结:

关于babel的知识点大概就这些。
1.babel常用的转译器是babel-preset-env。
2.常用的配置选项是plugins和presets
3.常用的使用场景是在webpack中

babel配置一般所需要的依赖:
babel-loader、babel-core、babel-preset-env、babel-polyfill、babel-runtime和babel-plugin-transform-runtime

babel-loader:在import或加载模块时,对es6代码进行预处理,es6语法转化为es5语法。
babel-core:允许我们去调用babel的api,可以将js代码分析成ast(抽象语法树),方便各个插件分析语法进行相应的处理.
babel-preset-env:指定规范,比如es2015,es2016,es2017,latest,env(包含前面全部)
babel-polyfill:它效仿一个完整的ES2015+环境,使得我们能够使用新的内置对象比如 Promise,静态方法比如Array.from 或者 Object.assign, 实例方法比如 Array.prototype.includes 和生成器函数(提供给你使用 regenerator 插件)。为了达到这一点, polyfill 添加到了全局范围,就像原生类型比如 String 一样。
babel-runtime babel-plugin-transform-runtime:与babel-polyfill作用一样,使用场景不一样。

Webpack4配置参考文章:http://www.imooc.com/article/287156

关于babel更多参考:

https://zhuanlan.zhihu.com/p/43249121
https://www.kancloud.cn/digest/babel/217112
https://juejin.im/post/5c0f39526fb9a04a0e2d09da
https://juejin.im/post/59ec657ef265da431b6c5b03
http://www.ruanyifeng.com/blog/2016/01/babel.html
https://segmentfault.com/a/1190000008159877
https://www.babeljs.cn/docs/usage
https://www.babeljs.cn/setup#installation

模块化总结

JavaScript高级面试题(1)_第2张图片
ES6模块化问题解答:
JavaScript高级面试题(1)_第3张图片

针对ES6模块化,我们需要使用babel对ES6进行编译,针对babel使用我们可以用webpack和rollup模块化工具。

4.ES6中Class

Class和普通构造函数有何区别

JS构造函数、Class基本语法、语法糖、继承(JS构造函数实现继承、Class实现继承)

JS构造函数:

构造函数:如用函数用来初始化(使用new运算符)一个新建的对象,我们称之为构造函数(constructor)

function MathHandle(x,y){
	this.x = x;
	this.y = y;
}

MathHandle.prototype.add  = function(){
	return this.x + this.y;
};

var m = new MathHandle(1,2);
console.log(m.add())

关于构造函数和普通函数区别:https://segmentfault.com/a/1190000008615288

Class语法:

class MathHandle{
	constructor(x,y){
		this.x = x;
		this.y = y;
	}

	add(){
		return this.x + this.y;
	}
}

const m = new MathHandle(1,2);
console.log(m.add());

class实质上是构造函数的语法糖,JS本身并没有class。(语法糖:本质是一样的,但是另外一种方式更加易懂,易学)

在构造函数/Class中下面输入输出都是一样的:

typeof MathHandle //function(所以class本质还是函数)
MathHandle.prototype.constructor === MathHandle //true (MathHandle(构造函数)显式原型是MathHandle.prototype)
m.__proto__ === MathHandle.prototype //true (实例m(对象实例)隐式原型通过m.__proto__获得,是MathHandle(构造函数)的显式原型,即MathHandle.prototype)

上面说明,Class中一些类型和原型知识是和构造函数一样的,所以Class实质上是构造函数的语法糖。

继承

ES5中继承(通过原型完成):

function Animal(){
	this.eat = function(){
		console.log();
	}
}

function Dog(){
	this.bark = function(){
		console.log();
	}
}

Dog.prototype = new Animal()

var hashiqi = new Dog()

ES6(1.子类加上extends 2.constructor里面加上super)继承:

class Animal {
	constructor(name){
		this.name = name
	}
	eat(){
		alert(this.name + ' eat')
	}
}

class Dog extends Animal{
	constructor(name){
		super(name)
	}
	say(){
		alert(this.name + ' say')
	}
}

const dog = new Dog('哈士奇')
dog.say()

我们还要注意一个问题,关于constructor指向的修正的问题,先看下面代码。

Dog.prototype = new Animal()

但是这样子写的话,dog 的构造函数就成 animal 的构造函数了,如下:

Dog.prototype.constructor == Animal.prototype.constructor == Animal

所以,指向了Animal构造函数,所以一般加上下面代码进行修正:

Dog.prototype.constructor = Dog

还可以参考:https://blog.csdn.net/u014465934/article/details/94666349

里面关键一句话是:constructor始终指向的是创建本身的构造函数,所以Dog.prototype.constructor指向Animal,按照这个思路理解也可以。

5.ES6中Promise

一个Promise使用实例:

function loadImg(src) {
    const imgUrl = new Promise((resolve, reject) => {
        let img = document.createElement('img')
        img.onload = () => resolve(img)
        img.onerror = () => reject()
        img.src = src
    })

    return imgUrl;
}
 
const src = 'https://www.imooc.com/static/img/index/logo.png'
 
loadImg(src).then((img)=> {
    console.log(img.width)    // 成功打印 200
    return img;
}).then((img) => {
    console.log(img.height)    // 打印高度
}).catch(error => {
    console.log(`${error}`)
})

回调函数/Promise/async await顺序对比讲解:

//1.callback 方式获取一个文件的内容
function getFileContent(fileName, callback) {
    const fullFileName = path.resolve(__dirname, 'files', fileName)
    fs.readFile(fullFileName, (err, data) => {
        if (err) {
            console.error(err)
            return
        }
        callback(
            JSON.parse(data.toString())
        )
    })
}

// 测试 callback-hell(回调地狱)
getFileContent('a.json', aData => {
    console.log('a data', aData)
    getFileContent(aData.next, bData => {
        console.log('b data', bData)
        getFileContent(bData.next, cData => {
            console.log('c data', cData)
        })
    })
})


//2.利用Promise解决回调地狱

// 用 promise 获取文件内容
function getFileContent(fileName) {
    const promise = new Promise((resolve, reject) => {
        const fullFileName = path.resolve(__dirname, 'files', fileName)
        fs.readFile(fullFileName, (err, data) => {
            if (err) {
                reject(err)
                return
            }
            resolve(
                JSON.parse(data.toString())
            )
        })
    })
    return promise
}

getFileContent('a.json')
    .then(aData => {
        console.log('a data', aData)
        return getFileContent(aData.next)
    })
    .then(bData => {
        console.log('b data', bData)
        return getFileContent(bData.next)
    })
    .then(cData => {
        console.log('c data', cData)
    })

//3.使用async await解决
function getFileContent(fileName) {
    const promise = new Promise((resolve, reject) => {
        const fullFileName = path.resolve(__dirname, 'files', fileName)
        fs.readFile(fullFileName, (err, data) => {
            if (err) {
                reject(err)
                return
            }
            resolve(
                JSON.parse(data.toString())
            )
        })
    })
    return promise
}

async function readFileData() {
    // 同步写法
    try {
        const aData = await getFileContent('a.json')
        console.log('a data', aData)
        const bData = await getFileContent(aData.next)
        console.log('b data', bData)
        const cData = await getFileContent(bData.next)
        console.log('c data', cData)
    } catch (err) {
        console.error(err)
    }
}

readFileData()

// async await 要点:
// 1. await 后面可以追加 promise 对象,获取 resolve 的值
// 2. await 必须包裹在 async 函数里面
// 3. async 函数执行返回的也是一个 promise 对象
// 4. try-catch 截获 promise 中 reject 的值

Promise问题解答:
JavaScript高级面试题(1)_第4张图片
更多参考:
https://developers.google.com/web/fundamentals/primers/promises
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

6.ES6常用功能

let/const
多行字符串/模板变量
解构赋值
块级作用域
函数默认参数
箭头函数

JavaScript高级面试题(1)_第5张图片

//多行字符串/模板变量
const name = 'zhangsan',age= 20;
const html = `

${anem}

${age}

`; consloe.log(html);

JavaScript高级面试题(1)_第6张图片

JavaScript高级面试题(1)_第7张图片

JavaScript高级面试题(1)_第8张图片

ES6排名前十位的最佳特性列表:
1.默认参数
2.模板文本
3.多行字符串
4.解构赋值
5.增强的对象文本
6.箭头函数
7.Promise
8.块作用域构造Let和Const
9.Class类
10.Modules模块

上面只是部分笔记。

你可能感兴趣的:(Javascript)