不忘初心,不负韶华,砥砺前行!
Pages: 1/295 First page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Next page Final page [ View by Articles | List ]
Jul 31
遇到vue一直报错assigning to rvalue解决,一直以为是js代码的问题,后面找了很久的原因,才发现是在html的模板中v-model绑定的属性并没有在data属性中定义

v-model绑定错误引起
Jul 31
xml字符串和对象转换
xml string转xmlobject


xml object转string


js操作xml对象方法和属性集合

节点对象属性

childNodes—返回节点到子节点的节点列表

firstChild—返回节点的首个子节点。
lastChild—返回节点的最后一个子节点。

nextSibling—返回节点之后紧跟的同级节点。

nodeName—返回节点的名字,根据其类型。
nodeType—返回节点的类型。
nodeValue—设置或返回节点的值,根据其类型。

ownerDocument—返回节点的根元素(document对象)。

parentNode—返回节点的父节点。

previousSibling—返回节点之前紧跟的同级节点。

text—返回节点及其后代的文本(IE独有)。

xml—返回节点及其后代的XML(IE独有)。

节点对象的方法

appendChild()—向节点的子节点列表的结尾添加新的子节点。

cloneNode()—复制节点。

hasChildNodes()—判断当前节点是否拥有子节点。

insertBefore()—在指定的子节点前插入新的子节点。

normalize()—合并相邻的Text节点并删除空的Text节点。

removeChild()—删除(并返回)当前节点的指定子节点。

replaceChild()—用新节点替换一个子节点。

IE6独有

selectNodes()—用一个XPath表达式查询选择节点。

selectSingleNode()—查找和XPath查询匹配的一个节点。

transformNode()—使用XSLT把一个节点转换为一个字符串。

transformNodeToObject()—使用XSLT把一个节点转换成为一个文档。

NodeList对象

length –返回节点列表中的节点数目。

item()—返回节点列表中处于指定的索引号的节点。

例如:

Javascript代码

输出:title element:4

Javascript代码

输出:book

NamedNodeMap对象

length—返回列表中节点数目。

getNamedItem()—返回指定的节点。(通过名称)

item()—返回处于指定索引号的节点。

removeNamedItem()—删除指定的节点(根据名称)。

例如:

Javascript代码

输出:1

Javascript代码

输出:COOKING
Javascript代码

x.item(0).attributes.removeNamedItem(“category”);
删除第一个book元素的category属性

Document对象代表整个XML文档。

Document对象的属性。

async—规定XML文件的下载是否应当被同步处理。

childNodes—返回属于文档的子节点的节点列表。

doctype—返回与文档相关的文档类型声明。

documentElement—返回文档的子节点。

firstChild—返回文档的首个子节点。

implementation—返回处理该文档的DOMImplementation对象。(IE没有)

lastChild—返回文档的最后一个子节点。

nodeType—返回节点类型。

nodeName—依据节点的类型返回其名称。

nodeValue—依据节点的类型返回其值。

text—返回节点及其后代的文本(IE独有)。

xml—返回节点及其后代的XML(IE独有)。

Document对象的方法

createAttribute(att_name)—创建拥有指定名称的属性节点,并返回新的属性对象。
createCDATASection(data)—创建CDATA区段节点。
createComment(data)—创建注释节点。
createDocumentFragment—创建空的DocumentFragment对象,并返回此对象。
createElement(node_name)—创建元素节点。
createEntityReference(name)—创建EntityReference对象,并返回此对象。(IE独有)
createTextNode(data)—创建文本节点。
getElementById(elementid)—查找具有指定的唯一ID的元素。
getElementsByTagName(node_name)—返回所有具有指定名称的元素节点。

例如:

Javascript代码


Element 对象的属性

attributes—返回元素的属性的NamedNodeMap
childNodes—返回元素的子节点的NodeList
firstChild—返回元素的首个子节点。
lastChild—返回元素的最后一个子节点。
nextSibling—返回元素之后紧跟的节点。
nodeName—返回节点的名称。
nodeType—返回元素的类型。
ownerDocument—返回元素所属的根元素(document对象)。
parentNode—返回元素的父节点。
previousSibling—返回元素之前紧跟的节点。
tagName—返回元素的名称。
text—返回节点及其后代的文本。(IE-only)
xml—返回节点及其后代得XML。(IE-only)

Element对象的方法

