Constructor question when building plugin / library - javascript

I’m tinkering around, trying to better understand how I’d go about building a custom jQuery plugin. I’ve never built my own library or plugin, so I’m kind of the bull in the china shop right now.
I have successfully managed to attach my library to the jquery object, however I’m not understanding a few things.
Within my library, I create a method on the prototype chain called checker. This works fine when I call it in my code. However, when I try instantiating the new object FunkyLib with some parameters, it says that FunkyLib is not a constructor, and I’m not sure why.
Here’s the code:
console.log('FuNkY Test');
(function ($, window, document, undefined) {
function FunkyLib (options) {
this.settings = options;
}
FunkyLib.prototype = {
checker: function() { alert('Purake'); }
};
$.fn.funky = new (FunkyLib);
}(jQuery, window, document));
If I were to try instantiating with some parameters with the constructor, I get an error in the console saying that FunkyLib is not a constructor.
For instance:
$.fn.funky = new (FunkyLib('Parameter'));
or
$.fn.funky = new (FunkyLib());
of even in the jquery call:
$('my-class').funky('param')
This works though:
$('my-class').funky.checker();
I’m pretty sure that my structure is just plain wrong. I have some material I’m reading, one of them being a tutorial on creating jQuery plugins. But I was hoping someone could give me a bit of 'to the point' advice on my errors here.
Thanks!

Related

visual studio code JavaScript code completion

Trying to use the Microsoft VS code to develop node.js app.
I'm starting with deciding if it worth the effort of learning this new IDE (new for me). so for now i am not asking about node.js completion rather my own objects.
I read about adding code completion for different packages, but my problem is much more basic.
I can't get code completion for my own JS objects.
Lets say i have this simple object:
function User() {
this.name = '';
}
var me = new User();
me. ????
when trying to get to the name property of User after instantiating it there is no code completion for the object properties.
It is something i am doing wrong or is it a basic problem?
to be clear. i am getting code completion for the node.js classes built in JS objects.
It has some really great things built in it but i can't find a solution for this basic problem.
10x
It seems that VSCode does not detect this pattern. If you would use a ES6 class:
class User {
constructor() {
this.name = '';
}
}
var me = new User();
me. // now proposes name

Cannot wrap my head around Immediately Invoking Anonymous Functions in Javascript

I have been studying framework development for a few weeks, and I ran across what is highly suggested and pressured in the world of lib development, Immediately-invoking Anonymous Functions.
I never can get it to work, and I have failed to find a resource that explains in-detail the use and logic behind it.
Here's what I know so far:
It's immediately invoking - It runs everything anonymously, immediately.
It's anonymous - It does not carry a name therefore the code inside of it is not "reachable" by exterior code.
You can pass global window, object and undefined parameters - That's about all I know on that, but do not understand them completely.
I am looking not only for a detailed resource, but one that explains the logic behind it. Because I find it very illogical.
Here's what I have:
(function( window, document, undefined ) {
window.myThingy = myThingy;
var myThingy = function() {
};
myThingy.prototype = {
constructor: myThingy,
create: function( elementToBeCreated ) {
return document.createElement( elementToBeCreated );
}
};
})( window, document );
Then,
myThingy().create("div");
But it is still saying myThingy() [object] is not a function.
What am I doing wrong? Why should I use immediately-invoking functions and not just create a global myThingy = function() object? Why do I have to use window?
I know there are several resources on the net about this, but I can't understand any of it. Some of them go half-way into detail, some of them try to go into detail, but fail to explain the critical stuff. Why is this so stressed when developing a framework?
Don't worry, I'm not trying to "re-invent the wheel", but I am trying, however, to actually learn JavaScript, not just the pre-packaged stuff.
A good answer should contain:
A good resource where it explains the logic behind immediately invoking anonymous functions
An insight to that link
What I am doing wrong with the code I provided
First off, you have not yet defined your function when you try to assign it to the global object so it is undefined:
window.myThingy = myThingy;
console.log(myThingy);//undefined
You need to do the assignment after myThingy is defined:
(function( window, document, undefined ) {
var myThingy = function() {
};
myThingy.prototype = {
constructor: myThingy,
create: function( elementToBeCreated ) {
return document.createElement( elementToBeCreated );
}
};
window.myThingy = myThingy;
})( window, document );
Okay, next, you cannot use
myThingy.create("div");
because myThingy is a function and not an object. Function objects are created when the new keyword is issued to a function. You can make this change to convert your function into a function object:
window.myThingy = new myThingy();//create a function object
This pattern is not how all frameworks are implemented, but similar. Sometimes there is more abstraction. However, making these changes will allow your approach to work.
Here is a demo of your code: http://jsfiddle.net/ZjRJW/
Links
Here are some of my favorites:
http://ejohn.org/blog/simple-class-instantiation/
http://ejohn.org/apps/learn/
http://ejohn.org/blog/simple-javascript-inheritance/
http://jibbering.com/faq/notes/closures/
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model
http://javascript.crockford.com/prototypal.html
If you want to learn about JS design patterns, I highly recommend Addy Osmani's books/articles. He keeps things very simple and usually supplies quite a bit of example code to help you understand. As far as your code and implementing a design pattern is concerned, it depends on what you want your code to do, and how you want your code/objects to behave. Understanding your requirements/goals are very important before you start coding so you don't get lost in a spaghetti of patterns that really aren't solving a specific problem.
In some cases, implementing a pattern intended for a complex, large application is simply overkill.
Since someone else already correctly pointed out the issues with your code, I'll just leave it there.

