<script>
  function linkedList() {
    // 内部的类,节点类
    function Node(data) {
      this.data = data;
      this.next = null;
    }
    // 属性
    this.head = null;
    this.length = 0;

    // 追加方法
    linkedList.prototype.append = function(data) {
      // 创建一个新的节点
      var newNode = new Node(data);
      // 判断链表是否为空
      if (this.length === 0) {
        // 将头结点指向新增节点
        this.head = newNode;
      } else {
        // 找到最后一个节点
        var current = this.head;
        // 如果单前节点的下一个节点不为空
        while (current.next) {
          current = current.next;
        }
        // 将最后一个节点的next指向新增的节点
        current.next = newNode;
      }

      //   链表长度+1
      this.length += 1;
    };

    // toString方法
    linkedList.prototype.toString = function() {
      // 定义变量
      var current = this.head;
      var listString = "";

      // 循环获取一个个节点
      while (current) {
        listString += current.data + " ";
        current = current.next;
      }

      return listString;
    };

    // insert方法
    linkedList.prototype.insert = function(position, data) {
      // 对position进行越界判断
      if (position < 0 || position > this.length) return false;

      // 根据data创建节点
      var newNode = new Node(data);

      // 判断插入的是否是第一个节点
      if (position === 0) {
        newNode.next = this.head;
        this.head = newNode;
      } else {
        var current = this.head;
        var index = 0;
        var previous = null;
        // console.log(current.next.data)
        while (index++ < position) {
          previous = current;
          current = current.next;
        }
        newNode.next = current;
        previous.next = newNode;
      }
      this.length += 1;
      return true;
    };

    // 4.get方法
    linkedList.prototype.get = function(position) {
      // 越界判断
      if (position < 0 || position >= this.length) return false;

      // 获取对应的数据
      var current = this.head;
      var index = 0;
      while (index++ < position) {
        current = current.next;
      }
      return current.data;
    };

    // 5.indexOf方法
    linkedList.prototype.indexOf = function(data) {
      // 1.定义变量
      var current = this.head;
      var index = 0;

      // 开始查找
      while (current) {
        if (current.data === data) {
          return index;
        }
        current = current.next;
        index += 1;
      }
      // 找到最后都没有找到,返回-1
      return -1;
    };

    // update 方法
    linkedList.prototype.update = function(position, data) {
      // 越界判断
      if (position < 0 || position >= this.length) return false;

      // 更新数据
      var current = this.head;
      var index = 0;
      while (index++ < position) {
        current = current.next;
      }
      // 将position位置的data改为新的data
      current.data = data;
      return true;
    };

    // removeAt 方法
    linkedList.prototype.removeAt = function(position) {
      // 越界判断
      if (position < 0 || position >= this.length) return null;


      var current = this.head;

      // 判断是否是第一个位置
      if (position === 0) {
        this.head = this.head.next;
      } else {
        // 删除指定位置的数据
        var previous = null;
        var index = 0;
        while (index++ < position) {
          previous = current;
          current = current.next;
        }
        previous.next = current.next;
      }
      this.length -= 1;
      // 返回删除的数据
      return current.data;
    };

    // 8.remove 方法
    linkedList.prototype.remove = function(data) {
      // 根据data获取data在列表中的位置
      var position = this.indexOf(data)

      // 根据位置信息删除节点
      return this.removeAt(position)
    };

    // 9.isEmpty 方法
    linkedList.prototype.isEmpty = function() {
      return this.length == 0
    } 

    // 10.size 方法
    linkedList.prototype.size = function() {
      return this.length
    }
  }

  //   测试代码
  // 创建linkedList
  var list = new linkedList();
  // 测试append方法
  list.append("abc");
  list.append("编辑");
  list.append("fajl");
  console.log(list.toString());
</script>