zoukankan      html  css  js  c++  java
  • (尚046)Vue_源码分析_准备1+(尚047)Vue_源码分析_准备2+(尚048)Vue_源码分析_准备3

    查找各种方法上MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/
     
    准备知识:
    1) [].slice.call(lis): 将伪数组转换为真数组
    伪数组不是数组,是个对象;只是对象特性有length属性;还有下标属性(说白了,可以通过下标取对应的属性值);
    const lis = document.getElementsByTagName('li') // lis是伪数组(是一个特别的对象, length和数值下标属性)
    console.log(lis instanceof Array,lis[1].innerHTML,lis.forEach) //false instanceof Array用来验证是否是数组 //lis[1].innerHTML 取第二个li文本内容
    //lis.forEach为undifined
    //关键是我就想通过li,遍历整个数组
    //call让一个函数Array.prototype.slice成为指定方法的调用
    const lis2=Array.prototype.slice.call(lis)
    console.log(lis2 instanceof Array,lis2[1].innerHTML,lis2.forEach)//true 'test2' function

    2) node.nodeType: 得到节点类型

    //节点是一个抽象的说法
    //节点有很多类型:(节点从大到小排)
    //1).最大的节点是?document(文档节点)(指整个html页面)
    //2).Element(元素节点)
    //3.1).Attribute(属性节点)
    //3.2).Text(文本节点)
    const elementNode=document.getElementById('test')//文档节点
    const attrNode=elementNode.getAttributeNode('id')//元素节点
    const textNode=elementNode.firstChild //.firstChild返回文档的首个子节点
    console.log(elementNode,attrNode,textNode)
    console.log(elementNode.nodeType,attrNode.nodeType,textNode.nodeType)

    nodeType 属性返回以数字值返回指定节点的节点类型。

    如果节点是元素节点,则 nodeType 属性将返回 1。

    如果节点是属性节点,则 nodeType 属性将返回 2。

    如果节点是文本节点,则nodeType属性返回的值是3.

     
    3) Object.defineProperty(obj, propName, {}): 给对象添加/修改属性(指定描述符)
    configurable: true/false 是否可以重新 define
    enumerable: true/false 是否可以枚举(for..in / keys())
    value: 指定初始值
    writable: true/false value 是否可以修改
    get: 回调函数, 用来得到当前属性值
    set: 回调函数, 用来监视当前属性值的变化
    const obj={
    firstName:'A',
    lastName:'B'
    }
    //给obj添加fullName属性
    //平时使用方式obj.fullName='A-B' 但是当firstName变化时,fullName不会自动变化,故采用以下方式:
    /**
    * (整体都叫)属性描述符:
    * 1)数据描述符
    * configurable:是否可以重新定义false为不可重新定义
    * enumerable:是否可以枚举(遍历查找出所有的值)
    * value:指定初始值
    * writable:是否可以修改属性值
    * 2)访问描述符
    * get:根据其他相关的属性动态计算得到当前属性值,类型:回调函数
    * set:监视当前属性值的变化,更新其他相关的属性值,类型:回调函数
    */
    //'fullName'的相关属性是firstName和lastName
    //注意:IE8不支持Object.defineProperty,说明vue不支持IE8
       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)
    obj.fullName2='J-K'
    console.log(obj.fullName2)
    /* 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) //为什么没有fullName??enumerable默认为false
    5) DocumentFragment: 文档碎片(高效批量更新多个节点)
     
    const ul=document.getElementById('fragment_test')
    //1.创建fragment
    const fragment=document.createDocumentFragment()
    //2.取出url中所有子节点取出保存到fragment
    let child
    while(child=ul.firstChild){//先取出ul的第一个孩子,文本的换行节点 <ul id="fragment_test"> 换行节点 <li>test1</li> 赋值给child
    //换行也是一个文本数据
    //接着判断child为不为真?为真;不加fragmentd.appendChild(child)为一个死循环
    //注意:一个节点只能有一个父亲;换行节点的父亲为ul,现在将其放入了fragment,也就是说现在换行节点的父亲成了fragment
    //也就是说将换行节点的父亲从ul中拿出来,即:移除
    //.appendChild()先将child从ul中移除,添加为fragment子节点
    fragment.appendChild(child)
    }

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

    //4.将fragment插入ul //但是fragment本身是不会进入页面的,因为他不对应任何标签,但我内部保存了很多标签,相当于把我内部标签塞到了ul里
    ul.appendChild(fragment)
    6) obj.hasOwnProperty(prop): 判断 prop 是否是 obj 自身的属性
    //document:对应显示的界面,包含n个element  一旦更新document内部的某个元素界面更新
    // DocumentFragment: 内部中保存n个element的容器对象(不与界面关联),如果更新feamgnent中的某个element,界面不变
    console.log(obj.hasOwnProperty('fullName'),obj.hasOwnProperty('toString'))   //true  false

     将多次更新更改为一次批量更新;

    最终减少更新界面的次数

  • 相关阅读:
    可视化svg深入理解viewport、viewbox、preserveaspectradio
    async generator promise异步方案实际运用
    JavaScript中面相对象OOP
    css3:神秘的弹性盒子flexbox
    JavaScript:我总结的数组API
    CSS3:过渡大全
    CSS3奇特的渐变示例
    缓存:前端页面缓存、服务器缓存(依赖SQL)MVC3
    nohup
    video和audio
  • 原文地址:https://www.cnblogs.com/curedfisher/p/12291246.html
Copyright © 2011-2022 走看看