<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Phillips</title>
    <description>The latest articles on DEV Community by Kevin Phillips (@phillipskevin).</description>
    <link>https://dev.to/phillipskevin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F208051%2Fd7dacb1b-8034-48dc-a885-321f4879b219.jpeg</url>
      <title>DEV Community: Kevin Phillips</title>
      <link>https://dev.to/phillipskevin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phillipskevin"/>
    <language>en</language>
    <item>
      <title>CanJS 6.0: web components, proxy-based observables, new type system
</title>
      <dc:creator>Kevin Phillips</dc:creator>
      <pubDate>Fri, 22 Nov 2019 18:00:16 +0000</pubDate>
      <link>https://dev.to/phillipskevin/canjs-6-0-web-components-proxy-based-observables-new-type-system-41k9</link>
      <guid>https://dev.to/phillipskevin/canjs-6-0-web-components-proxy-based-observables-new-type-system-41k9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is a cross-post from &lt;a href="https://www.bitovi.com/blog/canjs-6.0" rel="noopener noreferrer"&gt;bitovi.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello Web Developers,&lt;/p&gt;

&lt;p&gt;Today we are announcing the release of CanJS 6.0. The goal of CanJS is to be the best tool for building data-driven web applications. Building on &lt;a href="https://www.bitovi.com/blog/canjs-4.0" rel="noopener noreferrer"&gt;CanJS 4.0&lt;/a&gt; and &lt;a href="https://www.bitovi.com/blog/canjs-5" rel="noopener noreferrer"&gt;CanJS 5.0&lt;/a&gt;, CanJS 6.0 is designed to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;make it easier to get started creating components&lt;/li&gt;
&lt;li&gt;make observables behave more like normal objects and arrays&lt;/li&gt;
&lt;li&gt;make it easier to scale your code to larger applications and more complex use-cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CanJS 6.0 is built around web components - use CanJS to build custom elements that work natively in modern web browsers. CanJS’s &lt;code&gt;StacheElement&lt;/code&gt; greatly simplifies the APIs the browser gives you for creating custom elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyCounter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
        Count: &amp;lt;span&amp;gt;{{ this.count }}&amp;lt;/span&amp;gt;
        &amp;lt;button on:click="this.increment()"&amp;gt;+1&amp;lt;/button&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyCounter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Interested in trying this out yourself. Use this &lt;a href="https://codepen.io/bitovi/pen/XWWQWpL?editors=0010" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The foundation of CanJS is key-value observables that allow your application to efficiently react to changes, keep data in sync with your API layer, and re-render exactly the HTML that needs to be updated when something changes.&lt;/p&gt;

&lt;p&gt;Like previous versions of CanJS, 6.0 has a rich API for defining how the properties of your components and observables should behave. We’ve taken this a step further in 6.0 by making our observables based on classes with an even easier syntax for specifying type information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Along with simplified observables, the type system in CanJS 6.0 has been completely overhauled. It is now easier than ever to add type information to your observables. Types are strict by default, which means that if a property is set to the wrong type, an error will be thrown so you can fix issues in your application before your users ever see them. CanJS also provides the flexibility to use non-strict types so that you can ensure a value is always converted to the correct type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As always, types in CanJS can be used without the overhead of setting up a compiler or external type system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, get your snacks, let’s walk through the new features and how they can simplify your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Components
&lt;/h2&gt;

&lt;p&gt;CanJS has been promoting a component architecture since &lt;a href="https://github.com/canjs/canjs/issues/327#issuecomment-26154011" rel="noopener noreferrer"&gt;can-component&lt;/a&gt; was introduced in CanJS 2.0.0 (in 2013!), which has continued to evolve since then. Today, modern web browsers have native support for what we think of as components through the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements" rel="noopener noreferrer"&gt;custom elements APIs&lt;/a&gt;. In CanJS 6.0, we are providing support for building native custom elements through &lt;code&gt;StacheElement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Moving to native web components provides enormous benefits to the development process and makes it easier than ever to build your application out of small, independent components.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript classes
&lt;/h3&gt;

