vuejs / Discussion

Vue.js discussion
167 stars 17 forks source link

Got "TypeError: this._props is undefined" when adding a function to the Object.prototype #378

Closed Haixing-Hu closed 9 years ago

Haixing-Hu commented 9 years ago

The test code is as follows:

<!DOCTYPE html>
<html lang="en" class="fixed-footer" id="app">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta charset="utf-8">
  <title>Test</title>
</head>
<body>
  <div id="app">
    <span>{{message}}</span>
  </div>
  <script type="text/javascript" src="lib/vue/dist/vue.js"></script>
  <script>
    Object.prototype.test = function() {
      console.debug("Test");
    };
    var v = new Vue({
      el: "#app",
      data: {
        message: "Hello World."
      }
    });
  </script>
</body>
</html>

When loading this page in the browser, I got the following error message:

TypeError: this._props is undefined vue.js:8171:0

If I comment the definitnion of Object.prototype.test, the error disappeared.

But in my project, I have a third part library which add some functions to the Object.prototype.

Haixing-Hu commented 9 years ago

I looked into the source code of Vue, and found that the error occurs in the following function at the line 50 of vue/src/instance/scope.js:

exports._initData = function () {
  var propsData = this._data
  var optionsDataFn = this.$options.data
  var optionsData = optionsDataFn && optionsDataFn()
  if (optionsData) {
    this._data = optionsData
    for (var prop in propsData) {
      if (
        this._props[prop].raw !== null ||                //  HERE
        !optionsData.hasOwnProperty(prop)
      ) {
        optionsData.$set(prop, propsData[prop])
      }
    }
  }
  var data = this._data
  // proxy data on instance
  var keys = Object.keys(data)
  var i, key
  i = keys.length
  while (i--) {
    key = keys[i]
    if (!_.isReserved(key)) {
      this._proxy(key)
    }
  }
  // observe data
  Observer.create(data, this)
}

It seems that there are the following problems:

In fact I cannot understand the function of the for loop. If I comment it, the Vue still works without any error.

@yyx990803, could you please explain the function of the for prop in propsData loop? Thank you in advance.

yyx990803 commented 9 years ago

You should never, ever add an enumerable property to Object.prototype. It'll break any code that uses the for...in loop.

Haixing-Hu commented 9 years ago

@yyx990803 , My project use a third part library which defines some function to Object.prototype. And I think the for..in loop should work together with the Object.hasOwnProperty() function to overcome the problem.