JQuery JavaScript Design: Self Executing Function or Object Literal? [closed]

Asked
Active3 hr before
Viewed126 times

9 Answers

jqueryclosedobjectdesignjavascript
90%

It's a combination of the YUI module pattern with a bit of jQuery plugin pattern mixed in.. We ended up using the self executing closure pattern. This is beneficial in a few ways:,It keeps code to a minimum,It enforces separation of behavior from presentation,The nice thing about the second example is that a closure is created, thus allowing you to define private properties and methods.

This is what it looks like:

;
(function($) {
   var myPrivateFunction = function() {};

   var init = function() {
      myPrivateFunction();
   };

   $(init);
})(jQuery);
load more v
88%

The nice thing about the second example is that a closure is created, thus allowing you to define private properties and methods.,Now clearly, you can remove the YAHOO.namespace() call if you don't want to use YUI, but that's the basic outline. It uses object literal notation, but also allows you to define private properties and methods.,It's a combination of the YUI module pattern with a bit of jQuery plugin pattern mixed in.. We ended up using the self executing closure pattern. This is beneficial in a few ways:,Of course we could have written the init method inline, without defining a variable for the function. We agreed that explicitly defining the init function made the code clearer to readers.

Generally, when I construct a page I like to encapsulate the functions used within that page inside an object. This allows me some encapsulation when building applications. There's nothing I hate more than seeing a JavaScript file with a bunch of this

function doSomethingOnlyRelevantOnThisPage() {
   // do some stuff
}

In Mootools they favor the Object Literal Notation:

var Site = {
   // properties and methods
}

In YUI they favor the Self Executing Function notation:

