vueJS的源码解读

vue源码总共包含约一万行代码量(包括注释)特别感谢作者Evan You开放的源代码,访问地址为Github

  • 代码整体介绍与函数介绍预览
  • 代码模块分析
  • 代码整体思路

总体的分析

总体分析图片

从图片中可以看出的为采用IIFE(Immediately-Invoked Function Expression)立即执行的函数表达式的形式进行的代码的编写

常见的几种插件方式: (function(,){}(,))或(function(,){})(,)或!function(){}()等等,其中必有一项会传入内部依赖的上下文,可以为window或其他插件或框架名称

这种写法非常像jquery的源码的写法,jquery中多了一个window的判断

jquery的插件的写法

window对象

1.window对象的属性均指向window对象自身;(可以利用函数内this.window.的属性在进行对象调用时会因此指向不同的当前窗口)

  window.window.....

2.全局变量也即是定义在window下的属性,也即是在全局作用域下定义的变量attr等也即是相当于在window.attr上定义了相关的值,给我们启发 –1.通常在编码的过程中要避免污染全局变量;–2.定义函数的时候最好不要在外部可以访问与修改

    function test(){console.info("a")}
    window.test=function test(){.....}//也即是相当于全局的一个属性

3.对于window的自身的属性可以不必写window.可以直接调用,如innerWidth (innerWidth的表示可以参考jqzoom中的图)

IIFE

IIFE也即是立即执行的函数表达式,这种写法作为函数定义的两种方式之一(一种为函数声明,另一种为函数表达式)写法很多但是主要目的是告诉解析器一表达式的方式进行解析 (例如匿名函数:创建一个函数并将它的赋值给变量 ;)

 var s=function(){....}
 function s(){.......}

第一种形式也即是匿名函数,赋值号右边有值或表达式,告诉解析器为函数表达式的类型(另:函数表达式name属性为空字符串) ;第二种会在代码执行前会进行函数的声明提升,从而预先读取函数的声明(可以在未定义前调用该函数);

综上可以常见的很多插件中的写法如下
( function() {}() );
( function() {} )();
[ function() {}() ];
~ function() {}();
! function() {}();
+ function() {}();
- function() {}();

详细的可以参考该作者对问题的回答:
https://www.zhihu.com/question/20292224


1.删除一个属性必要时触发改变

Delete a property and trigger change if necessary.

function del(obj, key) {
if (!hasOwn(obj, key)) {
return;
}
……..
}


1.2 hasOwn(obj,key) (检查对象是否含有该属性)

var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key);
}

  1. 考虑避免当函数重新定义hasOwnProperty的覆盖原来的定义的时候 直接从原型链中取出
  2. 检测其直接挂载的属性(direct properties)而非从原型链中继承的属性(return false)

delete obj[key];
var ob = obj. _ ob _;
if (!ob) {
return;
}

如果存在该属性则删除之 ;
delete操作不会对直接释放内存做任何的操作,只是删除对象的引用;如果删除的属性在原型链中也存在的时候则 ,删除后对象将会继承原型链中的属性;删除对象的属性 对变量或函数的名称无效 (区分全局的变量 也即是挂在在全局对象的属性);不能删除预先定义对象的属性;不存在返回true

_ ob _位后续定义的一个属性 将会在def会看到;如果不存在该属性则直接返回


ob.dep.notify();
if (ob.vms) {
var i = ob.vms.length;
while (i–) {
var vm = ob.vms[i];
vm._proxy(key);
vm._digest();
}
}
return val;

此时出现的dep;

1.3 Dep函数 (发布订阅者模式应用)

var uid$1 = 0;

function Dep() {
this.id = uid$1++;
this.subs = [];
}
Dep.target = null;

Dep.prototype.addSub = function (sub) {
this.subs.push(sub);
};

Dep.prototype.removeSub = function (sub) {
this.subs.$remove(sub);
};

Dep.prototype.depend = function () {
Dep.target.addDep(this);
};

Dep.prototype.notify = function () {
// stablize the subscriber list first
var subs = toArray(this.subs);
for (var i = 0, l = subs.length; i < l; i++) {
subs[i].update();
}
};

……

以上为该文章的开始部分 ,以及各部分的将要介绍的格式,下文将分模块的解读vue的源码

这里写图片描述


Logo

前往低代码交流专区

更多推荐