&lt;p&gt;StacheElement is built on JavaScript classes. While classes are new to lots of JavaScript developers, they are a native feature of the language. This means there are blog posts, videos, and many other resources that developers can use to learn how to use them.&lt;/p&gt;

&lt;p&gt;Using classes removes the need for the custom inheritance system that enabled &lt;a href="https://canjs.com/doc/can-component.extend.html" rel="noopener noreferrer"&gt;Component.extend({ … })&lt;/a&gt; and makes it easier for developers to get started with CanJS since they no longer need this framework-specific knowledge.&lt;/p&gt;

&lt;p&gt;To create a component using StacheElement, just create a class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyThing&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{{ this.greeting }} World`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Observable element properties
&lt;/h3&gt;

&lt;p&gt;A design goal of StacheElement was to make elements work like built-in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction" rel="noopener noreferrer"&gt;DOM&lt;/a&gt; elements. This enables developers to use them in ways they’re already familiar with and with the tools they already use.&lt;/p&gt;

&lt;p&gt;With StacheElement, all of an element’s properties are observable. This means elements can react to property changes just like the elements built in to the browser -- set a property and the view will update if it needs to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F52k312t42zvdcvh3mqb6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F52k312t42zvdcvh3mqb6.gif" alt="change property"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lifecycle methods and hooks
&lt;/h3&gt;

&lt;p&gt;StacheElement also comes with lifecycle hooks that allow you to ensure your code runs at the right time and lifecycle methods that make your components easy to test.&lt;/p&gt;

&lt;p&gt;For example, the following Timer component will increment its &lt;code&gt;time&lt;/code&gt; property once every second. This interval is started in the &lt;code&gt;connected&lt;/code&gt; hook so that the timer will only run when the component is in the page. The &lt;code&gt;connected&lt;/code&gt; hook also returns a teardown function so the interval can be cleared when the component is removed from the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Timer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
        {{ this.time }}
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;connected&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;timerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-timer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three lifecycle methods that can be used to test this component -- &lt;code&gt;initialize&lt;/code&gt;, &lt;code&gt;render&lt;/code&gt;, and &lt;code&gt;connect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// calling `initialize` allows &amp;lt;my-timer&amp;gt;’s properties to be tested&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 5&lt;/span&gt;

&lt;span class="c1"&gt;// calling `render` allows &amp;lt;my-timer&amp;gt;’s view to be tested&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstElementChild&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; &amp;lt;p&amp;gt;0&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// calling `connect` allows &amp;lt;my-timer&amp;gt;’s `connect` logic to be tested&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...some time passes&lt;/span&gt;
&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstElementChild&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; &amp;lt;p&amp;gt;42&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connect attributes and properties
&lt;/h3&gt;

&lt;p&gt;Another design goal of StacheElement was to give developers the flexibility to connect an element’s attributes and properties, similar to how many built-in elements &lt;a href="https://dom.spec.whatwg.org/#concept-reflect" rel="noopener noreferrer"&gt;“reflect”&lt;/a&gt; changes between attributes and properties.&lt;/p&gt;

&lt;p&gt;By default, setting an attribute on a component will not set the property, but the &lt;a href="https://canjs.com/doc/can-observable-bindings/fromAttribute.html" rel="noopener noreferrer"&gt;fromAttribute&lt;/a&gt; binding can be used to set a property whenever an attribute changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa65ikxfy7rim10954hv1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa65ikxfy7rim10954hv1.gif" alt="change attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that if you want to use your component in static HTML or in HTML generated by your backend web application, you can do that. You can even set properties from JSON or another complex data type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-user&lt;/span&gt;
    &lt;span class="na"&gt;user-data=&lt;/span&gt;&lt;span class="s"&gt;'{ "first": "Leonardo", "last": "DiCaprio", "age": 44 }'&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/my-user&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StacheElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
            &amp;lt;form&amp;gt;
                &amp;lt;input value: bind="user.first"&amp;gt;
                &amp;lt;input value: bind="user.last"&amp;gt;
                &amp;lt;input value: bind="user.age" type="number"&amp;gt;
            &amp;lt;/form&amp;gt;
        `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;fromAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user-data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Improved Observables
