Mastering JavaScript without the use of the `new` keyword: Unleashing the Power of the Good Parts

In his book, "JavaScript: The Good Parts," Crockford emphasizes the importance of giving constructor functions names with an initial capital letter (e.g., Point) and using function names with initial capital letters only with constructor functions, while everything else should be in lowercase.

Following this convention helps prevent forgetting to use the new operator with constructor functions.

Crockford even suggests that "[a]n even better coping strategy is to not use new at all."

The question then arises - how can we write JavaScript code without utilizing new altogether?

  • To avoid using new Object() and new Array(), we can opt for the literal representations like {} and [].
  • Instead of new Number(), new Boolean(), and new String(), we can stick to 0, true and ''.
  • We can forego new RegExp() by employing patterns such as /pattern/.

But what about displacing new Date()?

And perhaps most crucially, how do we manage to circumvent using new when creating our own custom Objects?

Answer №1

In one of his Javascript talks, Crockford provides an example of an object creation function that he believes should have been included in JavaScript itself. The YUI(3) team, however, opts to use "new" despite Crockford's recommendations. This discrepancy highlights a conflict within the language, which mixes prototype-based inheritance with elements of traditional class-based languages.

Despite these theoretical debates, the reality is that JavaScript is what it is, so developers are advised to simply go ahead and use "new" for object creation. If interested, Crockford's object creation function can be found here.

 if (typeof Object.create !== 'function') {
     Object.create = function (o) {
         function F() {}
         F.prototype = o;
         return new F();
     };
 }
 newObject = Object.create(oldObject);


An updated version of Crockford's object creation function is available on his website.


It's worth noting that modern browsers support Object.create(...), eliminating the need for Crockford's custom function. However, performance considerations may lead some developers to continue using the traditional new Constructor() approach instead.

As the industry moves towards wider acceptance of ES6 classes, there may be compelling reasons to explore both Object.create and traditional instantiation methods. Ultimately, the choice between the two approaches may depend on the specific requirements of each project and the preferences of individual developers.

Personal experiences vary, but some developers, including myself, have embraced ES 2015 Javascript and moved away from using new extensively. By adopting a more functional programming style without relying heavily on objects and classes, I have found greater convenience and power in my projects. While there are no hard and fast rules, it's always beneficial to experiment and find the approach that works best for your needs.

Answer №2

When it comes to avoiding the use of new Date() or new XMLHttpRequest(), I must admit that I am not entirely sure myself. However, I have found a way to steer clear of using 'new' for my custom types.

To begin, I rely on Object.create(). Although this method is part of ES5 and may not be universally supported, I can easily include it by utilizing the es5-shim.

Embracing the module pattern, I encapsulate my type within a self-invoking anonymous function as follows: var Xyz = (function() {...})(). This approach provides me with a private environment in which to operate without cluttering the global namespace. My returned object contains a create() function for users to instantiate my type and a prototype property for potential inheritance purposes.

For instance, consider the following example:

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

And when exploring inheritance:

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

Answer №3

It's unwise to dismiss the use of new and blindly adhere to Crockford's teachings.

Master JavaScript and strive for excellence in your code. Embracing the new keyword is fundamental to object-oriented programming in JavaScript.

Avoiding new means potentially overlooking valuable opportunities to enhance your JavaScript code.

Instead of arbitrarily limiting your coding capabilities, take the time to understand and properly utilize all tools at your disposal.

Crockford often condemns any aspect of JavaScript that has caused issues in his own code.

I personally believe that "[a]n even better coping strategy is to be competent."

Answer №4

To bypass the use of new, you can opt for constructing factory functions:

var current = Date.getCurrentDate();

