Cause of the matter

When writing a project, I want to use Map to iterate. Then I get the Map keys. Keys is a Map Iterator. And of course my expectation is to be able to iterate. We all know that Vue’s V-for provides two traversal modes,

v-for="item in items"
v-for="item of items"
Copy the code

It can be used in JS

for (index in items)
for// This notation supports iterator traversalCopy the code

At this point, I couldn’t help thinking that the traversal mode of OF in V-for should support iterator traversal, but the fact is that it can’t be tried, so why not, so I went to the source code of Vue, found such a code.

/**
 * Runtime helper for rendering v-for lists.
 */
function renderList (
  val,
  render
) {
  var ret, i, l, keys, key
  if (Array.isArray(val) || typeof val === 'string') {
    ret = new Array(val.length)
    for (i = 0, l = val.length; i < l; i++) {
      ret[i] = render(val[i], i)
    }
  } else if (typeof val === 'number') {
    ret = new Array(val)
    for (i = 0; i < val; i++) {
      ret[i] = render(i + 1, i)
    }
  } else if (isObject(val)) {
    keys = Object.keys(val)
    ret = new Array(keys.length)
    for (i = 0, l = keys.length; i < l; i++) {
      key = keys[i]
      ret[i] = render(val[key], key, i)
    }
  }
  if (isDef(ret)) {
    (ret)._isVList = true
  }
  return ret
}
Copy the code

Keys (val) of the Map Iterator is an empty Object [], an empty keys, so there is no iterate and render.

The beginning of death

Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator

. }else if (isObject(val)) {
    keys = Object.keys(val)
    if (keys.length === 0 && val.toString().indexOf('Iterator') > -1) {// May be an iterator ret = [] I = 0while (true) {
        if(typeof val.next ! = ='function') {
          break
        }
        var next = val.next()
        if (next.done) {
          break
        }
        ret.push(render(next.value, i++))
      }
    } else {
      ret = new Array(keys.length)
      for (i = 0, l = keys.length; i < l; i++) {
        key = keys[i]
        ret[i] = render(val[key], key, i)
      }
    }
  }
 ...
Copy the code

One method of the Symbol type is symbbol.toStringTag

Symol.toStringTag

A string value for the default description of an Object. Used by

Object.prototype.toString()

If the Iterator is an Iterator, then the Iterator is an Iterator. If the Iterator is an Iterator, the Iterator is an Iterator. If the Iterator is an Iterator, the Iterator is an Iterator. Here we use while but not for… Writing of, I dare not try writing ES5+ since I am modifying the file dist. Then everything looks perfect, but runs to handleError(e, VM, “render”), an ERROR branch… Scratching my head… After N rounds of debugging, I finally located the problem. Since the test was done based on the project, the project used ElementUI, which used the Form component. Layer upon layer, we found that the Error was caused by the null value of the V-Model, and then wrote a simple V-for to find that it actually worked.

template...
<div v-for="item of iterator">
  {{item}}
</div>
script...
data () {
  return {
    iterator: this.getIterator()
  }
},
methods: {
  getIterator () {
    let map = new Map()
    map.set('title'.' ')
    map.set('value'.' ')
    return map.keys()
  }
}
output...
title
value
Copy the code

conclusion

Although I did an ES5+ attempt on Vue, I don’t know if it is reasonable, but I learned a lot in the process of exploration, I hope it can be helpful to you. Which understand the Symbol type is what type, understand the implementation of the iterator, practice the problem of locating breakpoints and so on… A night to pay not in vain, or more pleased.

End

I’m a coder who wants to grow