认识Vue源码
一、预备知识:
1、节点与节点类型:
(1)如何获得元素节点。
var elementNode=document.querySelector(“selector”);
var elementNodes=document.querySelectorAll(“selector”);
(2)如何获得属性节点(一个元素节点的HTML属性们)。
var attrs=elementNode.attributes; //返回elementNode的所有属性节点的集合
var attr=elementNode.getAttrubuteNode(“attrName”);//返回elementNode指定的属性节点
(3)如何获得文本节点。
var subNode=elementNode.firstChild; //返回元素节点的第一个子节点
var subNode=elementNode.lastChild; //返回元素节点的最后一个子节点
(4)如何获得所有的子节点:childNodes。
var temp=elementNode.childNodes;
(5)三大节点的节点类型:nodeType。
三大节点:元素节点(<div></div>)、属性节点(title=“标题”)、文本节点
节点的三大属性:nodeType、nodeName、nodeValue。
返回节点的类型:元素节点-1,属性节点-2,文本节点-3。
2、属性的特性:也叫作属性的“描述符”。
-属性:利用var声明的变量、对象的属性、对象的方法。 一个属性要么具备数据特性,要么具备访问器特性。
(1)属性的数据特性:枚举性、可写性、取值、可配置性。
一个属性被创建出来之后,默认具备属性的数据特性。
Vue实例中data数据区的所有变量都具备访问器特性,不具备数据特性。
(2)属性的访问器特性:枚举性、可配置性、getter、setter。
getter:当获取属性取值时执行的代码。(get:function(){})
setter:当设置属性取值时执行的代码。(set:function(){})
getter和setter可以成功的实现数据拦截。
例:var a=1000;
Object.defineProperty(window,"x",{
enumerable:true, //枚举性
configurable:true,//可配置性
get:function(){
return a;
},
set:function(newValue){
a=newValue;
}
})
(3)读取属性的特性:
Object.getOwnPropertyDescriptor(对象,‘属性’,)
Object.getOwnPropertyDescriptors(对象)
例:var x=100;
var temp=Object.getOwnPropertyDescriptor(window,"x");
console.log(temp);
(4)设置属性的特性:
Object.defineProperty(对象,‘属性’,{描述符})
Object.defineProperties(对象,{
属性:{描述符},
属性:{描述符}
})
3、利用Object的方法遍历对象的可枚举属性:
Object.keys(对象):遍历对象的可枚举属性名,结果为数组。
Object.values(对象):遍历对象的可枚举属性值,结果为数组。
Object.entries(对象):遍历对象的可枚举属性名和属性值,结果为二维数组。
例:var obj={a:100,b:200,c:300,d:400,e:‘ABC’};
console.log(Object.keys(obj)); //[‘a’,‘b’,‘c’,‘d’,‘e’]
console.log(Object.values(obj)); //[100,200,300,400,‘ABC’]
console.log(Object.entries(obj)); //[ [‘a’,100],[‘b’,200],[‘c’,300],[‘d’,400],[‘e’,‘ABC’] ]
4、ES6为数组新增的静态方法:
Array.from():将类数组和可遍历对象转换为数组。
我们这里用来遍历NodeList对象、NamedNodeMap对象。
(1)类数组(长得像数组的对象 like-array object)
对象的属性必须是整数,对象必须具备length属性。
例:let obj={“0”:100,“1”:200,“2”:300,length:3}
let array=Array.from(obj);
(2)可遍历对象(Iterator):可以使用for-of遍历的对象。
原生的可遍历对象:数组、字符串、Set、Map、NodeList、NamedNodeMap。
for-in和for-of的区别:
for-in用来遍历对象;for-of用来遍历可遍历对象。
NodeList对象:DOM操作当中找到的包含多个标记的元素节点。
NamedNodeMap对象:DOM操作当中找到的属性节点的集合。
A .利用for-of遍历NodeList对象:
let nodes=document.querySelectorAll(".box"); //[object NodeList]
for(let item of nodes){
console.log(item);
}
let temp=Array.from(nodes);
B .利用for-of遍历NamedNodeMap对象:
let node=document.querySelector(".lj")
let attrs=node.attributes;
for(let item of attrs){
console.log(item);
}
let temp=Array.from(attrs);
5、ES6为字符串新增的实例方法:
startsWith(str):判断字符串是否以指定的子串str开头。
例:判断.lj元素节点的所有属性是属性还是指令。
let aNode=document.querySelector(".lj");
let attrs=aNode.attributes;
Array.from(attrs).forEach(item=>{
if(item.nodeName.startsWith('v-')){
console.log(item.nodeName + "是指令");
}else{
console.log(item.nodeName + "是属性");
}
})