appendChild(node)—向节点的子节点列表末尾添加新的子节点。
cloneNode(true)—克隆节点。
getAttribute(att_name)—返回属性的值。
getAttributeNode(att_name)—以 Attribute 对象返回属性节点。
getElementsByTagName(node_name)—找到具有指定标签名的子孙元素。
hasAttribute(att_name)—返回元素是否拥有指定的属性。
hasAttributes()—返回元素是否拥有属性。
hasChildNodes()—返回元素是否拥有子节点。
insertBefore(new_node,existing_node)—在已有的子节点之前插入一新的子节点。
removeAttribute(att_name)—删除指定的属性。
removeAttributeNode(att_node)—删除指定的属性节点。
removeChild(node)—删除子节点。
replaceChild(new_node,old_node)—替换子节点。
setAttribute(name,value)—添加新的属性或者改变属性的值。
setAttribute(att_node)—添加新的属性。

Javascript代码
Jul 28
保存为扩展名.reg的注册表文件后,双击导入注册表即可



Jun 22
https://www.npmjs.com/package/px2rem
https://www.npmjs.com/package/postcss-px-to-viewport
Jun 21

 各位读者好,我最近在 Github 上面发起了一个 JavaScript 算法和数据结构 的仓库,里面有经典算法的集合,还有带有解释的以及进一步阅读的文章链接和 YouTube 的链接的用 JavaScript ES6 实现的数据结构。也有 算法和数据结构 的 YouTube 的播放列表,包含了所有在仓库中提到的视频,你或许会很方便地点击链接就进入课程学习了:)

因此我猜想你已经掌握了项目的主要理念 - 帮助开发者学习和练习算法并且通过 JavaScript 实现。

为了让这个过程更顺畅,我试着为每一个算法和数据结构放了图解的插画,有助于掌握和记住那些算法背后的原理。

你或许在根 README 文件里面发现一些实践的信息,你学习的时候会很方便。一些例如这样的信息:

        
  • 大 O 记号图 - 快速查看哪些算法是最糟的 O(n!) 或者 O(n²)
  •     
  • 一些最常用的大 O 记号列表和它们的性能比较 - 理解 10! 有多大(是 3628800)
  •     
  • 数据结构操作的复杂性 - 为不同的数据结构搜索,读取,插入有多快
  •     
  • 排序算法复杂度的比较表 - 帮助你根据实际情况选择更合适的排序算法。

所有的代码都有 100% 的测试覆盖率。这样做不仅保障了代码能够正确的运行,也给了一个每一个算法和数据结构是如何工作的说明,它们都有哪些基础的操作(假设轮询堆)和边界情况是什么(如果图是有向做什么)。

仓库也有一个训练场(playground)。这仅仅是一个带有空测试案例的小函数模板,在你克隆这个仓库后帮助你开始测试或者运行算法。

当前涵盖有以下数据结构

        
  • 链表(Linked List)
  •     
  • 队列(Queue)
  •     
  • 栈(Stack)
  •     
  • 哈希表(Hash Table)
  •     
  • 堆(Heap)
  •     
  • 优先队列(Priority Queue)
  •     
  • 前缀树/字典树(Trie)
  •     
  • 树(二叉查找树,平衡二叉树)(Tree Binary Search Tree,AVL Tree)
  •     
  • 图(有向和无向)(Graph both dirented and undirected)
  •     
  • 分离集(Disjoint Set)

最重要的是数据结构有超过 50 个流行算法实现。有 排序,查找算法,图/树/集合/字符串/数学 相关的算法。所有的算法也会按照他们的模式归类:

        
  • 暴力破解算法(Brute Force Algorithms) - 查看所有的可能性和选择最好的方案。
  •     
  • 贪婪算法(Greedy Algorithms) - 在当前时间做最好的选择,不用为未来考虑。
  •     
  • 分而治之算法(Divide and Conquer Algorithms) - 将问题分为更小的部分,然后解决它们。
  •     
  • 动态规划算法(Dynamic Programming Algorithms) - 根据之前发现的小解决方案构建一个解决方案。
  •     
  • 回溯算法(Backtracking Algorithms) - 类似于暴力破解,尝试生成所有可能的解决方案,但是每次生成一个解决方案测试是否满足所有的条件,再产生后续的解决方案。否则回溯,然后从不同的路径开始寻找解决方案。

