Why is this variable undefined within the object literal? - javascript

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

Related

In jQuery closure, how to get window property descriptor?

I want to see window property ‘otherName’ descriptor into jQuery closure. But
into jQuery closures 'otherName' descriptor is showing undefined, I think may
be getOwnPropertyDescriptor() did not get window object. Am i right? If I use
this code in plain js—
var otherName = "ckMe";
var result = Object.getOwnPropertyDescriptor(window, "otherName");
console.log(result);
// Object { value: "ckMe", writable: true, enumerable: true, configurable:
//false }
This is fine. But when this code in jQuery, I have got result = undefined.
(function ($) {
$(window).on("load", function (event) {
var otherName = "ckMe";
var result = Object.getOwnPropertyDescriptor(window, "otherName");
console.log(result);//undefined
});
}(jQuery));
Or if I use this code same result, undefined.
(function ($) {
$(function () {
var otherName = "ckMe";
var result = Object.getOwnPropertyDescriptor(window, "otherName");
console.log(result);//undefined
});
}(jQuery));
I want to use this code in jQuery closure because my all codes in there. I
was already searched this problem on google, but did not get any best
solution. Please help me. Thanks to all.
And sorry If I have anything wrong.
In your second two code blocks, otherName isn't a property of window. window only gets properties for var declarations at global scope. In your second two code blocks, the var declaration isn't at global scope, so otherName isn't a property of anything¹, it's just a local variable. They don't have property descriptors, because they aren't properties.
¹ "isn't a property of anything" - in specification terms, local variables are bindings on a Lexical Environment object. Bindings are a bit like properties, but they aren't properties (in the sense of JavaScript's object properties), and they don't have property descriptors (nor can you access the Lexical Environment object directly anyway — in fact, it may well not literally exist in any particular JavaScript engine).

Is this a naming convention or a function declaration

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.

Unable to access another object in javascript

I have uploaded a sample code where there are two objects defined using the modular pattern.
var obj1 = {
cachdom: function() {
// querying a dom element
this.$interactiveReport = $('#BugPreventiveIR_data_panel');
}
};
var obj2 = {
$IR: obj1.$interactiveReport,
logging: function() {
// This returns undefined
console.log(this.$IR);
}
};
// Invoking the Objects only after document is ready.
$(document).ready(function() {
console.clear();
interactiveReportRegion.init();
displayOfBugList.logging();
});
However, when I check in console the obj2.logging returns undefined for this.$IR. However, if I were to access obj1.$interactiveReport through console I can view the object values. Similairly, if I were to define the second object in the console again, it obtains the correct value for obj2.$IR.
Any reason I am unable to access the first object's properties in the second object?
My entire code can be found here
https://gist.github.com/alaghu/6225e50b35ecfdaf2ee8f752f596f49b
The logging function needs to know what "this" means since it's not a constructed object.. this should do it.
displayOfBugList.logging.apply(displayOfBugList);
defining a function changes the scope for "this". Consider using lamda functions to fix this. There is also the ability to bind what "this" is but I shy away from that method

Understanding the javascript function usage