&lt;/h2&gt;

&lt;p&gt;CanJS 6.0 brings the third generation of CanJS key-value observables — &lt;a href="https://canjs.com/doc/can-observable-object.html" rel="noopener noreferrer"&gt;can-observable-object&lt;/a&gt;. Like &lt;a href="https://canjs.com/doc/can-map.html" rel="noopener noreferrer"&gt;can-map&lt;/a&gt; and &lt;a href="https://canjs.com/doc/can-define/map/map.html" rel="noopener noreferrer"&gt;can-define/map/map&lt;/a&gt; before it, working with &lt;code&gt;ObservableObject&lt;/code&gt; means that you can update your data and the rest of your application will update accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript Proxies
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ObservableObject&lt;/code&gt; was designed to make developing with observables just like developing with normal JavaScript Objects. To make this possible, it is built on a new feature of modern web browsers, the JavaScript &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;. Using proxies means that properties can be added, changed, and removed in all the ways that are possible with Objects and will always remain observable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://canjs.com/doc/can-observable-array.html" rel="noopener noreferrer"&gt;can-observable-array&lt;/a&gt; provides the same benefits when working with arrays of data. Using proxies irons out lots of edge cases, such as the ability to make items in an array observable when they are set using array index notation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyDefineList&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// list[0] is a plain object&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyObservableArray&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// arr[0] is an observable!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JavaScript Classes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ObservableObject&lt;/code&gt; and &lt;code&gt;ObservableArray&lt;/code&gt; are also built on top of JavaScript classes, so you can create an observable for your application by creating your own class constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dealership&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableArray&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tesla&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tesla&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Model S&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toyota&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toyota&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Camry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dealership&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DealerShip&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="nx"&gt;tesla&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;honda&lt;/span&gt; &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Simplified property definitions
&lt;/h3&gt;

&lt;p&gt;Like previous CanJS observables, &lt;code&gt;ObservableObject&lt;/code&gt; and &lt;code&gt;ObservableArray&lt;/code&gt; allow you to specify exactly how the properties of your observables should behave. We’ve made this even easier by simplifying some of the property definitions from &lt;code&gt;can-define&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To learn more about all of the differences in property definitions between &lt;code&gt;can-define&lt;/code&gt; and &lt;code&gt;can-observable-object&lt;/code&gt;, check out the &lt;a href="https://canjs.com/doc/migrate-6.html" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Type constructors
&lt;/h4&gt;

&lt;p&gt;One of the most common ways developers like to define their properties is by giving them types. With &lt;code&gt;ObservableObject&lt;/code&gt;, this is as simple as providing a constructor function (even for built-in constructors):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Asynchronous properties
&lt;/h4&gt;

&lt;p&gt;Another small improvement to property definitions is that asynchronous getters now have their own behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoList&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;todosPromise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;todosPromise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;StacheElement&lt;/code&gt; uses these same observable property behaviors under the hood, all of the benefits of &lt;code&gt;ObservableObject&lt;/code&gt; and &lt;code&gt;ObservableArray&lt;/code&gt; also apply to elements created with CanJS. 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  New Type System
&lt;/h2&gt;

&lt;p&gt;As we saw in the previous section, it is very easy to set the type of a property when using CanJS observables. The type system in CanJS 6 has been greatly improved to allow for strict type checking and much greater flexibility. This flexibility means that you can use more rigorous type checking as your application or requirements grow.&lt;/p&gt;

&lt;p&gt;CanJS 6 supports strict typing by default. This means if you declare a property is a specific type, an error will be thrown if that property is set to a value of a different type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;farah&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;farah&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Uncaught Error: "4" (string) is not of type Number.&lt;/span&gt;
&lt;span class="c1"&gt;// Property age is using "type: Number". Use "age: type.convert(Number)"&lt;/span&gt;
&lt;span class="c1"&gt;// to automatically convert values to Numbers when setting the "age" property.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If strict typing is not the best solution for your application, you can also set up a property to always convert its value to a specific type using &lt;a href="https://canjs.com/doc/can-type/convert.html" rel="noopener noreferrer"&gt;type.convert&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also create &lt;a href="https://en.wikipedia.org/wiki/Maybe_type" rel="noopener noreferrer"&gt;“Maybe types”&lt;/a&gt; that will allow the value to be &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; on top of whatever valid values the type allows. For example &lt;code&gt;type.maybe(Number)&lt;/code&gt; will allow the value to be a &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, or a Number and will throw if set to something else.&lt;/p&gt;

