I am learning javascript and now started with objects and basic functions. I came across this type of code and was wondering what exactly is this
var stringFunction = function(){};
stringFunction.test1 = function(){
console.log("Test 1");
}
does test1 is a part of stringFunction or just a naming convention.Thanks in advance
Here test1() is a property (function type) of the stringFunction var.
So you defined a function in a function object.
You can use it by invoking stringFunction.test1(); as you can invoke the outer function : stringFunction();
var stringFunction = function(){console.log("Test stringFunction")};
stringFunction.test1 = function(){
console.log("Test 1");
}
stringFunction();
stringFunction.test1();
OUTPUT :
Test stringFunction
Test 1
function instances are sort of "weird" in Javascript as they are objects but their typeof is "function" and not "object".
They can however have properties added and accessed using either the syntax f.x or f["x"]. Your code simply adds a property to a function object (the value of the property is also a function, but that is irrelevant).
in JavaScript every function is a Function Object. see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function. In you sample the code create a property 'test1' on object stringFunction. The new property is itsealf a Function Object.
Related
I am pretty new in JavaScript and I always used it in something like old procedural way.
Now I am studying how to JavaScript implement the object oriented paradigm and I have some doubt on this example finded on a tutorial.
I have an utility.js file that contain this simple code:
var steveApp = {}; // Object container
steveApp.person = 'Steve'; // Add a person field to the steveApp object
steveApp.logPerson = function() {
console.log(steveApp.person);
}
So I have some doubt about how exaclty works it.
I think that first it define something like an empty object named steveApp by this line:
var steveApp = {}; // Object container
Then I think that the . it is used to add a field to the previous empty object, so I have:
steveApp.person = 'Steve';
that add a valorized person field to the steveApp object.
Finally it do a "strange" thing:
steveApp.logPerson = function() {
console.log(steveApp.person);
}
it seems to me that add a new field (named logPerson) to the steveApp object but this field is not a normal field (an integer, a string or another object) but it is a function that perform a behvavior (write a log in the console).
Then, into another JavaScript, file it do:
steveApp.logPerson();
and the previous function is perfromed. So what it exactly means? It means that in JavaScript a function could be a field of an object or what?
Abd why to call this function (if it is true that it is a field) I have to do:
steveApp.logPerson();
and not call the field name ?:
steveApp.logPerson;
Tnx
Functions are first class objects in JavaScript. They can be treated just like any other kind of data.
You can store them in variables, store them in properties, pass them as function arguments, etc.
Abd why to call this function (if it is true that it is a field) I have to do:
steveApp.logPerson();
Putting (zero_or_more_aguments_here) after something that evaluates as a function is how you call a function. Leaving them off gives you the function itself, not the result of calling it.
steveApp.logPerson(); //calls the function
while
steveApp.logPerson; // returns the function itself (NOT the return value of the function
you can also print it in the console and you will see:
console.log(steveApp.logPerson())
vs
console.log(steveApp.logPerson);
greetings
As mentioned by Quentin & I quote:
Functions are first class objects in JavaScript. They can be treated
just like any other kind of data.
You can store them in variables, store them in properties, pass them
as function arguments, etc.
Another important thing to know is that objects in JS are passed around or called by reference. They are never copied.
var a = {};
var b = {};
a.test = "hello";
b.test // returns undefined
Also
var a = {};
var b = a;
a.test = "hello"
b.test // return "hello"
And
var stooge = {first: "Jerome", second: "Howard"}
var x = stooge;
x.nickname = "curly";
var nick = stooge.nickname;
nick // returns "Curly"
The basics is that JavaScript is not strongly typed, so you could even assign different types to the same variables at different times:
var myVar = true;
myVar = 3.14;
myVar = "now a string";
alert("myVar is now a string with content: " + myVar);
myVar = function (someArg) {
alert("myVar is now a reference to a function, passed argument " + someArg);
return true;
}
myVar();
typeof myVar; // would return "function"
typeof myVar(); // would return "boolean"
As for your object "fields" (usually called properties), indeed they can receive any type that a normal variable would as well. Including a function, since they are "first-class citizen".
var myObject = {
myBool: true,
myNumber: 3.14,
myMethod: function (myArg) {
return myArg;
},
myNull: null
};
And like previously, you can even re-assign them later on…
Your assumptions are correct. But the difference between the below lines are
steveApp.logPerson();
Accessing logPerson property and invokes it as a function using ()
steveApp.logPerson;
It is just accessing the property logPerson, it returns the reference/value if it is used in RHS in an equation.
If you consider programming language like Scala, it is intelligent enough to infer whether it is a function call or not without using () but in JavaScript it is the reference, and if you try to invoke a normal property which is not a function. You will get an error saying logPerson is not a function.
I'm trying to store an object of selectors in jQuery for performance reasons and later use.
In some case, I may need to access a key in the same object literal I am creating.
(function($) {
'use strict';
var appCache = {
$navSecondary: $('#nav-secondary'),
$navMore: appCache.$navSecondary.find('.more')
};
})(jQuery);
The above code produces the error:
TypeError: appCache is undefined
how can I get around this? Would I have to perform the selection again in jQuery?
Thanks.
The right hand side of the assignment operator is evaluated first. The result is then passed left and assigned to the variable.
The variable is undefined while the object is being constructed, so you can't use its value (it has been declared though, var statements are hoisted).
You can assign a new property after the object has been created.
var appCache = {
$navSecondary: $('#nav-secondary')
};
appCache["$navMore"] = appCache.$navSecondary.find('.more');
var appCache = {
$navSecondary: $('#nav-secondary'),
$navMore: appCache.$navSecondary.find('.more')
^^^^^^^^
};
Because you are trying to access variable during its initialization.
You could use a function instead:
$navMore: function(){return this.$navSecondary.find('.more')}
Then call it once object is initialized:
appCache.$navMore(); // this will return set of jQuery matched elements
I define an object called anotherObject with a function called anotherFunction based on the someFunction from the object someObject.
var someObject={
someFunction:function(){
return this;
}
};
console.log(someObject.someFunction()===someObject);//true
var someFunc=someObject.someFunction;
console.log(someFunc===someObject.someFunction);//true
//the function does not have the same context as that of the function called earlier...
console.log(someFunc()===someObject);//false
var anotherObject={
anotherFunction:someObject.someFunction
};
console.log(anotherObject.anotherFunction===someObject.someFunction);//true
console.log(anotherObject[anotherFunction]()===anotherObject);//true;
console.log(anotherObject.anotherFunction()===someObject);//false
Firefox Scratchpad reports that the function anotherFunction is not defined.
That's the way JavaScript functions actually work, the someFunction is a function which its responsibility is to return the this in the current context, no matter what is for this one:
var someFunc=someObject.someFunction;
you can call it using call or apply with whatever context you like:
var myobj = {};
console.log(someFunc.call(myobj)===myobj);//true
console.log(someFunc.apply(myobj)===myobj);//true
no matter what you pass as the first argument in call and apply, your function would return that very object. So as you see your function does what it is supposed to do, but if you want it to always return your first object someObject, you do not need to use this keyword.
Read my answer to the How does JavaScript .prototype work?, I have tried to dig into this concept in the first two parts.
And also this is one of the best resources you can find about this concepts:
Understanding JavaScript Function Invocation and “this”
There are different ways of defining the javascript functions. I often use the simplest way to define the function
function myfunc(){
}
and the next way to define the function in the variable like this (a little bit confusing the way of using)
var myvar = myfunc(){
/*some code*/
}
and the difficult way for me and mostly found in codes developed by advanced programmers like the following
var SqueezeBox={presets:{onOpen:function(){},onClose:function(){}}
Please, can anyone clear my concept on this how can I use?
function myfunc(){}
Function declaration: the function is declared using the standard syntax
function functionName(params[]) {
//functionbody
}
Using this syntax declares the function at the begin of the scope execution, so they'll be available everywhere in their scope(and in their descendeant scopes).
var s = myfunc(); //s == 0
function myfunc() {return 0;}
var myfunc = function() {};
This uses the pattern known as function expression, it just assigns a reference of an anonymous function to a variable named myfunc. Using this syntax won't allow you to use the function until the variable is parsed. Even if variables are hoisted at the top of their scope, they're initialized when the interpreter parses them, so the above example won't work:
var s = myfunc(); //ReferenceError: myfunc is not defined
var myfunc = function() {return 0;};
But the example below will:
var myfunc = function() {return 0;};
var s = myfunc(); //s == 0
The third example is just assigning an anonymous function to an object property(also known as object method) in the way we've just done with function expression, so if I use the pattern above the code will become:
var onOpen = function() {},
onClose = function() {},
SqueezeBox = {//curly braces denotes an object literal
presets: {//again, this is a nested object literal
onOpen: onOpen,
onClose: onClose
}
};
This acts exactly the same as your example, with the only difference that here I used a variable to get a reference to the anonymous function before passing it to the object. If you need to know more about objects, I recommend you reading the MDN docs. Anyway, if you're really intrested in how JS works, I'd suggest Javascript Garden, which is a very good article about JS.
The first code snippet is a function declaration:
function myfunc() { }
You are declaring a named function called myfunc. You can verify this by myfunc.name === "myfunc"
Your second code snippet contains syntax error. I believe you meant:
var myvar = function() { };
This is an anonymous function expression assigned to a variable. You can verify this by typeof myvar === "function" and myvar.name === "".
The third snippet is a javascript object. Basically you can think of it as a Map or Dictionary<string, object>. So SqueezeBox contains 1 key presets, which in turn is a dictionary that contains 2 keys, onOpen and onClose, which both of them are anonymous functions.
In
var SqueezeBox={presets:{onOpen:function(){},onClose:function(){}}}
He's creating an object SqueezeBox containing another object presets with two empty anonymous functions, he's defining the function inline with an empty body inside the {}.
A better way to see it is formatted this way:
var SqueezeBox={
presets:{
onOpen:function(){/* empty function body */},
onClose:function(){/*empty function body */}
}
}
There is a lot of useful information on this subject here
Functions can have a name, which if specified cannot be changed. Functions can also be assigned to variables like any other object in javascript.
The first example is of a function declaration:
function myfunc(){
}
Using the function declaration you will be able to call the function from anywhere within the closure in which the function is declared, even if it is declared after it is used.
The other two examples are function expressions:
var myvar = function(){
/*some code*/
}
var SqueezeBox= {
presets: {
onOpen:function(){/* empty function body */},
onClose:function(){/*empty function body */}
}
}
Using function expressions you are assigning functions to a variable. When doing this you must declare them before you use them. Most of the time you see this the functions will be anonymous but it is possible to name a function in an expression:
var myvar = function myFunc(){
myFunc(); // Because it has a name you can now call it recursively
}
When doing this, the myFunc function is only available within the body of the function because it is still a function expression rather than a declaration.
The third example declares a javascript object literal, SqueezeBox and within that object there is another called presets. Within this object there are two more objects/labels called onOpen and onClose. This means you can do the following to use these functions:
SqueezeBox.presets.onOpen();
SqueezeBox.presets.onClose();
You can think of onOpen and onClose as variables that are part of the object. So it's very similar to doing the following (but the variable is only in the scope of the presets object which is only available within the SqueezeBox object).
var onOpen = function() {};
This has already been answered here: What is the difference between a function expression vs declaration in Javascript?.
For the last example, as Atropo said, it's affecting an anonymous function to an object. It's similar to the var example.
Let's say I instantiate an object in Javascript like this:
var myObj = new someObject();
Now, is it possible to obtain the var object's name as string 'myObj' from within one of the class methods?
Additional details (edited):
The reason why I would like to get the name of the variable holding reference to the object is that my new myObj would create a new clickable DIV on the page that would need to call a function myObj.someFunction(). As I insert the new DIV I need to know the name of the variable holding reference to the object. Is there maybe a better way of doing this?
You are right, sorry for the mixup in terminology.
The reason why I would like to get the name of the variable holding reference to the object is that my new myObj would create a new clickable DIV on the page that would need to call a function myObj.someFunction(). As I insert the new DIV I need to know the name of the variable holding reference to the object. Is there maybe a better way of doing this?
Shog9 is right that this doesn't make all that much sense to ask, since an object could be referred to by multiple variables. If you don't really care about that, and all you want is to find the name of one of the global variables that refers to that object, you could do the following hack:
function myClass() {
this.myName = function () {
// search through the global object for a name that resolves to this object
for (var name in this.global)
if (this.global[name] == this)
return name
}
}
// store the global object, which can be referred to as this at the top level, in a
// property on our prototype, so we can refer to it in our object's methods
myClass.prototype.global = this
// create a global variable referring to an object
var myVar = new myClass()
myVar.myName() // returns "myVar"
Note that this is an ugly hack, and should not be used in production code. If there is more than one variable referring to an object, you can't tell which one you'll get. It will only search the global variables, so it won't work if a variable is local to a function. In general, if you need to name something, you should pass the name in to the constructor when you create it.
edit: To respond to your clarification, if you need to be able to refer to something from an event handler, you shouldn't be referring to it by name, but instead add a function that refers to the object directly. Here's a quick example that I whipped up that shows something similar, I think, to what you're trying to do:
function myConstructor () {
this.count = 0
this.clickme = function () {
this.count += 1
alert(this.count)
}
var newDiv = document.createElement("div")
var contents = document.createTextNode("Click me!")
// This is the crucial part. We don't construct an onclick handler by creating a
// string, but instead we pass in a function that does what we want. In order to
// refer to the object, we can't use this directly (since that will refer to the
// div when running event handler), but we create an anonymous function with an
// argument and pass this in as that argument.
newDiv.onclick = (function (obj) {
return function () {
obj.clickme()
}
})(this)
newDiv.appendChild(contents)
document.getElementById("frobnozzle").appendChild(newDiv)
}
window.onload = function () {
var myVar = new myConstructor()
}
Short answer: No. myObj isn't the name of the object, it's the name of a variable holding a reference to the object - you could have any number of other variables holding a reference to the same object.
Now, if it's your program, then you make the rules: if you want to say that any given object will only be referenced by one variable, ever, and diligently enforce that in your code, then just set a property on the object with the name of the variable.
That said, i doubt what you're asking for is actually what you really want. Maybe describe your problem in a bit more detail...?
Pedantry: JavaScript doesn't have classes. someObject is a constructor function. Given a reference to an object, you can obtain a reference to the function that created it using the constructor property.
In response to the additional details you've provided:
The answer you're looking for can be found here: JavaScript Callback Scope (and in response to numerous other questions on SO - it's a common point of confusion for those new to JS). You just need to wrap the call to the object member in a closure that preserves access to the context object.
You can do it converting by the constructor to a string using .toString() :
function getObjectClass(obj){
if (typeof obj != "object" || obj === null) return false;
else return /(\w+)\(/.exec(obj.constructor.toString())[1];}
You might be able to achieve your goal by using it in a function, and then examining the function's source with toString():
var whatsMyName;
// Just do something with the whatsMyName variable, no matter what
function func() {var v = whatsMyName;}
// Now that we're using whatsMyName in a function, we could get the source code of the function as a string:
var source = func.toString();
// Then extract the variable name from the function source:
var result = /var v = (.[^;]*)/.exec(source);
alert(result[1]); // Should alert 'whatsMyName';
If you don't want to use a function constructor like in Brian's answer you can use Object.create() instead:-
var myVar = {
count: 0
}
myVar.init = function(n) {
this.count = n
this.newDiv()
}
myVar.newDiv = function() {
var newDiv = document.createElement("div")
var contents = document.createTextNode("Click me!")
var func = myVar.func(this)
newDiv.addEventListener ?
newDiv.addEventListener('click', func, false) :
newDiv.attachEvent('onclick', func)
newDiv.appendChild(contents)
document.getElementsByTagName("body")[0].appendChild(newDiv)
}
myVar.func = function (thys) {
return function() {
thys.clickme()
}
}
myVar.clickme = function () {
this.count += 1
alert(this.count)
}
myVar.init(2)
var myVar1 = Object.create(myVar)
myVar1.init(55)
var myVar2 = Object.create(myVar)
myVar2.init(150)
// etc
Strangely, I couldn't get the above to work using newDiv.onClick, but it works with newDiv.addEventListener / newDiv.attachEvent.
Since Object.create is newish, include the following code from Douglas Crockford for older browsers, including IE8.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o
return new F()
}
}
As a more elementary situation it would be nice IF this had a property that could reference it's referring variable (heads or tails) but unfortunately it only references the instantiation of the new coinSide object.
javascript: /* it would be nice but ... a solution NOT! */
function coinSide(){this.ref=this};
/* can .ref be set so as to identify it's referring variable? (heads or tails) */
heads = new coinSide();
tails = new coinSide();
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);
alert(["FF's Gecko engine shows:\n\ntoss.toSource() is ", toss.toSource()])
which always displays
[object Object]
and Firefox's Gecko engine shows:
toss.toSource() is ,#1={ref:#1#}
Of course, in this example, to resolve #1, and hence toss, it's simple enough to test toss==heads and toss==tails. This question, which is really asking if javascript has a call-by-name mechanism, motivates consideration of the counterpart, is there a call-by-value mechanism to determine the ACTUAL value of a variable? The example demonstrates that the "values" of both heads and tails are identical, yet alert(heads==tails) is false.
The self-reference can be coerced as follows:
(avoiding the object space hunt and possible ambiguities as noted in the How to get class object's name as a string in Javascript? solution)
javascript:
function assign(n,v){ eval( n +"="+ v ); eval( n +".ref='"+ n +"'" ) }
function coinSide(){};
assign("heads", "new coinSide()");
assign("tails", "new coinSide()");
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);
to display heads or tails.
It is perhaps an anathema to the essence of Javascript's language design, as an interpreted prototyping functional language, to have such capabilities as primitives.
A final consideration:
javascript:
item=new Object(); refName="item"; deferAgain="refName";
alert([deferAgain,eval(deferAgain),eval(eval(deferAgain))].join('\n'));
so, as stipulated ...
javascript:
function bindDIV(objName){
return eval( objName +'=new someObject("'+objName+'")' )
};
function someObject(objName){
this.div="\n<DIV onclick='window.opener."+ /* window.opener - hiccup!! */
objName+
".someFunction()'>clickable DIV</DIV>\n";
this.someFunction=function(){alert(['my variable object name is ',objName])}
};
with(window.open('','test').document){ /* see above hiccup */
write('<html>'+
bindDIV('DIVobj1').div+
bindDIV('DIV2').div+
(alias=bindDIV('multiply')).div+
'an aliased DIV clone'+multiply.div+
'</html>');
close();
};
void (0);
Is there a better way ... ?
"better" as in easier? Easier to program? Easier to understand? Easier as in faster execution? Or is it as in "... and now for something completely different"?
Immediately after the object is instantiatd, you can attach a property, say name, to the object and assign the string value you expect to it:
var myObj = new someClass();
myObj.name="myObj";
document.write(myObj.name);
Alternatively, the assignment can be made inside the codes of the class, i.e.
var someClass = function(P)
{ this.name=P;
// rest of the class definition...
};
var myObj = new someClass("myObj");
document.write(myObj.name);
Some time ago, I used this.
Perhaps you could try:
+function(){
var my_var = function get_this_name(){
alert("I " + this.init());
};
my_var.prototype.init = function(){
return my_var.name;
}
new my_var();
}();
Pop an Alert: "I get_this_name".
This is pretty old, but I ran across this question via Google, so perhaps this solution might be useful to others.
function GetObjectName(myObject){
var objectName=JSON.stringify(myObject).match(/"(.*?)"/)[1];
return objectName;
}
It just uses the browser's JSON parser and regex without cluttering up the DOM or your object too much.