I am trying to understand the below snippet of code in javascript. I have tried to google to check the usage of creating javascript function in the below format, but i did not find any references.
Below is the my understanding of the code and plz correct if this is what the code and appreciate any reference Guide to check more on this type of using notation.
function(obj) --> this is basically running a function in the global scope which is run on the load of the page after the DOM is loaded.
obj['test'] = 'DummyObj'; This is creating a global variable. I guess i am sure on this usage.
obj['test1'] = obj['test1'] || function(){
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
obj['test1'].m = 1 * new Date()
I am having trouble in understanding this. My analysis is this is checking for if test1 object is null it is creating a function and in that function it is checking for 'h' object and if it is null it is creating an Empty Array and pushing the local 'arguments' Object. I don't understand the second part where we have a comma and date object is created? Does it mean that it would execute as one statement and create a 'm' local variable with current Date value?
The last part where we are using (window) is what i don't understand completely. What does it mean? Can you please guide me where to further read on this
(function(obj) {
obj['test'] = 'DummyObj';
obj['test1'] = obj['test1'] || function(){
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
obj['test1'].m = 1 * new Date();
})(window);
I took the code you posted and marked it up with some comments that try to describe what is going on.
// wrap code in a self-executing function
// this creates a scope-boundary, but since you are not using
// the "var" keyword anywhere it doesn't matter much
// the "obj" argument is the global "window" variable
// made available by the execution content (most-likely your web-browser)
(function(obj) {
// create a "test" variable that live off of the "window" object
// so: window.test = 'DummyObj';
obj['test'] = 'DummyObj';
// if window.test1 is "truthy" then this will be a no-op
// otherwise, assign window.test1 to a function
obj['test1'] = obj['test1'] || function(){
// if window.test1.h doesn't have a value,
// assign it to an empty array
// Then, add the value of window.test1.h to the
// implicit "arguments" variable that comes with each function
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
}; // NOTE: I changed the comma here to a semi-colon
// set window.test1.m to the unix epoch integer value (in ms)
obj['test1'].m = 1 * new Date();
})(window);
Overall, I would say this code is cryptic and ugly. Assigning values within the same statements as a push to an array for example. Manually pushing to the arguments array is another.
I would not recommend using this code-snippit for learning JavaScript as it may teach you some anti-patterns.
This pattern (function(x) {})(y); is known as an immediately invoked function expression (IIFE) and is generally used to create a scope.
As for the rest, this is horrible garbage. Analyzing it is not terribly difficult but its really unclear why anyone would ever do any of this.
Here's the blow-by-blow:
//create a scope with the function wrapper, pass in the global
//window object under the alias 'obj'
(function(obj) {
//assign sting 'DummyObj' to the 'test' property of
//the global object, effectively creating a global variable
//and totally nullifying the reason for wrapping this in a
//function
obj['test'] = 'DummyObj';
//same thing but with the 'test1' global property/variable
//hese the logical or operator is used to conditionally
//assign the property. problem is *none* of this works,
//the following will throw:
obj['test1'] = obj['test1'] || function(){
//when called fn will attempt to conditionally assign
//an array to the h property of the test1 variable,
//ie the function itself. this is a bad idea. then it
//pushes the arguments on to that array. this is kinda
//sorta an attempt at making a function that caches its
//arguments, but it doesn't really work.
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
//1 * new Date() will yield a millisecond timestamp, but
//+new Date() and Date.now() are both clearer. note that
//this code is also assigning a random property to the
//function object stored in test1
obj['test1'].m = 1 * new Date();
})(window);

Is "this" necessary in javascript apart from variable definition

My question is dead simple.
I just casually discovered that once you have defined a property with this. into an object, you don't need to prepend this. anymore when you want to call them.
So this. is really meant to be used ad definition time, like var?
I found it my self shortly after, i was referencing the window object with this. since i called my object without using new, so like it was a function.
One extra question, maybe for comments. Inside the main object, if i create a new object, and use this during the object definition, this this what will be referring to?
No, unless the context of this is a global object, such as window. Take the following example:
function Foo(bar) {
this.data = bar;
console.log(this.data); // OK
console.log(data); // ReferenceError
}
In this example, you'll get a ReferenceError: data is not defined on the first console.log(data), unless, data is a global variable. To access the instance's public member, you have to use this.data.
References:
Understanding JavaScript’s this keyword
The this keyword
There are all sorts of circumstances where you MUST use this in order to reference the right data.
These two implementations do very different things:
Array.prototype.truncate(newLen) {
// sets the length property on the current Array object
this.length = newLen;
}
Array.prototype.truncate(newLen) {
// sets a global variable named length
length = newLen;
}
var arr = [1,2,3,4,5,6,7];
arr.truncate(2);
You MUST use this in order to control what happens if you want to modify the current object. Your assumption that you can leave it off and it will still modify the current object's properties is not correct. If you leave it off, you are modifying global variables, not member properties.
So this. is really meant to be used ad definition time, like var?
No, the point of this is to be the current scope of execution. You can (and will) run into weird errors if you don't use this. For example, imagine you are an object with a property val and then on the prototype of that object you have
App.obj = function(){
this.val = 'initial';
}
obj.prototype.myMethod = function(val) {
// how would you assign argument val to object val?
}
also note that your reasoning breaks down with methods.
obj.prototype.meth2 = function(){
myMethod(); // fails where this.myMethod() would work.
}
See http://jsfiddle.net/BRsqH/:
function f(){
this.public='hello!';
var hidden='TOP SECRET!';
}
var instance=new f();
alert('Public data: '+instance.public+ /* gives "hello!" */
'\nHidden data: '+instance.hidden /* gives undefined */
);
Variables created with var are hidden and cannot be viewed nor modified outside the function which created them.
But variables created with this are public, so you can access them outside the function.
I think I got it.
I defined my object as function My_Object(){...} and then called it with MyObject(). This way the My_Object was treated as a function, not an object and therefore this == window.
So in the end I was attaching properties and methods to window instead of My_Object! That's way there were available without prepending .this.
The right way to initialize My_Object as an object is to call it like this new My_Object, isn't right?

Categories

Resources