【笔记】imooc- 揭秘一线互联网企业 前端javaScript高级面试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aSuncat/article/details/87619174

(aSuncat:①内容较为冗余,不复杂的内容,说得却不够简洁。②很多简单的东西,对于高级面试课程,可以一笔带过,讲师却浮于表面过多解释。③第三章讲解jQuery源码,原型-构造函数-实例,可以看一下)

第01章 课程介绍

01-01 课程介绍

一、基础知识
1、es6常用语法
class、module、promise等
2、原型高级应用
结合jQuery和zepto源码
3、异步全面讲解
从原理到jQuery,再到promise
二、框架原理
1、虚拟dom
存在价值,如何使用,diff算法
2、MVVM dom
vue 响应式、模板解析、渲染
3、组件化react
组件化、jsx、vdom、setState
三、混合开发
1、hybrid
2、hybrid vs h5
基础,和h5对比,上线流程
3、前端客户端通讯
通讯原理,js-bridge封装
四、热爱编程
1、读书博客
2、开源
五、高级js面试中,面试官爱问“源码”、“实现”

01-02 架构

一、es6
1、模块化的使用和编译环境
2、class和js构造函数的区别
3、promise的用法
4、es6其他常用功能
二、异步
1、什么是单线程,和异步有何关系
2、什么是event-loop
3、目前js解决异步的方案有哪些
4、如果只用jquery,如何解决异步
5、promise的标准
6、async/await的使用
三、原型
1、原型如何实际应用
2、原型如何满足扩展
四、vdom
1、什么是vdom,为何要用vdom
2、vdom如何使用,核心函数有哪些?
3、了解diff算法吗
vom的核心算法
五、mvvm
1、之前使用jquery和现在使用vue或react框架的区别
2、你如何理解mvvm
3、vue如何实现响应式
4、vue如何解析模板
5、介绍vue的实现流程
六、组件化
1、对组件化的理解
2、jsx是什么
3、jsx和vdom什么关系
4、简述react和setState
5、阐述自己如何比较react和vue
七、hybrid
1、hybrid是什么,为何要用hybrid
2、hybrid如何更新上线
3、hybrid和h5如何区别
4、js如何与客户端通信
八、其他
如何写博客
如何做开源

第02章 es6语法

02-01 开始

一、es6模块化如何使用,开发环境如何打包?
二、class和普通构造函数有何区别?
三、promise的基本使用和原理?
四、总结一下es6其他常用功能?

2-02 es6模块

一、es6模块化如何使用,开发环境如何打包?
1、模块化的基本语法
export/ˈekspɔːrt/

export default{
	a: 100
}

2、开发环境配置
3、关于js众多模块化标准

2-02 babel-new-part

一、开发环境-babel (处理es6语法)
1、电脑有node环境,运行npm init
2、npm install --save-dev babel-core babel-preset-es2015 babel-pareset-latest
3、创建.babelrc文件
4、npm install --global babel-cli
5、babel -version
6、创建 ./src/index
7、.babelrc文件

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

8、sudo npm install -g babel-cli (windows需要管理员模式)
9、babel src/indes.js 就能得到es6转换为es5的代码

2-05 模块化-webpack

一、webpack (处理es6模块,当然还有其他功能)
1、npm install webpack bable-loader --save-dev
2、配置webpack.config.js

module.exports = {
	entry: './src/index.js',
	output: {
		path: __dirname,
		filename: './build/bundle.js'
	},
	module: { // 模块
		rules: [{
			test: /\.js?$/,
			exclude: /(node_modules)/, // 安装第三方插件创建的,是第三方插件的代码
			loader: 'babel-loader'
		}]
	}
}

3、配置pacakage.json的scripts

“scripts”: {
	"start": "webpack" // 运行webpack,根据webpack.js对babel进行编译,输出bundle.js
}

4、运行npm start
5、index.html中script 的src 是build/bundle.js
6、http-server -p 8881 // 启动一个静态服务

2-06 rollup介绍

一、rollup
1、npm init
2、npm i --save-dev rollup ruollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest babel-core
3、配置.babelrc(一般面试官不会问这个配置文件里的东西)