(Just so you know, evasion of using new doesn't apply to the factory function itself:)

Date.getCurrentDate = function() { return new Date(); };

I recommend creating such functions only if it enhances semantic meaning (like in the example above) or allows defaulting constructor parameters. In essence, don't resort to this technique solely to evade the use of new.

Answer №5

This query has already been addressed and resolved: Is JavaScript's "new" keyword considered harmful?

According to Raynos, mindlessly adhering to Crockford (or any other authority) without comprehending the rationale behind their assertions is foolish.

Answer №6

In my opinion, the suggestion to avoid using new altogether should be seen as more of a theoretical concept rather than a strict rule to follow. One exception to this guideline is when working with the Date class in JavaScript, where using new is necessary to create date objects.

When it comes to creating instances of custom objects without using new, there are alternative methods that can be employed. For example, one approach is to use factory-like functions instead of constructors. These functions can accept an object instance as input and modify it to fit the desired type. Here's an example:

var createNewCar = function(obj) {
  obj = obj || {};
  // Define methods and properties for 'obj' here...
  return obj;
}

Answer №7

When it comes to creating objects, you don't have to rely on the 'new' keyword for other people's code. However, for your own code, there are ways to avoid the issues that come with using both 'this' and 'new'.

(Interestingly, the problem doesn't actually lie with 'new' itself. Instead, when an object is instantiated with 'new', it often involves the use of 'this' internally. Working with 'this' can introduce subtle bugs due to JavaScript's nature of requiring the caller to bind the called method correctly to the object. Detecting incorrect bindings before runtime can be challenging.)

In short:

If you want to steer clear of using 'new' to create objects in your code, simply return an object from any function. Within that function, attach methods to the object and handle initialization tasks. That function serves as both your class definition and constructor.

For a more detailed explanation with an example:

The 'self' pattern provided below eliminates the need for 'new' and 'this'. While this pattern does result in multiple copies of methods being stored in each object, this won't pose an issue unless you're generating numerous objects during runtime. In such cases, you can consider implementing the 'flyweight' pattern outlined at . (It may require slight modifications to adapt examples from that page to the pattern described below.)

// This function serves as a "class" -- the entire function acts as the constructor
function Foo(x) {
    // Define and initialize the desired object type here
    var self = {x: x};
    
    // For subclassing purposes, you can also do:
    // var self = Baz(x);

    // Public method
    self.foo = function() {
        return self.x;
    };

    // Another public method
    self.bar = function() {
        console.log(self.x);
        logger();
    };

    // Private method
    function logger() {
        console.log(self.x);
    }

    // Other constructor components can be added here

    // Remember to return self
    return self;
}

var f = Foo(1); 
var g = Foo(2); 
setTimeout(f.bar, 1000);
setTimeout(g.bar, 1000);

console.log(g.foo()); // 2
g.x = 5;
console.log(f.foo()); // 1
console.log(g.foo()); // 5

// ...after 1 second:
// 1  (from f.bar)
// 1  (from f.logger)
// 5  (from g.bar)
// 5  (from g.logger)

// Uncommenting will cause an error
// f.logger();

Answer №8

define function F() { return { /* add properties and functions here */ } }

Answer №9

Avoid using the "new" keyword by returning an anonymous object and incorporating a closure in your constructor function. This technique also allows you to conceal private data effectively.

For example:

function CustomCounter(start) {

    var counter = start;

    return {
        getCounter: function() {
            return counter;
        },

        increaseCounter: function() {
            counter++;
        }

    };
}

To utilize this, simply follow these steps:

var myCustomCounter = CustomCounter(5);
myCustomCounter.increaseCounter();
console.log(myCustomCounter.getCounter()); // output should be 6

The advantage here is that there's no need to remember using "new", although it won't cause any issues if you decide to use it.

var anotherCounter = new CustomCounter(5); // it still functions correctly

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Validating a model in Mongoose: Best practices for updating data

I am facing an issue with my model. It seems that while creating, incorrect information is prohibited, but when editing, it is allowed. How can I prevent this from happening? var userSchema = new Schema({ cartaoCidadao: { type: String, require ...

While attempting to deploy my project on Vercel by pulling in my code from GitHub, I ran into this error

As a self-taught Front End developer diving into building and hosting my first web page using React, I've encountered this warning. Any suggestions on how to resolve it? Cloning gitohub.com/Passion94/React-Apps (Branch: main, Commit: da89a2a) Cloning ...

Preparing the format/serialization of a JQuery JSON array prior to submitting it

Looking at the JSON structure I have: { "firstArrayOfJSON": [ { "something" : "something" }, { "another" : "another" }, { "secondArrayOfJson" : [ ...

Is it possible to link an asp.net dropdownlist to javascript/jquery?

I'm looking to bind an asp.net dropdownlist using javascript/jquery. I am retrieving the data from a web method using jquery ajax, so I want to avoid postback at this point. However, I still need to be able to do postback and save all the data using s ...

What is the reason behind the absence of unwrapping when utilizing a ref as an element within a reactive array or reactive Map?

The Vue documentation states the following: Unlike reactive objects, there is no unwrapping performed when the ref is accessed as an element of a reactive array or a native collection type like Map Here are some examples provided in the documentation: c ...

Embedding JavaScript directly into a Jade file(Note: This is

After spending about 3 hours trying to unravel the mystery, I'm still lost and unsure where to even begin looking for answers. We implemented a method that allows us to include JS files directly in a single Jade file, serving as a manifest for all ou ...

Mastering the art of handling errors in asynchronous Node.js code using try-catch and async

Recently, I made the switch to using async/await instead of promises. Despite this shift, I find myself unsure about the proper usage of try...catch. Consider the example below: const rp = require('request-promise'); const func2 = async () => ...

Ways to enhance the efficiency of this javascript duplicates

I recently wrote this JavaScript code but, as I am still in the early stages of learning, I am struggling to optimize it efficiently. I ended up duplicating the code for each if statement. $(function() { var lang = $(".lang input[type='checkbox&a ...

Populate the table with JSON content using jQuery

I am attempting to populate a table with JSON data using jQuery, but the content within the div remains empty. I need assistance in identifying the error. The array list contains the data (I verified this using console.log(list)). Additionally, list[' ...

Error message encountered: "Node.js Object [object Object] does not support the method"

My application uses Express.js and mongodb, including the mongodb Native driver. I have created a model with two functions for retrieving posts and comments: // Retrieve single Post exports.posts = function(id,callback){ MongoClient.connect(url, fun ...

Determining the height of the first element in jQuery

I am dealing with multiple elements that share the same class but have different heights. The class 'xyz' is only for styling borders, as shown below: <div class='xyz'></div> //1st element height=10px <div class='xy ...

"Customized color selection based on conditions using Angular's UI-Grid

I'm trying to create conditional coloring in my grid based on the data, using the cellClass function in columnDefs. The issue I'm facing is that the classes are not updated when there is a selection change, preventing me from defining colors for ...

Tips for updating multiple documents in a MongoDB database using an array of values

I have a range of Product items in my inventory and when a client places an Order, they submit an array of objects. Each object in the array includes the _id product (objectId) and the quantity they purchased. [ {producId: "dshsdsdh72382377923", quantity: ...

Encountering excessive re-renders while using MUI and styled components

Hey there! I recently worked on a project where I used MUI (Material-UI) and styled-components to render a webpage. To ensure responsiveness, I made use of the useTheme and useMediaQuery hooks in my web application. My goal was to adjust the font size for ...

How do I assign a default value to an optional parameter in a derived class in Typescript?

One of my classes is called ClientBase: export class ClientBase { constructor(private uri: string, private httpClient: HttpClient) { } // Contains Various Methods } I have multiple subclasses that are derived from the ClientBase For instance: @I ...

Utilizing jQuery for AJAX-Based Deletion of Records

Hey, I stumbled upon a code snippet that allows me to delete a row from my database using Ajax. However, there seems to be an issue where the table that should disappear when deleted is not working properly. Here is the JavaScript code: <script type=" ...

Issues with AngularJS <a> tag hyperlinks not functioning as expected

After performing a search, I have an array of objects that needs to be displayed on the template using ng-repeat. The issue arises when constructing the URL for each item in the array – although the ng-href and href attributes are correct, clicking on th ...

Is there a way to prevent users from right clicking on all links with the same class using js/jquery?

Rails 4 + JS + jquery Is there a way to disable right click on links with the same class in Rails? <% @schedule_hash.values.each do |schedule| %> <%= link_to "Cancellation policy", {:controller => 'web', :action => 'get ...

Tips for Showing Certain Slides When the Page Loads

When using jQuery filter effects to organize div slides on a page, I encountered an issue where all the divs containing different slides are displayed on page load instead of just the default chosen ['active'] div. The filter effect itself is fun ...

What is the most effective way to add images to a table using JavaScript?

Is there a way to insert images into the "choicesDiv" without having to make changes to the HTML & CSS? Here is the table code: <table id="choices"> <tr> <td><div class="choicesDiv" value="1"></div></td> ...