--- title: Adding Instance Properties type: cookbook order: 2 --- ## Base Example There may be data/utilities you'd like to use in many components, but you don't want to [pollute the global scope](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md). In these cases, you can make them available to each Vue instance by defining them on the prototype: ```js Vue.prototype.$appName = 'My App' ``` Now `$appName` is available on all Vue instances, even before creation. If we run: ```js new Vue({ beforeCreate: function() { console.log(this.$appName) } }) ``` Then `"My App"` will be logged to the console! ## The Importance of Scoping Instance Properties You may be wondering: > "Why does `appName` start with `$`? Is that important? What does it do? No magic is happening here. `$` is a convention Vue uses for properties that are available to all instances. This avoids conflicts with any defined data, computed properties, or methods. > "Conflicts? What do you mean?" Another great question! If you set: ```js Vue.prototype.appName = 'My App' ``` Then what would you expect to be logged below? ```js new Vue({ data: { // Uh oh - appName is *also* the name of the // instance property we defined! appName: 'The name of some other app' }, beforeCreate: function() { console.log(this.appName) }, created: function() { console.log(this.appName) } }) ``` It would be `"My App"`, then `"The name of some other app"`, because `this.appName` is overwritten ([sort of](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch5.md)) by `data` when the instance is created. We scope instance properties with `$` to avoid this. You can even use your own convention if you'd like, such as `$_appName` or `ΩappName`, to prevent even conflicts with plugins or future features. ## Real-World Example: Replacing Vue Resource with Axios Let's say you're replacing the [now-retired Vue Resource](https://medium.com/the-vue-point/retiring-vue-resource-871a82880af4). You really enjoyed accessing request methods through `this.$http` and you want to do the same thing with Axios instead. All you have to do is include axios in your project: ```html
If you raised an eyebrow at `Object.freeze`, what it does is prevent the object from being changed in the future. This essentially makes all its properties constants, protecting you from future state bugs.
Now the source of these shared properties is more obvious: there's an `App` object defined somewhere in the app. To find it, developers can run a project-wide search. Another advantage is that `App` can now be used _anywhere_ in your code, whether it's Vue-related or not. That includes attaching values directly to instance options, rather than having to enter a function to access properties on `this`: ```js new Vue({ data: { appVersion: App.version }, methods: { reverseText: App.helpers.reverseText } }) ``` ### When Using a Module System When you have access to a module system, you can easily organize shared code into modules, then `require`/`import` those modules wherever they're needed. This is the epitome of explicitness, because in each file you gain a list of dependencies. You know _exactly_ where each one came from. While certainly more verbose, this approach is definitely the most maintainable, especially when working with other developers and/or building a large app.