{
	"presets": [
		[
			"latest": {
				"es2015": {
					"modules": false
				}
			}
		],
		"plugins": ["external-helpers"]
	]
}

4、配置rollup.cofig.js

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
export default {
	entry: 'src/index.js',
	format: 'umd',  // 格式,兼容直接引入,兼容amd,兼容comonJs
	plugins: [
		resolve(),
		babel({
			exclude: 'node_modules/**'
		})
	],
	dest: 'build/bundle.js'
}

5、package.json里的scripts的start改成rollup -c rollup.config.js
6、npm start
二、rollup功能单一,只能打包模块化,webpack功能强大
参考《设计原则》和《linux/unix设计思想》
三、rollup没有冗余代码,调试方便。

2-08 模块化-总结

一、模块化
1、amd成为标准,require.js(也有cmd)
2、前端打包工具,使nodejs可以被使用(commonJs虽然是后端的,但是可以被打包成前端可识别的方式)
3、es6出现,想统一现在所有模块化标准
4、nodejs积极支持,浏览器尚未统一
5、可以自造库lib,但是不要自造标准(造轮子是属于造类,造库,但是不属于造标准)
二、问题解答
1、语法:import export(注意有无default)
2、环境:babel编译es6语法,模块化可用webpack和rollup
3、扩展:说一下自己对模块化标准统一的期待

2-09 class-js构造函数

1、class和普通构造函数有何区别?
(1)js构造函数

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); // new一个实例
console.log(m.add())

(2)class基本语法

class MathHandler{ // MathHandler是一个构造函数,构造函数都有显式原型:prototype
	constructor(x, y) { // 构造器,java,c#的语法,面向对象高级语言的语法
		this.x = x;
		this.y = y;
	}
	add() {
		return this.x + this.y;
	}
}
const m = new MathHandle(1, 2); // 实例,所有实例都会有一个隐式原型:__proto__
console.log(m.add());

typeof MathHandle  // 'function'
MathHandle.prototype.constructor === MathHandle; // true
m.__proto__ === MathHandle.prototype; // true

(3)语法糖
class本身就是一个语法糖
(4)继承
①低级构造函数的原型,赋值成高级构造函数的实例

function Animal(){this.eat = function() {console.log('animal eat')}}
function Dog(){this.bark = function() {console.log('dog dark')}}
Dog.prototype = new Animal(); // 绑定原型,实现继承
var hashiqi = new Dog();

class的继承