JavaScript 算法和数据结构 仓库仍在开发状态,后面还有更多的算法和数据结构。你可以贡献你的代码为仓库的一部分,也可以是一些众所周知的算法的实现!

希望这个仓库对你有帮助!享受编程吧!

Jun 21
链表和数组
大家都用过js中的数组,数组其实是一种线性表的顺序存储结构,它的特点是用一组地址连续的存储单元依次存储数据元素。而它的缺点也正是其特点而造成,比如对数组做删除或者插入的时候,可能需要移动大量的元素。

这里大致模拟一下数组的插入操作:

    function insert(arr, index, data) {
      for (let i = arr.length; i >index; i--) {
        arr[i] = arr[i - 1];
      }
      arr[index] = data;
    }
从上面的代码可以看出数组的插入以及删除都有可能会是一个O(n)的操作。从而就引出了链表这种数据结构,链表不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所具有的缺点,当然它也失去了数组在一块连续空间内随机存取的优点。

单向链表
图片描述

单向链表的特点:
用一组任意的内存空间去存储数据元素(这里的内存空间可以是连续的,也可以是不连续的)
每个节点(node)都由数据本身和一个指向后续节点的指针组成
整个链表的存取必须从头指针开始,头指针指向第一个节点
最后一个节点的指针指向空(NULL)
链表中的几个主要操作
创建节点
插入节点
搜索/遍历节点
删除节点
合并
初始化节点
指针指向空
存储数据
    class Node {
        constructor(key) {
            this.next = null;
            this.key = key;
        }
    }
初始化单向链表
每个链表都有一个头指针,指向第一个节点,没节点则指向NULL
    class List {
        constructor() {
            this.head = null;
        }
    }
创建节点
    static createNode(key) {
        return new createNode(key);
    }
这里说明一下,这一块我是向外暴露了一个静态方法来创建节点,而并非直接把它封装进插入操作里去,因为我感觉这样的逻辑会更加正确一些。 从创建一个链表 -> 创建一个节点 -> 将节点插入进链表中。可能你会遇到一些文章介绍的方式是直接将一个数据作为参数去调用insert操作,在insert内部做了一个创建节点。

插入节点(插入到头节点之后)
插入操作只需要去调整节点的指针即可,两种情况:

head没有指向任何节点,说明当前插入的节点是第一个

head指向新节点
新节点的指针指向NULL
head有指向的节点

head指向新的节点
新节点的指针指向原本head所指向的节点
    insert(node) {
        // 如果head有指向的节点
        if(this.head){
           node.next = this.head;
        }else {
           node.next = null;
        }
        this.head = node;
    }
搜索节点
从head开始查找
找到节点中的key等于想要查找的key的时候,返回该节点
    find(key) {
        let node = this.head;
        while(node !== null && node.key !== key){
            node = node.next;
        }
        return node;
    }
删除节点
这里分三种情况:

所要删除的节点刚好是第一个,也就是head指向的节点

将head指向所要删除节点的下一个节点(node.next)
要删除的节点为最后一个节点

寻找到所要删除节点的上一个节点(prevNode)
将prevNode中的指针指向NULL
在列表中间删除某个节点

寻找到所要删除节点的上一个节点(prevNode)
将prevNode中的指针指向当前要删除的这个节点的下一个节点
    delete(node) {
        // 第一种情况
        if(node === this.head){
            this.head = node.next;
            return;
        }
        
        // 查找所要删除节点的上一个节点
        let prevNode = this.head;
        while (prevNode.next !== node) {
            prevNode = prevNode.next;
        }
        
        // 第二种情况
        if(node.next === null) {
            prevNode.next = null;
        }
        
        // 第三种情况
        if(node.next) {
            prevNode.next = node.next;
        }
    }
单向链表整体的代码
class ListNode {
  constructor(key) {
    this.next = null;
    this.key = key;
  }
}

class List {
  constructor() {
    this.head = null;
    this.length = 0;
  }

  static createNode(key) {
    return new ListNode(key);
  }

  // 往头部插入数据
  insert(node) {
    // 如果head后面有指向的节点
    if (this.head) {
      node.next = this.head;
    } else {
      node.next = null;
    }
    this.head = node;
    this.length++;
  }

  find(key) {
    let node = this.head;
    while (node !== null && node.key !== key) {
      node = node.next;
    }
    return node;
  }