&lt;p&gt;To see all the ways types can be defined, check out the &lt;a href="https://canjs.com/doc/can-type.html" rel="noopener noreferrer"&gt;can-type&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the old APIs?
&lt;/h2&gt;

&lt;p&gt;If you have an existing CanJS application, don’t worry! None of the APIs you’re using today are going away. You can continue to use &lt;code&gt;can-component&lt;/code&gt; and &lt;code&gt;can-define&lt;/code&gt; and update to the new APIs when it makes sense for your application.&lt;/p&gt;

&lt;p&gt;Also, if your application needs to &lt;a href="https://canjs.com/doc/guides/setup.html" rel="noopener noreferrer"&gt;support IE11&lt;/a&gt;, which doesn’t support &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Browser_compatibility" rel="noopener noreferrer"&gt;Proxies&lt;/a&gt;, &lt;code&gt;can-component&lt;/code&gt; and &lt;code&gt;can-define&lt;/code&gt; will continue to be available for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrading
&lt;/h2&gt;

&lt;p&gt;If you do have an existing CanJS application that you are interested in upgrading, check out the &lt;a href="https://canjs.com/doc/migrate-6.html" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt; which will explain all of the changes in depth. Make sure to take a look at the &lt;a href="https://canjs.com/doc/guides/upgrade/using-codemods.html" rel="noopener noreferrer"&gt;Using codemods&lt;/a&gt; guide to automate your upgrade process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;The CanJS core team is going to continue working to make CanJS the best tool to build data-driven web applications. Every bug we fix, change we make, and feature we add is based on &lt;a href="https://www.bitovi.com/community/slack" rel="noopener noreferrer"&gt;talking with the community&lt;/a&gt;, &lt;a href="https://donejs.com/survey.html" rel="noopener noreferrer"&gt;community surveys&lt;/a&gt;, and lots of user testing. Please come join in the conversation and if you’re interested in being a beta tester, please &lt;a href="https://www.surveymonkey.com/r/QPQ2F8P" rel="noopener noreferrer"&gt;fill out this survey&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank You
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CanJS developers around the world building some of the most high-profile, high-performance, and amazing pieces of software on the web. Keep building!&lt;/li&gt;
&lt;li&gt;Contributors big and small to CanJS. Every bug report, feature request, documentation fix, and user test makes CanJS better.&lt;/li&gt;
&lt;li&gt;Bitovi and its team for helping other companies build quality applications and investing its resources back into open-source development that benefits everyone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sincerely and with much love,&lt;br&gt;
CanJS Core Team&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Use Lazy Values to Speed Up Your JS Apps</title>
      <dc:creator>Kevin Phillips</dc:creator>
      <pubDate>Wed, 07 Aug 2019 15:45:30 +0000</pubDate>
      <link>https://dev.to/bitovi/use-lazy-values-to-speed-up-your-js-apps-2fp6</link>
      <guid>https://dev.to/bitovi/use-lazy-values-to-speed-up-your-js-apps-2fp6</guid>
      <description>&lt;p&gt;Defining properties with "lazy values" is a technique you can use to improve performance in Object-Oriented JavaScript. It is especially beneficial because it can improve application load time, which can greatly impact important metrics like bounce rate and revenue.&lt;/p&gt;

&lt;p&gt;In this article, we’ll answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a Lazy Value?&lt;/li&gt;
&lt;li&gt;How do Lazy Values work?&lt;/li&gt;
&lt;li&gt;Should you use Lazy Values?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a Lazy Value?
&lt;/h2&gt;