Backbone.js (with Require.js) variable/scope access issue

I'm trying to figure out how best to resolve an architectural issue with Backbone.js/Require.js
I have a test project here: https://github.com/Integralist/Backbone-Playground
The problem I'm having is that I'm creating a View in my main script file and then in another View script file I'm trying to access the other View but I don't know how to do it other than setting a global variable/property?
https://github.com/Integralist/Backbone-Playground/blob/master/Assets/Scripts/App/main.js#L73 is where I'm setting the global and https://github.com/Integralist/Backbone-Playground/blob/master/Assets/Scripts/Views/Contacts.js#L34-35 is where I'm accessing it.
I can't seem to wrap my head around how else to access it.
I know that this is just one global being set and if I had to keep it like that then I could also limit any damage by namespacing the global like so: window.myapp.contact_view = new ContactView(...) but this feels like an ugly workaround for this type of scope issue.
Any advice greatly appreciated.
UPDATE: Addy Osmani from Google has since tweeted me to suggest that namespacing my global is the best thing I can do in this instance, but I'll leave this question open for a while to see if there are any other suggestions that crop up.
The guru has spoken :) (Addy Osmani)
Here's what you can/should do IMHO - wrap your code in a self-executing function block:
File1.js:
(function(myNameSpace){
// do something
myNameSpace.sharedValue = something();
})(window.myNameSpace = window.myNameSpace || {});
Repeat the exact same code (structure) in File2.js
The last line makes sure that whichever file is loaded first the object is created and the same object is then used across files. Passing that same argument to the function allows you to access myNameSpace object in the function itself.
Other files can extend/augment/use the object as they deem fit. Basically there is no way to share variables in javascript (across files) other than exposing globals but can be done in a nice way :)
Try this for ContactsView.js:
define([ 'backbone' ],
function(B) {
return B.View.extend({
display_selected: function(event) {
this.options.contactView.render(model);
}
})
})
In your code,
new ContactsView({
contactView: new ContactView( ... )
})
Anyway, you should probably create your injected view from ContactsView and just pass the required information as extra option values.
I've decided my best option is to use the global namespace as suggested by Addy Osmani, BUT I think if I needed an alternative option then I would just set an instance specific property like so:
contacts_view.contact = new ContactView({
el: $('#view-contact')
});
I can then access the View's render() method from within contacts_view like so...
var ContactsView = Backbone.View.extend({
events: {
'change select': 'display_selected'
},
display_selected: function (event) {
this.contact.render(model);
}
});
...this feels cleaner than the single global namespace option but I'm worried that this alternative solution could get messy if I ended up needing to tie more than one View to ContactsView. I don't know why I would need to tie in more than one View but it's still a potential mess waiting to happen, so I think having a single global namespace is the best option (for now).
UPDATE: I've realised I can pass in additional data when creating a View instance and so that's what I've done here...
var contacts_view = new ContactsView({
el: $('#view-contacts'),
collection: contacts,
associated_view: new ContactView({
el: $('#view-contact'),
collection: contacts
})
});

Use of prototype for single instance functions in JavaScript

For performance optimization I'm using a single JavaScript file to handle all the pages of the website I'm working on.
The basic structure I'm using is as followed:
(function($) {
// Shared functions ...
// A function for every page
function Page1() {
}
Page1.prototype = {
init: function() {
//...
},
//more functions
};
// more pages
$(document).ready(function() {
if ($('#page1uniqueidentifier').length) {
var page1 = new Page1();
page1.init();
}
// more pages
}
}) (jQuery);
I'm not an experienced JavaScript programmer so I've been searching a lot about best practices and different ways of structuring my code and I've ended up choosing this one but I'm not really sure about it and I have a few questions:
Is it worth it to use prototype if I'm never gonna have more than a single instance of a page? I think I understand how prototype works and that I'm not gaining any performance there. But I'm using it just as a best practice because in the case different instances would exist, these functions would be the same in every instance.
Is there a better way to structure the code?
Should I put the call of the init function inside the constructor and then only call new Page1()?
function Page1() {
this.init();
}
if ($('#page1uniqueidentifier').length) {
new Page1();
}
For performance optimization I'm using a single JavaScript file to
handle all the pages of the website I'm working on
That makes no sense. You should separate code into files, and then run all your js files thru a minimizer/concatenator to package it up.
Anyway, to answer your questions,
if you are only going to have 1, then prototype won't buy you anything. However, if you are going to use more than 1, would you go back and change it? Plus, using prototype wont hurt you either, so you might as well do it for learning.
You should create the files that make sense according to the functionality implemented. I would separate your object definition into its own file, for example, so when you look at that file, all you see is the code for that object.
If you have a constructor function, you don't really need init, do you?

Understanding prototype method calls

In trying to call a method on the CodeMirror javascript code editor. I'm new to javascript and trying to understand how object oriented stuff works. I'm having problems calling what I believe are methods. For instance,
var editor = CodeMirror.fromTextArea('code', options);
editor.grabKeys(function(e) { alert("Key event");});
This gives the Uncaught TypeError: Cannot call method 'grabKeys' of undefined. Looking at the editor object reveals that grabKeys seems to be located at editor.__proto__.grabKeys.
How should I be thinking about this?
Probably yoour code should be something like this:
var editor = new CodeMirror.fromTextArea('code', options);
editor.grabKeys(function(e) { alert("Key event");});
Notice the 'new' operator..
Here is a good explanation of what prototype method calls are for:
http://www.javascriptkit.com/javatutors/proto.shtml

Categories