Can the 'this' keyword be used inside the RequireJS module?

I defined the RequireJS module (see below). This is the set of functions that are needed on every page of the site.

One of the functions in the returned object, initTwitter (), must call another function, shorttenURL (), in the same object. I get a console error: "TypeError: this.shortenURL is not a function."

All of these functions were originally in a regular singleton Javascript object, and the code worked fine. I'm new to RequireJS, so I'm not sure if the this keyword works differently in RequireJS, or I'm just doing something wrong.

EDIT: I also tried removing "this", but instead I get the message "ReferenceError: shortenURL not defined".

define(['config', 'jquery'], function(config, $) { /* Site-wide functions go here */ return { doesObjPropertyExist: function(obj, prop) { var parts = prop.split('.'); for(var i = 0, l = parts.length; i < l; i++) { var part = parts[i]; if(obj !== null && typeof obj === "object" && part in obj) { obj = obj[part]; } else { return false; } } return true; }, /** * Shorten URL via bit.ly * Requires a callback function, so that once getJSON is absolutely finished, we can continue with the function */ shortenURL: function(longURL, callback, settingsOverride) { var defaults = { login: '@ bitly.username@ ', apiKey: '@ bitly.key@ ' }; $.extend({}, defaults, settingsOverride); var bitly_service_url = "http://api.bit.ly/v3/shorten?" + "&login=" + defaults.login + "&apiKey=" + defaults.apiKey + "&longUrl=" + longURL + "&format=json&callback=?"; $.getJSON(bitly_service_url, function(results){ if (results.status_txt === "OK") { callback(results.data["url"]); } else { callback(longURL); } }); }, initTwitter: function() { var bitly_obj = '', $bitly_link = '', twitterShortenUrl = function(obj, $elem) { this.shortenURL(obj.url, function(url) { $elem.attr('href', 'http://twitter.com/home?status=' + 'From @Real_Simple ' + arg_obj.headline + ' ' + shortened_url); }); }; $bitly_link = $('#share-twitter'); /* On document.ready, only call bitly service and change the link href if the twitter link exists; cannot use page_context, * because we are looking for a specific element ID that is only placed when Twitter is needed. */ if ($bitly_link.length) { bitly_obj = config.page_context.bitly; twitterShortenUrl(bitly_obj, $bitly_link); } }, initFullSiteLink: function() { var canonical_url = $('link[rel="canonical"]').attr('href'), content_type = config.markup_id.content; if (content_type == 'search') { $('#fullsite').attr('href', canonical_url + location.search + '&nomobile=1'); } else { $('#fullsite').attr('href', canonical_url + '?nomobile=1'); } }, initNav: function() { /* Global navigation */ /* Make Channels button open and close the global flyout navigation */ $('#channels-toggle').bind('click', function() { if ($('#channels').hasClass('is-open')) { $('#channels').removeClass('is-open'); } else { $('#channels').addClass('is-open'); } return false; }); /* Touch the close button in the global flyout navigation to close it */ $('#channels .close').bind('click', function() { $('#channels').removeClass('is-open'); return false; }); }, omniture: { mobilePageTrack: function (desc) { /* Global function in rsmobile.js */ omniPg(desc); } }, init: function() { this.initNav(); this.initTwitter(); this.initFullSiteLink(); } } /* End return object */ }); 

EDIT 2: It turns out that โ€œthisโ€ in my code was inside another function, so its scope changed to a window. I need to save the volume of this before entering the function.

 initTwitter: function() { var bitly_obj = '', $bitly_link = '', self = this; /* Preserve scope of this */ var twitterShortenUrl = function(obj, $elem) { self.shortenURL(obj.url, function(url) { $elem.attr('href', 'http://twitter.com/home?status=' + 'From @Real_Simple ' + obj.headline + ' ' + url); }); }; /* rest of code .... */ 

Otherwise, Paulโ€™s answer emphasizes that I can return anything and add initialization.

+5
source share
1 answer

No, because Require.js does not perform any magic bindings for this . You must rewrite your module as an instance object:

 define(['config', 'jquery'], function(config, $) { function obj() { this.initNav(); this.initTwitter(); this.initFullSiteLink(); } obj.prototype = { doesObjPropertyExist: function (/*...*/) { /*...*/ }, shortenURL: function (/*...*/) { /*...*/ }, initTwitter: function (/*...*/) { /*...*/ }, initFullSiteLink: function (/*...*/) { /*...*/ }, initNav: function (/*...*/) { /*...*/ }, omniture: function (/*...*/) { /*...*/ } }; return obj; }); require(['that_main_module'], function (obj) { var newObj = new obj(); }); 
+7
source

All Articles