#

API Docs for: v2.11.1
Show: Inherited Protected Private Deprecated

# File: packages/ember-runtime/lib/ext/function.js

    /**
    @module ember
    @submodule ember-runtime
    */

    import { ENV } from 'ember-environment';
    import {
      assert,
      deprecateFunc,
      computed,
      observer
    } from 'ember-metal';

    const a_slice = Array.prototype.slice;
    const FunctionPrototype = Function.prototype;

    if (ENV.EXTEND_PROTOTYPES.Function) {
      /**
        The `property` extension of Javascript's Function prototype is available
        when `EmberENV.EXTEND_PROTOTYPES` or `EmberENV.EXTEND_PROTOTYPES.Function` is
        `true`, which is the default.

        Computed properties allow you to treat a function like a property:

        ```javascript
        MyApp.President = Ember.Object.extend({
          firstName: '',
          lastName:  '',

          fullName: function() {
            return this.get('firstName') + ' ' + this.get('lastName');
          }.property() // Call this flag to mark the function as a property
        });

        let president = MyApp.President.create({
          firstName: 'Barack',
          lastName: 'Obama'
        });

        president.get('fullName'); // 'Barack Obama'
        ```

        Treating a function like a property is useful because they can work with
        bindings, just like any other property.

        Many computed properties have dependencies on other properties. For
        example, in the above example, the `fullName` property depends on
        `firstName` and `lastName` to determine its value. You can tell Ember
        about these dependencies like this:

        ```javascript
        MyApp.President = Ember.Object.extend({
          firstName: '',
          lastName:  '',

          fullName: function() {
            return this.get('firstName') + ' ' + this.get('lastName');

            // Tell Ember.js that this computed property depends on firstName
            // and lastName
          }.property('firstName', 'lastName')
        });
        ```

        Make sure you list these dependencies so Ember knows when to update
        bindings that connect to a computed property. Changing a dependency
        will not immediately trigger an update of the computed property, but
        will instead clear the cache so that it is updated when the next `get`
        is called on the property.

        See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/classes/Ember.computed.html).

        @method property
        @for Function
        @public
      */
      FunctionPrototype.property = function () {
        let ret = computed(this);
        // ComputedProperty.prototype.property expands properties; no need for us to
        // do so here.
        return ret.property(...arguments);
      };

      /**
        The `observes` extension of Javascript's Function prototype is available
        when `EmberENV.EXTEND_PROTOTYPES` or `EmberENV.EXTEND_PROTOTYPES.Function` is
        true, which is the default.

        You can observe property changes simply by adding the `observes`
        call to the end of your method declarations in classes that you write.
        For example:

        ```javascript
        Ember.Object.extend({
          valueObserver: function() {
            // Executes whenever the "value" property changes
          }.observes('value')
        });
        ```

        In the future this method may become asynchronous.

        See `Ember.observer`.

        @method observes
        @for Function
        @public
      */
      FunctionPrototype.observes = function(...args) {
        args.push(this);
        return observer.apply(this, args);
      };

      FunctionPrototype._observesImmediately = function () {
        assert(
          'Immediate observers must observe internal properties only, ' +
          'not properties on other objects.',
          function checkIsInternalProperty() {
            for (let i = 0; i < arguments.length; i++) {
              if (arguments[i].indexOf('.') !== -1) {
                return false;
              }
            }
            return true;
          }
        );

        // observes handles property expansion
        return this.observes(...arguments);
      };
      /**
        The `observesImmediately` extension of Javascript's Function prototype is
        available when `EmberENV.EXTEND_PROTOTYPES` or
        `EmberENV.EXTEND_PROTOTYPES.Function` is true, which is the default.

        You can observe property changes simply by adding the `observesImmediately`
        call to the end of your method declarations in classes that you write.
        For example:

        ```javascript
        Ember.Object.extend({
          valueObserver: function() {
            // Executes immediately after the "value" property changes
          }.observesImmediately('value')
        });
        ```

        In the future, `observes` may become asynchronous. In this event,
        `observesImmediately` will maintain the synchronous behavior.

        See `Ember.immediateObserver`.

        @method observesImmediately
        @for Function
        @deprecated
        @private
      */
      FunctionPrototype.observesImmediately = deprecateFunc(
        'Function#observesImmediately is deprecated. Use Function#observes instead',
        { id: 'ember-runtime.ext-function', until: '3.0.0' },
        FunctionPrototype._observesImmediately
      );

      /**
        The `on` extension of Javascript's Function prototype is available
        when `EmberENV.EXTEND_PROTOTYPES` or `EmberENV.EXTEND_PROTOTYPES.Function` is
        true, which is the default.

        You can listen for events simply by adding the `on` call to the end of
        your method declarations in classes or mixins that you write. For example:

        ```javascript
        Ember.Mixin.create({
          doSomethingWithElement: function() {
            // Executes whenever the "didInsertElement" event fires
          }.on('didInsertElement')
        });
        ```

        See `Ember.on`.

        @method on
        @for Function
        @public
      */
      FunctionPrototype.on = function () {
        let events = a_slice.call(arguments);
        this.__ember_listens__ = events;

        return this;
      };
    }