&lt;p&gt;Normally when a property is created on an object, the expression that defines its value is evaluated &lt;em&gt;eagerly&lt;/em&gt;. Eager evaluation means that the &lt;code&gt;getUniqueId&lt;/code&gt; function in the following example is called immediately to compute the value for &lt;code&gt;id&lt;/code&gt; whenever &lt;code&gt;MyObj&lt;/code&gt; is called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUniqueId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// some magic to create an ID&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyObj&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUniqueId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyObj&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; { id: 1 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;getUniqueId&lt;/code&gt; function is called even if the &lt;code&gt;id&lt;/code&gt; property is never used in the rest of the code. Lazy Values avoid this evaluation. Lazy Values are not computed until the first time the property is read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyObjWithLazyId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; { }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; { id: 2 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How do Lazy Values work?
&lt;/h2&gt;

&lt;p&gt;The key to setting up Lazy Values is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"&gt;Object.defineProperty&lt;/a&gt;. This API lets you define properties and gives you lots of control over how they behave.&lt;/p&gt;

&lt;p&gt;To define a Lazy Value, first we define the property as a &lt;a href="https://dev.togetter"&gt;getter&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyObjWithLazyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getUniqueId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notice how we're adding this to the &lt;code&gt;prototype&lt;/code&gt; of our &lt;code&gt;MyObjWithLazyId&lt;/code&gt; constructor. This allows us to define this property once and have it used by any instance of &lt;code&gt;MyObjWithLazyId&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This gets us part of the way there, but with just this, the &lt;code&gt;id&lt;/code&gt; property would change every time it is read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyObjWithLazyId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 3&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 5&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 8 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this work correctly, we first define the property using a getter, but when the getter is called, we use &lt;code&gt;Object.defineProperty&lt;/code&gt; again to redefine the property as a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyObjWithLazyId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUniqueId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redefining the property as a value means that the next time it is read, the value will be returned without any function needing to be called.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you use Lazy Values?
&lt;/h2&gt;

&lt;p&gt;The benefit of using Lazy Values is that they don't have to be computed during the initialization of your app. As you can see from this &lt;a href="https://jsbench.github.io/#3da95139f6e8599bd44386e958220621"&gt;benchmark&lt;/a&gt;, the performance of  Lazy Values (the orange bar below) is very close to the performance of constructing a completely empty object, which is shown in the blue bar (larger is better):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--72aw5Q2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh6.googleusercontent.com/ivc_D5KWaFAUCURLN19lZeO4eCEzZePrDRZuQSIJYbxTcZfoOUoxOeoynW8G50tlHCYIPmPDjT7iJLPeHwPVVZ6qe5UD5k9K0D-brg3_GY3sUZeo4TLCtdq5KD0ph7EdqXAj1geu" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--72aw5Q2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh6.googleusercontent.com/ivc_D5KWaFAUCURLN19lZeO4eCEzZePrDRZuQSIJYbxTcZfoOUoxOeoynW8G50tlHCYIPmPDjT7iJLPeHwPVVZ6qe5UD5k9K0D-brg3_GY3sUZeo4TLCtdq5KD0ph7EdqXAj1geu" alt="" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're building a module that will only be used in a few places in your application, the benefits of using this technique are probably outweighed by the complexity you're adding for yourself the next time you read this code. Make sure to performance test in your app to see if the benefits are worth any decrease in readability.&lt;/p&gt;

&lt;p&gt;If the code you're writing will be used many times throughout your application or you are building a &lt;a href="https://canjs.com/"&gt;world-class JavaScript library&lt;/a&gt;, it is likely that your users will benefit from the performance improvement Lazy Values provide.&lt;/p&gt;

&lt;p&gt;If you want to use this technique, we just published &lt;a href="https://canjs.com/doc/can-define-lazy-value.html"&gt;can-define-lazy-value&lt;/a&gt; to make it very easy to get started. You can install it from &lt;a href="https://www.npmjs.com/package/can-define-lazy-value"&gt;npm&lt;/a&gt; and take a look at its &lt;a href="https://github.com/canjs/can-define-lazy-value/blob/4c8529d566f33eb6566bbb9da93e003192545e85/dist/cjs/define-lazy-value.js"&gt;25 lines&lt;/a&gt; of code to see exactly how it works.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
