Vue系列二十一:源码解析

在这里插入图片描述
1、[].slice.call(lis): 将伪数组转换为真数组
2、node.nodeType: 得到节点类型
3、Object.defineProperty(obj, propertyName, {}): 给对象添加/修改属性(指定描述符)
 configurable: true/false 是否可以重新define
 enumerable: true/false 是否可以枚举(for…in / keys())
 value: 指定初始值
 writable: true/false value是否可以修改存取(访问)描述符
 get: 函数, 用来得到当前属性值
 set: 函数, 用来监视当前属性值的变化
4、Object.keys(obj): 得到对象自身可枚举的属性名的数组
5、DocumentFragment: 文档碎片(高效批量更新多个节点)
6、obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性

<body>

<div id="test">vue源码解析</div>

<ul id="fragment_test">
  <li>test1</li>
  <li>test2</li>
  <li>test3</li>
</ul>

<!--
1. [].slice.call(lis): 将伪数组转换为真数组
2. node.nodeType: 得到节点类型
3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
6. DocumentFragment: 文档碎片(高效批量更新多个节点)
-->

<script type="text/javascript">
  //1. [].slice.call(lis): 根据伪数组生成对应的真数组
  const lis = document.getElementsByTagName('li') // lis是伪数组(伪数组是指一个有length和数值下标属性的对象)
  console.log(lis instanceof Object, lis instanceof Array, lis.forEach)//true false undefined
  // 数组的slice()截取数组中指定部分的元素, 生成一个新的数组
  const lis2 = Array.prototype.slice.call(lis)
  console.log(lis2 instanceof Object, lis2 instanceof Array, lis.forEach)//false true function

  //2. node.nodeType: 得到节点类型
  const elementNode = document.getElementById('test')
  const attrNode = elementNode.getAttributeNode('id')
  const textNode = elementNode.firstChild
  console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType)

  //3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
  const obj = {
    firstName: 'A',
    lastName: 'B'
  }
  //给obj添加fullName属性
  //obj.fullName = 'A-B'
  /*
    属性描述符:
    1.数据描述符:
      configurable: 是否可以重新定义
      enumerable: 是否可以枚举
      value: 初始值
      writable: 是否可以修改属性值
    2.访问描述符:
      get: 回调函数,根据其它相关的属性动态计算得到当前属性值
      set: 回调函数,监视当前属性值的变化,更新其它相关的属性值
    */
  Object.defineProperty(obj, 'fullName', {
    get () {
      return this.firstName + "-" + this.lastName
    },
    set (value) {
      const names = value.split('-')
      this.firstName = names[0]
      this.lastName = names[1]
    }
  })
  console.log(obj.fullName) //A-B
  obj.firstName = 'C'
  obj.lastName = 'D'
  console.log(obj.fullName) // C-D
  obj.fullName = 'E-F'
  console.log(obj.firstName,obj.lastName) // E F

  Object.defineProperty(obj, 'fullName2', {
    configurable: false,
    enumerable: true,
    value: 'G-H',
    writable: false
  })
  console.log(obj.fullName2)  // G-H
  obj.fullName2 = 'J-K'
  console.log(obj.fullName2) // G-H

  /*Object.defineProperty(obj, 'fullName2', { //不能重新定义
      configurable: false,
      enumerable: false,
      value: 'G-H',
      writable: true
  })*/

  //4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
  const names = Object.keys(obj)
  console.log(names)

  //5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
  console.log(obj.hasOwnProperty('fullName'), obj.hasOwnProperty('toString'))  // true false

  //6. DocumentFragment: 文档碎片(高效批量更新多个节点)
  // document: 对应显示的页面, 包含n个elment  一旦更新document内部的某个元素界面更新
  // documentFragment: 内存中保存n个element的容器对象(不与界面关联), 如果更新framgnet中的某个element, 界面不变
  /*
  <ul id="fragment_test">
    <li>test1</li>
    <li>test2</li>
    <li>test3</li>
  </ul>
   */
  const ul = document.getElementById('fragment_test')
  // 1. 创建fragment
  const fragment = document.createDocumentFragment()
  // 2. 取出ul中所有子节点取出保存到fragment
  let child
  while(child=ul.firstChild) { // 一个节点只能有一个父亲
    fragment.appendChild(child)  // 先将child从ul中移除, 添加为fragment子节点
  }

  // 3. 更新fragment中所有li的文本
  Array.prototype.slice.call(fragment.childNodes).forEach(node => {
    if (node.nodeType===1) { // 元素节点 <li>
      node.textContent = 'atguigu'
    }
  })

  // 4. 将fragment插入ul
  ul.appendChild(fragment)

</script>
</body>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值