class Animal() {
	constructor(name) {
		this.name = name;
	}
	eat() {
		alert(this.name + 'eat);
	}
}
class Dog extends Animal{
	constructor(name) {
		super(name); // 如果有class,extends,则要用super(),super是被继承的class的constructor
		this.name = name;
	}
	eat() {
		alert(this.name + 'eat);
	}
}

2-12 class-总结

一、问题解答
1、class 在语法上更加贴合面向对象的写法
2、class实现继承更加易读、易理解
3、更易于写java等后端语言的使用
4、本质还是语法糖,使用prototype

2-15 promise总结

一、promise
1、new promise实例,要return
2、new promise时要传入函数,函数有resolve、reject两个参数
3、成功时执行resolve(),失败时执行reject()
4、then监听结果

2-16 常用功能演示

一、总结一下es6其他常用功能
1、let、const /'kɑnst/
const定义常量,常量不能被重新赋值
2、多行字符串/模板变量
js拼接变量字符串模板

console.log(`输出:${name}`)

3、解构赋值
整体数组或对象中拿到其中一个元素或属性值

// obj
const obj = {a: 10, b: 20, c:30};
const {a, c} = obj;
console.log(a); // 10
console.log(c); // 30

// arr
const arr = ['xxx', 'yyy', 'zzz'];
const [x, y, z] = arr;
console.log(x); // xxx
console.log(z); // zzz

4、块级作用域
for循环

// js
var obj = {a: 100, b: 200};
for (var item in obj) {console.log(item)};
console.log(item); // 'b'

// es6
const obj = {a: 100, b: 200};
for (let item in obj) {console.log(item)};
console.log(item); // undefined

5、函数默认参数

// js
function(a, b) {
	if(b == null) {b = 0;}
}
// es6
function (a, b=0) {

}

6、箭头函数
彻底解决了之前函数this指向全局window对象的问题

function fn() {
	console.log('real', this); // {a: 100}
	var arr = [1, 2, 3];
	// 普通js
	arr.map(function(item) {
		console.log('js',this); // window
		return item + 1;
	});
	// 箭头函数
	arr.map(item => {
		console.log('es6', this); // {a: 100}
		return item + 1;
	});
}
fn.call({a: 100})

第03章 原型

3-01 开始

1、说一个选型的实际应用
2、原型如何体现它的拓展性

3-02 实际应用-Jquery使用

一、jquery
多个实例都可以共用一个方法时,说明这些方法(eg:css(), html())都是来自于一个构造函数的原型中

var $p = $('p'); 
$p.css('color', 'red'); // css是原型方法
console.log($p.html()); // html是原型方法 // 如果有多个p元素,$p.html()默认是最后一个元素的html
<body>
<div>
  <p>段落1</p>
  <p>段落2</p>
</div>

<!--<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>-->
<script>
  (function(window) {
    var jQuery = function(selector) {
      return new jQuery.fn.init(selector); // new了一个构造函数的实例
    };
    jQuery.fn = {
      css: function(key, value) {

      },
      html: function(value) {
        return '这是html';
      }
    };
    var init = jQuery.fn.init = function(selector) { // 构造函数
      var slice = Array.prototype.slice;
//      var dom = document.querySelectorAll(selector); // nodeList[p,p]:__proto__是nodeList
      var dom = slice.call(document.querySelectorAll(selector)); // [p, p]:__proto__是Array // selector转换成dom的list,然后转换成数组
      console.log(dom);
      var i, len = dom ? dom.length : 0;
      for (i = 0; i < len; i++) {
        this[i] = dom[i]; // 所有的元素都变成实例的属性
      }
      this.length = len;
      this.selector = selector || '';
    };
    init.prototype = jQuery.fn; // 构造函数的原型赋值成jQuery.fn,jQury.fn是一个js对象

    window.$ = jQuery;
  })(window);

