I'm learning to use dojo for a project I'm about to undertake and so confess in advance this is probably a very basic question. I've tried to find the answer but without success. Also, I'm having to use a slightly older version of dojo - 1.6 I think so without AMD.
I've delcared a class using dojo.declare, here is a slightly modified example:
dojo.declare("myNamespace.CustomClass", null, {
firstProperty: "The default value",
constructor: function () { }
Test: function () {
alert(this.firstProperty);
}
});
So, essentially, a class called CustomClass with a public property called firstProperty that has a default value of "The default value", a constructor that doesn't currently do anything and a public method called Test that when called will alert with the value of firstProperty.
My assumption was that when I create an instance of CustomClass and call Test() I would get an alert box with "The default value". However, I don't, I get an alert box with "undefined" instead. If I set the value of firstProperty after the instance has been created and then call Test, it works and I get whatever the property had been set to. A way around would therefore be to set the default values in the constructor but what I've read suggests it should work the way I assumed so I'd rather do it correctly.
I've also tried calling dojo.safeMixin(this, null) in the constructor as something I read made my wonder if this was required, but it didn't make a difference.
Thanks in advance to anyway that reads this!
Simon
The key concept you are missing is the concept of scope. when you do alert(firstProperty);, you are referring to a local variable firstProperty. Which, in your case you have not defined any local variable wit that name. You have, however defined an instance variable with that name. Unlike in a language such as java, instance variables must be accessed explicitly using this.
So your example should be:
dojo.declare("myNamespace.CustomClass", null, {
firstProperty: "The default value",
constructor:function(params){
console.log(params);
dojo.safeMixin(this,params);
},
Test: function () {
alert(this.firstProperty);
}
});
var myInstance = new myNamespace.CustomClass({firstProperty:'something else'});
myInstance.Test();
You might also want to take a look at Javascript Scope Tricks, since scope in javascript can get pretty tricky.
EDIT: I realized you weren't inherited from dijit._Widget. In that case, you need to manually apply the constructor parameters to the instance using dojo.safeMixin. I updated the code example above. I also created a simple jsfiddle demonstrating the code.
Related
I'm sure someone is going to shout at me for asking this question, but here goes: in Javascript, what is the best strategy for coping with the fact that the properties of objects are case-sensitive? If I create an object with a property called FavouriteDrink, but then I later start referring to it as favouriteDrink then I could end up in a mess.
I don't want a big library here, but is there any way to define the object so that FavouriteDrink is defined somewhere, and where in Visual Studio 2012 some intellisense will help me choose the correct property name if I can somehow contextualise the object I'm dealing with? It is only properties I'm pondering here.
Thanks.
It doesn't work this way
if i look at your your code and see :
FavouriteDrink() {}
the first thing will popup in my mind is this is a constructor function not just a normal function
and by looking at this following one
favouriteDrink() {}
i would tell that this is a normal function and i can't use it as a constructor - can't be called with new
Here is some other examples
first_name // variable
FIRST_NAME // uppercase variables shouldn't change
_first_name // local variable not intended to be used out of its scope
var FIRSTNAME = {} // name space
it’s a good idea to follow a convention as to how the words will be separated
see this Code Conventions for the JavaScript Programming Language
For the other part of your question i'm using VS 2012 and i installed JSEnhancements
and i can see all my object element
JavaScript shares the following conventions with Java and ActionScript 3.
ALL_UPPERCASE
Use this as the variable name when you define a constant, or a value that should never change.
For example, myObject.NUM_TIMES_CLICKED = 2 would be a poor candidate for a constant because it is likely to change. However, myObject.APPLE_FRENCH_SPELLING = 'pomme' would be appropriate here.
firstWordLowercaseAndTheRestAllUppercase
Use this when you are defining anything that is not a constant or a class. You would use this for most things, for example, myObject.numTimesClicked, myObject.myFunction(), myObject.returnString.
AllWordsCapitalized
Use this when you are defining a function that defines a "class," generally any function you would call with the syntax myObject.myClassInstance = new MyClass(). Notice how myClassInstance is in camel-case because it is an instance of the class. However, MyClass is all caps because it is meant to be invoked with new.
You would define the class initially like this: myObject.MyClass = function(){};
WebStorm and Sublime Text are great tools that offer the code intelligence you're looking for.
WebStorm does this out of the box, but my personal preference is Sublime Text with the SublimeCodeIntel plugin.
That being said, it's probably best for you to be using naming conventions:
UpperCamelCase is for classes
ALL_CAPS_SNAKE_CASE is for constants
lowerCamelCase is used for everything else
I'm looking for a way to inject properties from "this" into local function scope, so i dont need write 'this.' when referencing to this properties.
Exact details are displayed in this code http://jsfiddle.net/wwVhu/3/, look at this part
...
//it's how it works
doStuff: function(param) { $('#output').html(this.value + param) }
//it's how i want it work - without referencing to this
//doStuff: function(param) { $('#output').html(value + param) }
I know it could be achieved by wrapping function code in "with(this) { ... }", but what are other options?
Writing "with(this)" in the beginning of every method or using js aop is what i'm trying to avoid.
Why would you want to do this? It's namespaced because it makes sence. this references to the element the listener is listening on. And it contains a lot more information than just the value.
If you want the value in another variable, you can do:
var value = this.value
There are basically four options:
You keep it the way it is. Context and local scope are different objects, combining them is bad practice and leads to collisions.
You add the value property as the 2nd parameter to the doStuff function.
You nickname this with a shorter identifier. I often find myself use $t.
You use with(this) $('#output').html(value + param);. This is a bad coding practice, as explained in 1). Your code becomes broken the second there is a param property in this.
I'm wanting to directly update the object referred by a function argument from within the scope of that function. An example:
var thisObj = { "val" : "original value" };
function modFunc(objRef) {
objRef = { "val" : "modified" };
console.log(objRef); // { "val" : "modified" }
}
console.log(thisObj); // { "val" : "original value" };
I understand why this happens, and I realize that I could have used
objRef.val = "modified";
within modFunc to perform the modification. For reasons specific to my project though, I would like to be able to accomplish something like:
function modFunc(objRef) {
objRef.self = { "val" : "modified" }; // Of course this will not work,
// but is there an Object property or method that allows one to access
// the actual memory pointer being referenced by the variable?
}
where I can specify that I want to directly modify thisObj to reference the new object that I instantiate within modFunc. Is this possible? I know there are tools like Object.assign() that I could use to do this but it's not supported universally, or library tools like bind() that I could use if I imported the library, but it just seems like there might be some native syntax that would allow me to do this and I just haven't been able to find it?..
I've spent some time looking, otherwise I try not to ask questions like this. I also know there are other similar posts to this one, but nothing exactly like what I'm asking and I don't have the 'reputation' here to be able to respond directly to posts etc. so I didn't see an easy way to focus the discussion. Anyway, thanks for any help!
What you're asking for is, essentially, a call-by-reference mechanism, or the ability to explicitly create a reference to a variable. In JavaScript, that's not possible. You can (as you note) pass around references to objects and use those to modify object property values (and to add and remove properties, even), but that's not quite the same thing.
This would be true assignment by reference which javascript doesn't support. It only supports the false, misunderstood kind of assignment by reference.
since you cant deal with references, you can simply make objRef a global variable, and not pass it as an arg at all. then you're updating the original object.
I was playing with class/function/prototype inheritance a bit and got a decent setup working. Something simple that I understand.
http://jsfiddle.net/rudiedirkx/rwPeD/6/
For debugging purposes, I wanted to print in each constructor what kind of object was calling that constructor. For instance the Ronin constructor calls the Ninja constructor and that calls the Person constructor. For that I made a get_class function:
function get_class(obj) {
var C = String(obj.__proto__.constructor);
return C.match(/function (\w+)\(/, C)[1];
}
and that doesn't work. It always returns "Person". Why? Every 'class' has its own constructor, doesn't it? If I do a console.log(this) in every constructor, Chrome Devtools knows which type the object is. How do I get there (with vanilla JS)?
PS. Full output in my Chrome:
Or you could do something that actually works...
function getClass(obj) {
return obj.__proto__.constructor.name;
}
obj.attr("class") only works if the method attr exists with it won't in a native environment.
Still your suggestion was very good in it's design.
Please note that proto.constructor.name will always return "Object" if the class is not a native class, such as Array, String, RegExp, Error, etc... If anyone knows how to convince the "name" property to return the real name, even if I have to add code to do it, I would buy him a banana for his/her trouble.
I think the problem refers to following line. this.prototype.constructor points to what Person.prototype points to.
this.prototype = Object.create(sup.prototype);
You may need change its reference explicitly.
this.prototype.constructor = this;
The similar question can be found at Get name of derived constructor in Javascript
Excuse me first. because i don't know this is question is valid or not. i if any one clear my doubt then i am happy.
Basically : what is the different between calling a method like:
object.methodname();
$('#element').methodname();
calling both way is working, but what is the different between, in which criteria make first and second type of methods. is it available in the core javascript as well?
In case if i have a function is it possible to make 2 type of method call always?
Can any one give some good reference to understand correctly?
Thanks in advance.
The first syntax:
object.methodName();
Says to call a function, methodName(), that is defined as a property of object.
The second syntax:
$('#element').methodname();
Says to call a function called $() which (in order for this to work) must return an object and then call methodname() on that returned object.
You said that "calling both way is working," - so presumably you've got some code something like this:
var myObject = $('#element');
myObject.methodname();
This concept of storing the result of the $() function in a variable is commonly called "caching" the jQuery object, and is more efficient if you plan to call a lot of methods on that object because every time you call the jQuery $() function it creates another jQuery object.
"Is it available in the core javascript as well?" Yes, if you implement functions that return objects. That is, JS supports this (it would have to, since jQuery is just a JS library) but it doesn't happen automatically, you have to write appropriate function code. For example:
function getObject() {
return {
myMethod1 : function() { alert("myMethod1"); return this; },
myMethod2 : function() { alert("myMethod2"); return this; }
};
}
getObject().myMethod1().myMethod2();
In my opinion explaining this concept in more depth is beyond the scope of a Stack Overflow answer - you need to read some JavaScript tutorials. MDN's Working With Objects article is a good place to start once you have learned the JS fundamentals (it could be argued that working with objects is a JS fundamental, but obviously I mean even more fundamental stuff than that).
The difference is very subtle.
object.methodname();
This is when JavaScript has the object at hand.
$('#element').methodname();
If you are using jQuery, you are asking jQuery to select the object that has the id of #element. After that you invoke the method on the selected object.