(function() { // properties and methods })()
load more v
72%

What is the difference between a method and a function?,If you wanted to separate your private and public methods and create a closure (a mini environment which has access to the namespaces’ local variables even when the function is returned), you’d probably do this:,In JavaScript, a method is code that belongs to an object and which is able to interface with other code and data within that object (object-orientated). A function is code that sits outside of an object and can be called from anywhere. In the case of the example above, publicMethod() is associated with the object ‘example’, so it is therefore a method. It is, however, just a naming convention. JavaScript does not have (or have a need for) a type ‘method’, just a type ‘function’ which can be associated to an object.,The second argument passes in our jQuery object, although it could pass in any favourite JavaScript library. As the code we are executing is in its own local scope, we can now use the $ variable safe in the knowledge that no-one else has declared $ for use as anything else. We also include an argument of undefined and pass in no correlating value which removes the threat of someone else redefining undefined.

var example = {
   publicVariable: 'publicValue',
   publicMethod: function() {

   }
};
load more v
65%

In JavaScript, there are several options for implementing modules. These include:,Object literal notation,Below, we can see a more complete example of a module defined using object literal notation:,Let’s begin looking at an implementation of the Module pattern by creating a module that is self-contained.

var myObjectLiteral = {

   variableKey: variableValue,

   functionKey: function() {
      // ...
   };
};
var myModule = {

   myProperty: "someValue",

   // object literals can contain properties and methods.
   // e.g we can define a further object for module configuration:
   myConfig: {
      useCaching: true,
      language: "en"
   },

   // a very basic method
   myMethod: function() {
      console.log("Where in the world is Paul Irish today?");
   },

   // output a value based on the current configuration
   myMethod2: function() {
      console.log("Caching is:" + (this.myConfig.useCaching) ? "enabled" : "disabled");
   },

   // override the current configuration
   myMethod3: function(newConfig) {

      if (typeof newConfig === "object") {
         this.myConfig = newConfig;
         console.log(this.myConfig.language);
      }
   }
};

// Outputs: Where in the world is Paul Irish today?
myModule.myMethod();

// Outputs: enabled
myModule.myMethod2();

// Outputs: fr
myModule.myMethod3({
   language: "fr",
   useCaching: false
});
load more v
75%

This is how I do most all my JS these days (pretty close anyway). Essentially this allows objects on "this" to be "public", and "var" scoped objects to be "private".,As you can see, "this.getMessage" was bound to the object literal context which made it a public method of the resultant singleton reference.,Then, if I need a singleton I invoke like you show above. Otherwise for a "class" I do not, allowing instantiation. ,To see this in action, let's take a look at the following demo. In this scenario, we are using call() to explicitly define the "this" context of the self-executing function block:

<!DOCTYPE html>
<html>
<head>
	<title>Changing The Context of a Self-Executing Function</title>

	<script type="text/javascript">


		// Set the singleton value to the return value of the self-
		// executing function block.
		var singleton = (function(){


			// Declare a private variable.
			var message = "Stop playing with your context!";


			// Declare a public method. In this function, the "THIS"
			// keyword is a reference to the object literal context
			// defined with the .call() method.
			this.getMessage = function(){

				return( message );

			};


			// Return this object reference.
			return( this );


		}).call( {} );
		// NOTE: When we are invoking the self-executing function
		// block, we are using CALL() to change the execution
		// context of the function. In this case, we are setting it
		// equal to the object literal, {}.


		// Log the singleton message.
		console.log( "Message:", singleton.getMessage() );


	</script>
</head>
<body>
	<!-- Left intentionally blank. -->
</body>
</html>
load more v
40%

http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses,Reference: http://stackoverflow.com/questions/3259496/jquery-document-ready-vs-self-calling-anonymous-function,http://stackoverflow.com/questions/8275658/passing-window-and-undefined-to-an-immediately-invoked-anonymous-function-why,jQuery equivalent of JavaScript's addEventListener method http://stackoverflow.com/questions/2398099/jquery-equivalent-of-javascripts-addeventlistener-method

$(init);

$(document).ready(function() {
   ...
});

$(function() {});
$(document).ready(function() {
   ...
});
or short $(function() {
   ...
});

This Function is called when the DOM is ready which means, you can start to query elements for instance. .ready() will use different ways on different browsers to make sure that the DOM really IS ready.

(function() {
   ...
})();
load more v
22%

Parameters can also be passed to these Self invoked functions, generally, references to global objects are passed as parameters.,As these functions are unnamed or anonymous, expression of the function is immediately invoked even without using any identifier or closure and not spoiling the scope.,We have two syntax variations for Self-invoked functions as below,,These functions are called as Immediately Invoked Function Expressions, as IIFE or Self Executing functions. The purpose of wrapping these functions is to control the visibility of its members. You might be thinking why we would ever need to use these self-invoking functions. So, let us dig deeper into it.

(function() {
// body of the function
})();

(function() {
   // body of the function
})();
load more v
60%

Modifying an objects prototype, on the other hand, is used to establish inheritance (or extend natives). This pattern is used to produce 1:n objects with common methods or properties.,You should not choose one pattern in preference to the other, since they perform different tasks. In terms of namespacing, the Self Executing Function is an appropriate choice.,The only time that I'd use prototype anymore really is to define inheritance.,I tend to prefer Self-Executing Anonymous Functions however I am curious what the community vote is on these techniques.

Here's the pattern that I just began using (have been using variations of it up until yesterday):

function MyClass() {
   // attributes
   var privateVar = null;

   // function implementations
   function myPublicFunction() {}

   function myPrivateFunction() {}

   // public declarations
   this.myPublicFunction = myPublicFunction;
}

MyClass.prototype = new ParentClass(); // if required
load more v
48%

The three common ways to create new objects in JavaScript are as follows:,We can then instantiate the object using the Car constructor we defined above like this:,As we can see, this allows us to easily "mix" in common behaviour into object constructors fairly trivially. ,JavaScript Patterns by Stoyan Stefanov

The most common approach to achieving this is by defining a JavaScript function where we then create an object using the new keyword. this can be used to help define new properties and methods for the object as follows:

// A car "class"
function Car(model) {

   this.model = model;
   this.color = "silver";
   this.year = "2012";

   this.getInfo = function() {
      return this.model + " " + this.year;
   };

}

We can then instantiate the object using the Car constructor we defined above like this:

var myCar = new Car("ford");

myCar.year = "2010";

console.log(myCar.getInfo());

// Each of the following options will create a new empty object:

var newObject = {};

// or
var newObject = Object.create(Object.prototype);

// or
var newObject = new Object();

// ECMAScript 3 compatible approaches

// 1. Dot syntax

// Set properties
newObject.someKey = "Hello World";

// Get properties
var value = newObject.someKey;

// 2. Square bracket syntax

// Set properties
newObject["someKey"] = "Hello World";

// Get properties
var value = newObject["someKey"];

// ECMAScript 5 only compatible approaches
// For more information see: http://kangax.github.com/es5-compat-table/

// 3. Object.defineProperty

// Set properties
Object.defineProperty(newObject, "someKey", {
   value: "for more control of the property's behavior",
   writable: true,
   enumerable: true,
   configurable: true
});

// If the above feels a little difficult to read, a short-hand could
// be written as follows:

var defineProp = function(obj, key, value) {
   var config = {
      value: value,
      writable: true,
      enumerable: true,
      configurable: true
   };
   Object.defineProperty(obj, key, config);
};

// To use, we then create a new empty "person" object
var person = Object.create(Object.prototype);

// Populate the object with properties
defineProp(person, "car", "Delorean");
defineProp(person, "dateOfBirth", "1981");
defineProp(person, "hasBeard", false);

console.log(person);
// Outputs: Object {car: "Delorean", dateOfBirth: "1981", hasBeard: false}

// 4. Object.defineProperties

// Set properties
Object.defineProperties(newObject, {

   "someKey": {
      value: "Hello World",
      writable: true
   },

   "anotherKey": {
      value: "Foo bar",
      writable: false
   }

});

// Getting properties for 3. and 4. can be done using any of the
// options in 1. and 2.

// Usage:

// Create a race car driver that inherits from the person object
var driver = Object.create(person);

// Set some properties for the driver
defineProp(driver, "topSpeed", "100mph");

// Get an inherited property (1981)
console.log(driver.dateOfBirth);

// Get the property we set (100mph)
console.log(driver.topSpeed);

function Car(model, year, miles) {

   this.model = model;
   this.year = year;
   this.miles = miles;

   this.toString = function() {
      return this.model + " has done " + this.miles + " miles";
   };
}

// Usage:

// We can create new instances of the car
var civic = new Car("Honda Civic", 2009, 20000);
var mondeo = new Car("Ford Mondeo", 2010, 5000);

// and then open our browser console to view the
// output of the toString() method being called on
// these objects
console.log(civic.toString());
console.log(mondeo.toString());

function Car(model, year, miles) {

   this.model = model;
   this.year = year;
   this.miles = miles;

}

// Note here that we are using Object.prototype.newMethod rather than
// Object.prototype so as to avoid redefining the prototype object
Car.prototype.toString = function() {
   return this.model + " has done " + this.miles + " miles";
};

// Usage:

var civic = new Car("Honda Civic", 2009, 20000);
var mondeo = new Car("Ford Mondeo", 2010, 5000);

console.log(civic.toString());
console.log(mondeo.toString());
load more v

Other "jquery-closed" queries related to "JQuery JavaScript Design: Self Executing Function or Object Literal? [closed]"