源码学习
2020-04-16 11:10:06 0 举报
AI智能生成
前端源码学习方法论
作者其他创作
大纲/内容
学习什么
架构设计思维
对所用工具更深的理解
优秀编码技巧
源码都有的特性
开始经常会有大量的健壮性判断
健壮性很重要
1. 健壮性最有效的保证就是在参数层面
2. 把容易出问题的代码块用 try catch 包裹起来
2. 把容易出问题的代码块用 try catch 包裹起来
模块调模块
看源码技巧
不要一句一句读
先理清架构,再看入口,依照流程读下去
摈弃其他代码,看核心代码
典型架构
工厂模式
工厂模式是我们最常用的实例化对象模式,
是用工厂方法代替new操作的一种模式。
是用工厂方法代替new操作的一种模式。
工厂模式可以解决实例化对象产生大量重复的问题
<script type="text/javascript">
function createObject(name,age,profession){//集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.profession = profession;
obj.move = function () {
return this.name + ' at ' + this.age + ' engaged in ' + this.profession;
};
return obj;
}
var test1 = createObject('trigkit4',22,'programmer');//第一个实例
var test2 = createObject('mike',25,'engineer');//第二个实例
alert(test1.move());
alert(test2.move());
</script>
function createObject(name,age,profession){//集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.profession = profession;
obj.move = function () {
return this.name + ' at ' + this.age + ' engaged in ' + this.profession;
};
return obj;
}
var test1 = createObject('trigkit4',22,'programmer');//第一个实例
var test2 = createObject('mike',25,'engineer');//第二个实例
alert(test1.move());
alert(test2.move());
</script>
类库例子: JQuery
优点
通过使用工程方法而不是new关键字,将所有实例化的代码集中在一个位置防止代码重复
缺点
工厂模式解决了重复实例化的问题,但一定要查看工厂方法才知道是哪个对象的实例;
相比之下使用new关键字和构造函数,可以让代码更加简单易读。
相比之下使用new关键字和构造函数,可以让代码更加简单易读。
应用场景
- 当对象或组件涉及高复杂性时
- 当需要根据所在的不同环境轻松生成对象的不同实例时
- 当处理很多共享相同属性的小型对象或组件时
建造者模式
只需要产生少数对象,构造过程比较复杂
建造者模式将一个复杂对象的构建和其表示相分离,使得同样的构建过程可以创建不同的表示。
也就是说如果我们用了建造者模式,那么用户就需要制定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了。
建造者模式实际上就是一个指挥者,一个建造者,一个指挥者调用具体建造者工作得出结果给客户。
建造者模式主要用于”分步骤构建一个复杂的对象”,在这其中”分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
也就是说如果我们用了建造者模式,那么用户就需要制定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了。
建造者模式实际上就是一个指挥者,一个建造者,一个指挥者调用具体建造者工作得出结果给客户。
建造者模式主要用于”分步骤构建一个复杂的对象”,在这其中”分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
作用
1.分步创建一个复杂的对象
2.解耦封装过程和具体创建组件
3.无需关心组件如何组装
2.解耦封装过程和具体创建组件
3.无需关心组件如何组装
注意事项
1.一定要一个稳定的算法进行支持
2.加工工艺是暴露的--白富美不用关心如何建房子,但可以随时去看房子建得怎么样
2.加工工艺是暴露的--白富美不用关心如何建房子,但可以随时去看房子建得怎么样
类库例子: Vue
函数式编程
函数式编程是种编程方式,它将电脑运算视为函数的计算;
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
两个基本运算
合成
如果一个值要经过多个函数,才能变成另外一个值,
就可以把所有中间步骤合并成一个函数,这叫做"函数的合成"(compose)。
合成两个函数的简单代码如下。
const compose = function (f, g) {
return function (x) {
return f(g(x));
};
}
就可以把所有中间步骤合并成一个函数,这叫做"函数的合成"(compose)。
合成两个函数的简单代码如下。
const compose = function (f, g) {
return function (x) {
return f(g(x));
};
}
柯里化
f(x)和g(x)合成为f(g(x)),有一个隐藏的前提,就是f和g都只能接受一个参数。
如果可以接受多个参数,比如f(x, y)和g(a, b, c),函数合成就非常麻烦。
这时就需要函数柯里化了。所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。
如果可以接受多个参数,比如f(x, y)和g(a, b, c),函数合成就非常麻烦。
这时就需要函数柯里化了。所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。
// 柯里化之前
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
类库例子: lodash
Vue3 为什么要改成函数式
Logic Composition
组合大于继承
组合大于继承
One of the key aspects of the component API is how to encapsulate and reuse logic across multiple components.
With Vue 2.x's current API, there are a number of common patterns we've seen in the past, each with its own drawbacks.
These include:
In general, these patterns all suffer from one or more of the drawbacks below:
With Vue 2.x's current API, there are a number of common patterns we've seen in the past, each with its own drawbacks.
These include:
- Mixins (via the mixins option)
- Higher-order components (HOCs)
- Renderless components (via scoped slots)
In general, these patterns all suffer from one or more of the drawbacks below:
- Unclear sources for properties exposed on the render context. For example, when reading the template of a component using multiple mixins, it can be difficult to tell from which mixin a specific property was injected from.
- Namespace clashing. Mixins can potentially clash on property and method names, while HOCs can clash on expected prop names.
- Performance. HOCs and renderless components require extra stateful component instances that come at a performance cost.
The function based API, inspired by React Hooks,
presents a clean and flexible way to compose logic inside and between components without any of these drawbacks.
presents a clean and flexible way to compose logic inside and between components without any of these drawbacks.
Type Inference
更好地支持 TS
更好地支持 TS
One of the major goals of 3.0 is to provide better built-in TypeScript type inference support.
Originally we tried to address this problem with the now-abandoned Class API RFC,
but after discussion and prototyping we discovered that using Classes doesn't fully address the typing issue.
The function-based APIs, on the other hand, are naturally type-friendly.
In the prototype we have already achieved full typing support for the proposed APIs.
The best part is - code written in TypeScript will look almost identical to code written in plain JavaScript.
Originally we tried to address this problem with the now-abandoned Class API RFC,
but after discussion and prototyping we discovered that using Classes doesn't fully address the typing issue.
The function-based APIs, on the other hand, are naturally type-friendly.
In the prototype we have already achieved full typing support for the proposed APIs.
The best part is - code written in TypeScript will look almost identical to code written in plain JavaScript.
Bundle Size
打包后体积更小
打包后体积更小
Function-based APIs are exposed as named ES exports and imported on demand.
This makes them tree-shakable, and leaves more room for future API additions.
Code written with function-based APIs also compresses better than object-or-class-based code,
since (with standard minification) function and variable names can be shortened while object/class methods and properties cannot.
This makes them tree-shakable, and leaves more room for future API additions.
Code written with function-based APIs also compresses better than object-or-class-based code,
since (with standard minification) function and variable names can be shortened while object/class methods and properties cannot.
参考
https://github.com/vuejs/rfcs/blob/function-apis/active-rfcs/0000-function-api.md
参考
http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html
JQuery 源码
(function(window){
})(window)
})(window)
为什么要将 window 当参数传入
减少作用域链的查找时间
如何给 JQuery 添加各种功能
先构建 extend 方法,用 extend 来扩展模块
jquery.extend=jquery.fn.extend=function(){
}
jquery.fn.extend({
// css 模块
})
jquery.fn.extend({
// 动画 模块
});
}
jquery.fn.extend({
// css 模块
})
jquery.fn.extend({
// 动画 模块
});
extend 方法中的享元模式
享元模式可以有效减少代码中的对象数量
jquery.extend = jquery.fn.extend = function() {
// 享元模式,把不同部分拿出来,相同部分保留下
var target;
var source;
if (arguments.length === 1) {
target = this;
source=arguments[0];
}else{
target=arguments[0];
source = arguments[1];
}
for (var name in source) {
target[name] = source[name];
}
};
// 享元模式,把不同部分拿出来,相同部分保留下
var target;
var source;
if (arguments.length === 1) {
target = this;
source=arguments[0];
}else{
target=arguments[0];
source = arguments[1];
}
for (var name in source) {
target[name] = source[name];
}
};
模块化支持检测
(现在一定要有)
(现在一定要有)
jquery 里:
if (typeof define === "function" && define.amd && define.amd.jquery) {
define("jquery", [], function() {
return jquery;
});
}
if (typeof define === "function" && define.amd && define.amd.jquery) {
define("jquery", [], function() {
return jquery;
});
}
Vue 里:
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? (module.exports = factory())
: typeof define === "function" && define.amd
? define(factory)
: ((global = global || self), (global.Vue = factory()));
})(this, function() {})();
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined"
? (module.exports = factory())
: typeof define === "function" && define.amd
? define(factory)
: ((global = global || self), (global.Vue = factory()));
})(this, function() {})();
架构亮点
利用工厂模式,无 new 化构建对象
模块划分明确
开闭原则的优秀体现
指的是 extend 方法吗??
指的是 extend 方法吗??
在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)
应该对于扩展是开放的,但是对于修改是封闭的”,
这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
应该对于扩展是开放的,但是对于修改是封闭的”,
这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
express 架构
建造者模式,通过 mixin 函数来给 app 函数扩展功能
var mixin=require('merge-descriptors')
var proto=require('./application.js')
module.exports=createApplication
function createApplication(){
function app(){
}
mixin(app,proto)
return app
}
var mixin=require('merge-descriptors')
var proto=require('./application.js')
module.exports=createApplication
function createApplication(){
function app(){
}
mixin(app,proto)
return app
}
给 app 函数对象上添加
get post delete 等请求方法
get post delete 等请求方法
先将所有方法放入数组中,然后循环数组进行处理
var methods=['get','post','put','delete']
methods.forEach((method)=>{
app[method]=function(){
route[method].call(this)
}
})
var methods=['get','post','put','delete']
methods.forEach((method)=>{
app[method]=function(){
route[method].call(this)
}
})
参考
https://study.163.com/course/courseLearn.htm?courseId=1209772816#/learn/live?lessonId=1280423552&courseId=1209772816
https://segmentfault.com/a/1190000002525792
0 条评论
下一页