  $p = $('p'); // 初始化实例
  console.log($p.html());

二、百度bootcdn进入官网,能得到jquery的源码

3-09 扩展性-插件机制

一、扩展原型
将getNodeName属性放在构造函数的原型中,不是直接给构造函数的原型赋值,而是通过$.fn赋值

$.fn.getNodeName = function() {
	return this[0].nodeName;  // this[0]可以得到上述的第一个p标签,this就是实例$p,init这个构造函数里创建了this[i];
} 

好处:
1、只有$会暴露在window全局变量(只暴露一个变量,不然容易造成全局变量的污染)
2、将插件扩展统一到$.fn.xxx这一个接口,方便使用。

第04章 异步

4-01 开始

一、什么是单线程,和异步有什么关系?
1、单线程:只有一个线程,同一时间只能做一件事情。
setTimeout的时间为10的9次方,可以测试卡顿
2、原因:避免dom渲染的冲突
(1)
①浏览器需要渲染dom
②js可以修改dom结构
③js执行的时候,浏览器dom渲染会暂停
④两段js也不能同时执行(都修改dom就冲突了)
⑤webworder支持多线程,但是不能访问dom
(2)等待也属于占线程的一种
3、解决方案:异步
问题一:没按照书写方式执行,可读性差
问题二:callback中不容易模块化
4、实现方式:event-loop
二、js轮询event-loop
1、事件轮询/事件循环,js实现异步的具体解决方案
2、流程
(1)同步代码,直接执行
(2)异步先放在异步队列中
(3)待同步函数执行完毕,轮询执行异步队列的函数
ajax加载完成,即ajax什么时候success,就什么时候把ajax中的函数放入到异步队列中
①什么是异步队列,何时被放入异步队列
a.立即放入。b.延时时间到了再放入。c.ajax请求成功
②轮询的过程
三、是否用过jQuery的Deferred
1、deferred:延迟
2、jQuery1.5,可使用jQuery deferred

// 
ajax.done(function() {
	console.log('sucess1');
})
	.fail(function() {
		console.log('fail');
	})
	.done(function() {'success2'});
// 
ajax.then(function() {console.log('success1')}, function() {console.log('error1')})
		.then(function() {console.log('success1')}, function() {console.log('error1')})

①无法改变js异步和单线程的本质
②只能从写法上杜绝callback这种形式(ajax请求的success)
③它是一种语法糖形式,但是解耦了代码
④很好的体现:开发封闭原则,对扩展开放,对修改封闭
四、promise的基本使用和原理
1、jQuery Deferred

function waitHandler() {
	var dtd = $.Deferred();
	var wait = function(dtd) {
		var task = function() {
			console.log('处理);
			dtd.resolve();
		}
		setTimeout(function() {task();}, 100);
		// return dtd;
		return dtd.promise(); // 返回的是promise对象,而不是dtd对象。promise只有.then/.done/.fail这些方法,没有resolve(), reject()
	}
	return wait(dtd);
}
var w = waitHandler();
// w.then(function() {}, function() {}).then(function() {}, function() {});
// $.when(w).then();

(1)、dtd的api可分成2类,用意不同
①dtd.resolve dtd.reject
②dtd.then dtd.done dtd.fail
Deferred实例既能执行主动干预成功或失败的函数(eg:.resolve,.reject),又能执行被动监听结果的函数(eg:.then, .done, .fail)
2、jQuery1.5对ajax的改变举例
3、说明如何简单的封装,使用derrerred
4、说明promise和deferred的区别
5、promise.all、promise.race

// promise.all接收一个promise对象的数组
// 接收到的datas是一个数组,一次包含了多个promise

// promise.race接收一个包含多个promise对象的数组
// 接收到的data即最先执行完成的promise的返回值

①race:赛跑

6、w3c标准、ddt标准、ecma标准
7、如果console.log打印出来的是native code:浏览器自己定义的,浏览器不会打代码公布给你
8、

promise.then().catch();

9、promise标准
状态变化、then函数
五、介绍一下async/await(和promise的区别,联系)
1、then只是将callback拆分了。
2、async/await是最直接的同步写法

import 'babel-polyfill';
function load
const load = async function() {
	const result1 = await loadImg(src1);
	console.log(result1);
	const result2 = swait loadImg(src2);
	console.log(result2);
}
load();

①使用await,函数必须用async标识
②await后面跟的是一个promise实例
③需要babel-polyfill
六、总结一下当前js解决异步的方案
1、jQuery Deferred
2、promise
3、async/ await

第05章 虚拟dom

5-01 开始

一、virtual/ˈvɝ​tʃʊəl/ dom
1、vdom是vue和react的核心。
2、用js模拟dom结构,提高重绘性能。
3、浏览器最费性能的是dom操作,js操作比dom操作快多了。
二、vdom是什么?为何会存在vdom?
三、vdom的如何应用,核心api是什么?
1、snabbdom:开源vdom库
(1)①h函数:生成dom节点

h('<标签名>', {...属性...}, [...子元素...])
h('<函数名>', {...属性...}, '...')

②patch函数:进行对比,进行打补丁渲染

patch(container, vnode)
patch(vnode, newVnode)

(2)

var newVnode = h('table', {}, data.map(function(item) {
	var tds = [];
	var i;
	for (i in item) {
		if (item.hasOwnProperty(i)) {
			tds.push(h('td', {}, item[i] + ''));
		}
	}
	return h('tr', {}, tds);
}))

四、介绍一下diff算法?
1、diff test1.txt test2.txt
就能比较出两个文件的差异
2、git diff test1..html
文件内部改动:增删改
3、diff在线对比,和mac的svn客户端:cornerstone代码版本之间的对比一样
4、递归:自己调用自己,如果不能实现递归,就不能算是图灵完美语言
5、虚拟dom转换成真实dom
①没有旧节点

function createElement(vnode) {
	var tag = vnode.tag; // 'ul'
	var attrs = vnode.attrs || {};
	var children = vnode.children || [];
	if (!tag) {
		return null;
	}
	// 创建真实的dom元素
	var elem = document.createElement(tag);
	// 属性
	var attrName;
	for (attrName in attrs) {
		if (attrs.hasOwnProperty(attrName)) { // hasOwnProperty:true-是自己的属性,而不是原型property中的属性
			elem.setAttribute(attrNam, attrs[attrName]);
		}
	}
	// 子元素
	children.forEach(function(function(childVnode)){
		// 给elem添加子元素
		elem.appendChild(createElement(childVnode));
	})
	// 返回真实的dom元素
	return elem;
}

6、diff实现过程

patch(container, vnode) 和patch(vnode, newVnode);
createElement
updateChildren

7、(1)diff算法是linux的基础命令

(2)vdom中应用diff算法是为了找出需要更新的节点

第06章 mvvm和vue

6-03

一、中国vuejs官网:cn.vuejs.org

6-04

一、jquery和vue的区别
1、数据和视图的分离,解耦,开发封闭原则(对扩展开放、对修改封闭)
2、vue:以数据驱动视图,只关心数据变化,dom操作被封装

6-08

一、mvvm:model view viewModel
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。data。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。视图,html。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。连接器,对应newVue(),view可以通过事件绑定影响到model,model可以通过数据绑定影响到view。
二、mvvm是mvc发展过来的
三、mvvm框架实现的三要素?(vue的三要素)
1、响应式:vue如何监听到data的每个属性变化?
(1)修改data属性后,vue立刻监听到。Object.defineProperty

var __name = 'may';
Object.defineProperty(obj, 'name',{
	get: function() {
		return __name;
	},
	set: function(newVal) {
		__name = newVal; // 修改__name = 'april',obj.name就会变成april
	}
})

(2)data属性代理到vm上
2、模板引擎:vue的模板如何被解析,指令如何处理?
(1)模板是什么
①本质:字符串
②有逻辑,如v-if, v-for等
③与html格式很像,但有很大区别
④模板最终必须转换成Js代码(js函数-render函数),因为
有逻辑(v-if, v-for),必须用js才能实现(图灵完美语言)
转换为html渲染页面,必须用js才能实现
(2)render函数
(3)render函数与vdom
3、渲染:vue的模板如何被渲染成Html?以及渲染过程?

6-16

一、《js语言精粹》,美国
尽量不要用with,会给开发、测试带来很大的成本

6-19

一、vue源码搜索code.render,能找到var code = generate(ast, options),就能得到render函数。

6-20 render函数-讲解4

一、
(1)vue2.0开始,开始支持预编译,
开发环境:写模板
编辑打包:
生产环境:js
(2)react组件化
jsx模板
编译:->js代码
jsx语法 - 标准
二、v-model:双向事件绑定,有get、set
三、render函数返回的是vnode

6-25

一、vue的整个实现流程
1、第一步:解析模板成render函数
template
2、第二步:响应式开始监听
object.defineProperty
data属性代理到vm上
3、第三步:首次渲染,显示页面,且绑定依赖
(1)为何要监听get,直接监听set不行吗?
①data中有很多属性,有些被用到,有些可能不被用到(data中没有人访问,就不会用get,如没有{{aaa}}指的就是aaa没有被访问)
②被用到的会走到get,不被用到的不会走到get
③未走到get中的属性,set的时候也无需关心
④避免不必要的重复渲染
4、第四步:data属性变化,触发rerender
defineProperty, get, set
(1)修改属性,被响应式的set监听到
(2)set中执行updateComponent
(3)updateComponent重新执行vm._render()
(4)生成的vnode和prevVnode,通过Patch进行对比
渲染到html

6- 28

第07章 组件化和react

aSuncat:没看

第08章 hybrid

aSuncat:没看

第09章 课程总结

9-01 不讲nodejs

1、nodejs
(1)stream, server端的概念
(2)fs或者存储,server端的概念
(3)以及,服务器的运维(均衡、监控、报警灯)
(4)nodejs并不是像原型、异步一样,隶属于Js的一个模块。
(5)nodejs是一个独立的技术栈,只不过用了js语法。

9-02 如何热爱编程

1、如何证明你热爱编程
(1)看书
构建知识体系的最好方式
(2)写博客
(3)做开源

9-03 总结

对整个视频的总结,可以看一下,理个大纲。

猜你喜欢

转载自blog.csdn.net/aSuncat/article/details/87619174