一.源码中主要的方法
1.如何把伪数组转换成真数组的方法
在vue的源码中使用的是es5的方法 [].prototype.slice.bind(obj) 来实现的
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>源码主要技术点</title>
</head>
<body>
<div id="test">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</body>
<script>
// 如何把伪数组转换真数组
const ls = document.getElementsByTagName('li');
此时的ls是假数组虽然可以根据索引能获取值
console.log(ls instanceof Array); // false
// 方法1 该方法为es6的方法 也可以转换es6中的set语句
const arrls = Array.from(ls);
console.log(arrls instanceof Array); // true
// 方法2 es5实现继承数组原型的方法 用call或者apply都可以实现
const arrls1 = Array.prototype.slice.apply(ls)
console.log(arrls1 instanceof Array); // true
const arrls1 = Array.prototype.slice.call(ls)
console.log(arrls1 instanceof Array); // true
</script>
</html>
2.node.nodeType :获取节点类型
已代码为例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>源码主要技术点</title>
</head>
<body>
<div id="test1">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</body>
<script>
const elementNode = document.getElementById('test1'); // 元素节点 1
const attrNode = elementNode.getAttributeNode('id'); // 属性节点
const textNode = elementNode.firstChild // 文本节点
console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType)
// 1 , 2 , 3
console.log(elementNode, attrNode, textNode)
// 元素
// id="text"
// #text
</script>
</html>
3.Object.defineProperty(obj, prop, descriptor)
obj: 定义属性的对象
prop: 定义或修改属性的名称
descriptor: 将被定义或修改的属性描述符
数据描述符
value: 默认值
configurable: 是否可以重新定义
enumerable: 是否可以枚举
writable: 是否可以写或者更改
访问描述符
get: 动态计算读取当前属性的值
set: 监视属性值的变化,更新其他相关属性
const obj = {
firstName: 1,
lastName: 2
}
Object.defineProperty(obj, 'fullName', {
get: function() {
return this.firstName+ '~' +this.lastName
},
set:function(value) {
const names = value.split('~')
this.firstName = names[0]
this.lastName = names[1]
}
})
console.log(obj.fullName) // 1~2
obj.firstName = 3
obj.lastName = 4
console.log(obj.fullName) // 3~4
obj.fullName = 5~7
console.log(obj.firstName) // 5
console.log(obj.lastName) // 7
vue的计算属性就是运用了该语法
该语法IE8不支持,所以vue不支持IE8
4.Object.keys(obj)
obj: 要遍历的对象
代码如下
const obj = {
firstName: 1,
lastName: 2
}
const arr = Object.keys(obj)
console.log(arr) // ["firstName", "lastName"]
vue中的v-for就是用该语法来遍历的
5.obj.hasOwnProperty(prop)
判断prop是否为自身的属性
const obj = {
firstName: 1,
lastName: 2
}
console.log(obj.hasOwnProperty('fullName')) // true
console.log(obj.hasOwnProperty('toString')) // false
toString()是对象原型的方法, 不是自身属性
6.Document.Fragment
高效一次批量更新多个节点,提高性能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>源码主要技术点</title>
</head>
<body>
<div id="test1">
<ul id="test_fragment">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</body>
<script>
const ul = document.getElementById('test_fragment');
// 1.创建fragment
const fragment = document.createDocumentFragment();
// 2.取出ul中的所有子节点保存到fragment
let child;
while(child = ul.firstChild) {
fragment.appendChild(child);
}
console.log(fragment)
// 3.更新fragment使用li的文本
Array.prototype.slice.call(fragment.childNodes).forEach(function(item) {
if (item.nodeType === 1) {
item.textContent = 'fragment'
}
})
// 4.将fragment放入ul中
ul.appendChild(fragment)
</script>
</html>
此时显示的应该是fragment而不是1, 2, 3