  delete(node) {
    if (this.length === 0) {
      throw 'node is undefined';
    }

    if (node === this.head) {
      this.head = node.next;
      this.length--;
      return;
    }

    let prevNode = this.head;

    while (prevNode.next !== node) {
      prevNode = prevNode.next;
    }

    if (node.next === null) {
      prevNode.next = null;
    }
    if (node.next) {
      prevNode.next = node.next;
    }
    this.length--;
  }
}
双向链表
如果你把上面介绍的单向列表都看明白了,那么这里介绍的双向列表其实差不多。

图片描述

图片描述

从上面的图可以很清楚的看到双向链表和单向链表的区别。双向链表多了一个指向上一个节点的指针。

初始化节点
指向前一个节点的指针
指向后一个节点的指针
节点数据
    class ListNode {
        this.prev = null;
        this.next = null;
        this.key = key;
    }
初始化双向链表
头指针指向NULL
    class List {
        constructor(){
            this.head = null;
        }
    }
创建节点
    static createNode(key){
        return new ListNode(key);
    }
插入节点((插入到头节点之后)
看上图中head后面的第一个节点可以知道,该节点的prev指向NULL
节点的next指针指向后一个节点, 也就是当前头指针所指向的那个节点
如果head后有节点,那么原本head后的节点的prev指向新插入的这个节点(因为是双向的嘛)
最后将head指向新的节点
    insert(node) {
        node.prev = null;
        node.next = this.head;
        if(this.head){
            this.head.prev = node;
        }
        this.head = node;
    }
搜索节点
这里和单向节点一样,就直接贴代码了

  search(key) {
    let node = this.head;
    while (node !== null && node.key !== key) {
      node = node.next;
    }
    return node;
  }
删除节点
和之前单向链表一样,分三种情况去看:

删除的是第一个节点

head指向所要删除节点的下一个节点
下一个节点的prev指针指向所要删除节点的上一个节点
删除的是中间的某个节点

所要删除的前一个节点的next指向所要删除的下一个节点
所要删除的下一个节点的prev指向所要删除的前一个节点
删除的是最后一个节点

要删除的节点的上一个节点的next指向null(也就是指向删除节点的next所指的地址)
图片描述

    delete(node) {
        const {prev,next} = node;
        delete node.prev;
        delete node.next;
        if(node === this.head){
            this.head = next;
        }
        if(next){
            next.prev = prev;
        }
        if(prev){
            prev.next = next;
        }
    }
双向链表整体代码
    class ListNode {
  constructor(key) {
    // 指向前一个节点
    this.prev = null;
    // 指向后一个节点
    this.next = null;
    // 节点的数据(或者用于查找的键)
    this.key = key;
  }
}

/**
* 双向链表
*/
class List {
  constructor() {
    this.head = null;
  }

  static createNode(key) {
    return new ListNode(key);
  }

  insert(node) {
    node.prev = null;
    node.next = this.head;
    if (this.head) {
      this.head.prev = node;
    }
    this.head = node;
  }

  search(key) {
    let node = this.head;
    while (node !== null && node.key !== key) {
      node = node.next;
    }
    return node;
  }

  delete(node) {
    const { prev, next } = node;
    delete node.prev;
    delete node.next;

    if (node === this.head) {
      this.head = next;
    }

    if (prev) {
      prev.next = next;
    }
    if (next) {
      next.prev = prev;
    }
  }
}
总结
这里做一个小总结吧,可能有一部分人读到这里还不是特别的明白,我的建议是先好好看懂上面的单向链表。 其实只要你明白了链表的基础概念,就是有一个head,然后在有好多的节点(Node),然后用一个指针把他们串起来就好了,至于里面的插入操作也好,删除也好,其实都是在调整节点中指针的指向。
Jun 20
https://graphql.cn/
Quotation
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。


使用GraphQL的理由
Quotation

数据冗余和请求冗余 (overfetching & underfetching)
灵活而强类型的schema
接口校验 (validation)
接口变动,维护与文档
开发效率



问题
Quotation

迁移成本
牺牲Performance
缺乏动态类型
简单问题复杂化
缓存能解决很多问题


项目
https://github.com/graphql/graphql-js/
https://github.com/graphql/express-graphql
https://github.com/apollographql/apollo-server
Pages: 1/295 First page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Next page Final page [ View by Articles | List ]