Getting access to scoped objects - javascript

I have this code below:
<!DOCTYPE html>
<html>
<body>
<script>
function zz(){
var location = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
return this;
}
var abc= zz();
console.log(abc); //This works, but it is the the window objects location, I want the location I have defined
console.log(some code here to print out John);
console.log(some code here to print out Doe);
</script>
</body>
</html>
I choose location as the object name to learn about more about scope collision.
But now I can't figure out how to get to the variables I have defined. I know I have an object named location wrapped in a function zz
I know the object location has a firstName property of John
I know also the object location has a method fullName that will return the John Doe back to the calling reference.
So what do I need to do to output for example John to the console?
Thanks,

vars are only available within the scope which they are defined with the keyword var. I'm pretty sure that you actually want this inside your location Object to refer to your location Object, while you may want more methods in zz. Here is how that can be achieved:
function zzLoc(context){
this.firstName = 'John';
this.lastName = 'Doe';
this.id = 5566;
this.fullName = function(){
return this.firstName+' '+this.lastName;
}
this.parent = context;
}
function zz(){
this.location = function(){
return new zzLoc(this);
}
// more methods here
}
var wellNow = new zz, loc = wellNow.location();
console.log(loc.fullName());

How about this: Rather than use var, assign properties to this. And since it looks like you are trying to make an object constructor, try using the new keyword.
function zz() {
this.location = {
firstName: "John",
lastName: "Doe",
id: 5566,
fullName: function () {
return this.firstName + " " + this.lastName;
}
};
this.getFirstName = function () {
return this.location.firstName;
};
this.getLastName = function () {
return this.location.lastName;
};
}
var abc = new zz();
console.log(abc); // zz { location={...}, getFirstName=function(), getLastName=function()}
console.log(abc.getFirstName(), abc.location.firstName); //John, John
console.log(abc.getLastName(), abc.location.lastName); //Doe, Doe
console.log(abc.location.fullName()); //John Doe

Related

Why should I use javascript call method?

I'm trying to understand the call and apply methods in javascript. But I didn't understand why I should use it.
var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
var person2 = {
firstName:"Mary",
lastName: "Doe"
}
var x = person.fullName.call(person1);
I can do this example without using call and apply.
var person = {
fullName: function(firstName, lastName) {
return firstName + " " + lastName;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
var person2 = {
firstName:"Mary",
lastName: "Doe"
}
var x = person.fullName(person1.firstName, person1.lastName);
Or I don't understand this example.
function Product(name) {
this.name = name;
}
function Pizza(name) {
Product.call(this,name);
}
const pizza = new Pizza("Margherita");
When I think of this example, I can do with the prototype. Why use call or apply? Thank you
A good use case is when you want to 'borrow' a function with a different context. Take the example below, you can definitely use inheritance to give Cat the bark function but maybe you don't want that function to exist on every instance but only want to use it in certain situations.
function Dog(name) {
this.name = name
this.bark = function() {
console.log('woof' + this.name)
}
}
const dog = new Dog('spot')
dog.bark() // woofspot
function Cat(name) {
this.name = name
}
const cat = new Cat('cat')
dog.bark.call(cat) // woofcat
function Product(name) {
this.name = name;
}
function Pizza(name) {
Product.call(this,name);
}
const pizza = new Pizza("Margherita");
That's inheritance. Pizza is a product. In other languages, for example PHP, inheritance looks like this:
class Foo {
public function __construct() {
// Do stuff specific for Foo
}
}
class Bar extends Foo {
public function __construct()(
parent::__construct();
// Do stuff specific for Bar
}
}
Here, we don't have extends and in order to make it work, you need to say that the this in the parent constructor is the child.
Using call, you can say what the this in the Product() function/constructor is.
In this case, it is the Pizza object (the new created an object {}). Without using call, Pizza wouldn't even have a name.
The same goes for your first example
var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
var person2 = {
firstName:"Mary",
lastName: "Doe"
}
var x = person.fullName.call(person1);
Yes, it worked without calling call but not without drastic changes.
person.fullName.call(person1); is like saying take this function and permute this with my person1 object. So in the end, it is as though you did this:
return person1.firstName + " " + person1.lastName;
As to which one to use
Note: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.
As far as I know, it is all a matter of preference on which you use, but you must use call and/or apply, you cannot do it without them.

When does aPerson.firstname and aPerson.lastname actually change in this code snippet?

I'm going through some JavaScript koans to learn the language syntax and I'm confused by this set of tests:
it("should know that variables inside a constructor and constructor args are private", function () {
function Person(firstname, lastname)
{
var fullName = firstname + " " + lastname;
this.getFirstName = function () { return firstname; };
this.getLastName = function () { return lastname; };
this.getFullName = function () { return fullName; };
}
var aPerson = new Person ("John", "Smith");
aPerson.firstname = "Penny";
aPerson.lastname = "Andrews";
aPerson.fullName = "Penny Andrews";
expect(aPerson.getFirstName()).toBe("John");
expect(aPerson.getLastName()).toBe("Smith");
expect(aPerson.getFullName()).toBe("John Smith");
aPerson.getFullName = function () {
return aPerson.lastname + ", " + aPerson.firstname;
};
expect(aPerson.getFullName()).toBe("Andrews, Penny");
});
I get that the variables inside a constructor are private, and that's why "John Smith" still prints when calling getFullName() even after attempting to set aPerson.firstname, lastname, and fullName. But then a function is created called getFullName(), and then after that calling the function "Andrews, Penny" prints.
I would have expected "Smith, John" to print since this new function was created after the "failed" attempt to set firstname to "Penny" and lastname to "Andrews". Why does "Andrews, Penny" print?
Thanks
The key here is the new operator; var aPerson = new Person ("John", "Smith") creates a new Person, passing in John and Smith as the names used by the Person function, and assigning the new instance of the function to the variable aPerson.
Note the var fullName = firstname + " " + lastname inside of the Person function. This takes whatever is passed through as the function parameter at the time the Person function is called. At this point, this.getFullName will be equal to John Smith.
When you run aPerson.firstname = "Penny"
this only updates the new instance of the Person; it doesn't modify the original Person function. When you call aPerson.getFirstName(), the getFirstName() method returns what was originally set as firstname for Person (John), not what has been set for the new instance aPerson (Penny).
As such, the first time you call aPerson.getFullName(), the name is John Smith.
Your new function aPerson.getFullName = function () { } returns aPerson.lastname + ", " + aPerson.firstname. Unlike the previous function, this takes the last and first name from the new instance of Person (Penny Andrews).
As such, the second time you call aPerson.getFullName(), the name is Penny Andrews.
Hope this helps! :)
First, you need to understand this:
function Person(firstname, lastname)
{
var fullName = firstname + " " + lastname;
...
}
var aPerson = new Person ("John", "Smith");
Here, the only thing you created was an object with only methods on it, not even attributes, like firstname, lastname. (Parameters and variables declared with var aren't attached to your object)
So your object aPerson is like this:
{
getFirstName: function(), // => John
getLastName: function(), // => Smith
getFullName: function() // => John Smith
}
Then:
aPerson.firstname = "Penny";
aPerson.lastname = "Andrews";
aPerson.fullName = "Penny Andrews";
You assigned on your aPerson object new attributes. So, it becomes like this:
{
firstname: "Penny",
lastname: "Andrews",
fullName: "Penny Andrews",
getFirstName: function(), // => John
getLastName: function(), // => Smith
getFullName: function() // => John Smith
}
Next, you overriding getFullName with this:
aPerson.getFullName = function () {
return aPerson.lastname + ", " + aPerson.firstname;
};
As your can see, you use these new attributes.
Now, you should be able to understand your result.
If you do the replacement, you get this:
aPerson.getFullName = function () {
return aPerson.lastname + ", " + aPerson.firstname;
// Andrews , Penny
};
And voilĂ  ! It's why you get your result ;)

Can a function be declared as a variable in JavaScript?

Consider the following JavaScript object definition :
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
I know that if we want to use the object property(i.e. a function) we have to write the following code :
person.fullName();
As per my knowledge, JavaScript objects are containers for named values called properties or methods.
Also, I know that I can define the object properties like firstName, lastName, id as individual variables.
Now, my question is can I also define the function "fullName" as a variable? If it is possible then how? and if not then why?
Thank You.
It is possible. Note that your code is equivalent to this code:
var person = {};
person.firstName = "John";
person.lastName = "Doe";
person.id = 5566;
person.fullName = function() {
return this.firstName + " " + this.lastName;
}
The important bit to see is that function() { return this.firstName + " " + this.lastName; } (or rather, the result of evaluation of that string of code) is a value, just like 5566 is, and can be contained in a property, or a variable, or an array... just like 5566 can. The only difference is, one is a number, the other - a function.
Besides the original example of a function stored in a property ("method"), here is an example of a functional value being stored in a variable:
var sayHello = function(name) { console.log("Hello, " + name); }
Here it is in an array:
var adders = [
function(x) { return a; },
function(x) { return (a + 1) % 3; }
function(x) { return (a + 2) % 3; }
];
Here it is being passed as a parameter:
function twice(f, x) {
return f(f(x));
}
twice(function(x) { return x * 2; }, 7);
// 28
Yes
Here is simple answer with example to your question
jQuery(document).ready(function() {
window.$ = jQuery;
initializeGlobelCalls.init();
});
var initializeGlobelCalls = function () {
var validatefunction = function() {
$(document).on('click','#divid',function(){//event trigger when you want to call function
//your function code
});
};
return {
init: function () {
validatefuction();//can add multiple functions here
}
};
}();
with this structure you can write multiple functions ,first need to define function like validatefunction and then add into init
It is not possible unless you generate fullName when creating the object such as the following:
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : ''
};
person.fullName = person.firstName + person.lastName;
Otherwise there's no way to create a static variable only one that will be created by the function when called (such as in your original example).
That is not possible because by the way JavaScript was designed, you can't have dynamic properties assigned statically (apart from ES6 getters as cited below, which will still generate the value on every call) in a way that they'll only be generated once automatically without some kind of algorithm from your part or a library to do that for you.
As I cited above, you can try ES6 getters but that will only make it look like a property, it will still get called every time it is accessed:
Example:
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
get fullName() { return this.firstName + ' ' + this.lastName; }
};
Then you'd access it like this: person.fullName
In JavaScript a variable can point to function as well.
Example:
var fullName = function(param) {
return param;
}
console. log(fullName('some text'));

Javascript revealing module pattern and variables

My question is precisely the same as this one Javascript revealing module pattern, public properties
In that thread, the answer was given but not the "why". Here's the same question restated with my own example:
myApp.User = function () {
var firstName = 'Default',
lastName = 'Default';
function setFirstName(name) {
firstName = name;
}
function setLastName(name) {
lastName = name;
}
function getFirstName() {
return firstName;
}
function getLastName() {
return lastName;
}
return {
getLastName: getLastName,
**getFirstName: getFirstName**,
setLastName: setLastName,
setFirstName: firstName
};
};
In this scenario, User().getFirstName always evals to "Default" -- even if I change it to some other value via the setFirstName function.
If I replace with setFirstName like:
return {
getLastName: getLastName,
**getFirstName: getFirstName**,
setLastName: setLastName,
setFirstName: firstName
};
I am able to access the changed value. I understand that the var firstName is passed by value which is why the updated values are not reflected. I don't understand what is special about the function. Where is the pointer to the value within the function living? Why do all the functions "magically" get access to the update(s)?
Where is the pointer to the value within the function living?
In the scope of the function - which contains all the variables it has access to. This access makes the function a closure actually.
Why do all the functions "magically" get access to the update(s)?
Because all the functions share the variables declared in a higher scope.
They don't "magically" get access to the update. They are inside myApp.User that's why they can access the variable location.
When you do myApp.User().getFirstName(), because getFirstName is inside the function (scope), it will be able to access variables declared both inside this function and outside this function.
function a(){
var b = "hello";
return {
setB: function(c){ b = c; },
getB: function(){ return b; }
};
}
var obj = new a();
obj.getB(); //hello
obj.setB("new");
obj.getB(); //new
In the example above, getB and setB both live inside your object, and they can access all variables inside the a() scope.
look at what you did here in your first example
setFirstName: firstName
setFirstName is not a reference to the function "setFirstName" but rather the variable 'firstName'... you don't have access to the function 'setFirstName'. That function is still unavailable to you, so you can't modify firstName, like you want.
It is out of scope - you didn't return it, so that it is available to the outside world, so to speak. It is not available "outside" of the scope of the function. Return the function (), and apply the "setFirstName", as shown below.
try this;
myApp.User = function () {
var firstName = 'Default',
lastName = 'Default';
function setFirstName(name) {
firstName = name;
}
function setLastName(name) {
lastName = name;
}
function getFirstName() {
return firstName;
}
function getLastName() {
return lastName;
}
return {
getLastName: getLastName,
getFirstName: getFirstName,
setLastName: setLastName,
setFirstName: setFirstName
};
}();
myApp.User.setFirstName('bill');
myApp.User.getFirstName();
var User = function () {
var firstName = 'Default',
lastName = 'Default';
return {
getLastName: function() { return lastName; },
getFirstName: function() { return firstName; },
setLastName: function(name) { lastName = name; },
setFirstName: function(name) { firstName = name; },
getName: function() { return firstName + ' ' + lastName; }
};
};
var u = User(),
v = User();
console.log( u.getName() + ' - ' + v.getName() );
// Outputs: 'Default Default - Default Default'
u.setFirstName( 'Alice' );
u.setLastName( 'Bob' );
console.log( u.getName() + ' - ' + v.getName() );
// Outputs: 'Alice Bob - Default Default'

In JavaScript: Syntax difference between function & method definition within a class

The Object class has both methods and functions meaning they both are accessed through Object.nameOfMethodOrFunction(). The following question What is the difference between a method and a function explains the difference between a method and and a function, but it doesn't explain how to create them within an object. For example, the code below defines the method sayHi. But how do you define a function inside the same object?
var johnDoe =
{
fName : 'John',
lName: 'Doe',
sayHi: function()
{
return 'Hi There';
}
};
The following defines two classes, ClassA and ClassB, with equal functionality but different in nature:
function ClassA(name){
this.name = name;
// Defines method ClassA.say in a particular instance of ClassA
this.say = function(){
return "Hi, I am " + this.name;
}
}
function ClassB(name){
this.name = name;
}
// Defines method ClassB.say in the prototype of ClassB
ClassB.prototype.say = function(){
return "Hi, I am " + this.name;
}
As shown below, they doesn't differ much in usage, and they are both "methods".
var a = new ClassA("Alex");
alert(a.say());
var b = new ClassB("John");
alert(b.say());
So now what you mean for "function", according to the msdn link that you gave as a comment, seems that "function" is just a "static method" like in C# or Java?
// So here is a "static method", or "function"?
ClassA.createWithRandomName = function(){
return new ClassA("RandomName"); // Obviously not random, but just pretend it is.
}
var a2 = ClassA.createWithRandomName(); // Calling a "function"?
alert(a2.say()); // OK here we are still calling a method.
So this is what you have in your question:
var johnDoe =
{
fName : 'John',
lName: 'Doe',
sayHi: function()
{
return 'Hi There';
}
};
OK, this is an Object, but obviously not a class.
Quoting Aaron with "A method is on an object. A function is independent of an object".
Logically a method is useless without a "this" defined.
Consider this example:
var johnDoe =
{
fName: 'John',
lName: 'Doe',
sayHi: function () {
return 'Hi There, my name is ' + this.fName;
}
};
function sayHi2() {
return 'Hi There, my last name is ' + this.lName;
}
//Will print Hi there, my first name is John
alert(johnDoe.sayHi());
//An undefined will be seen since there is no defined "this" in SayHi2.
alert(sayHi2());
//Call it properly now, using the oject johnDoe for the "this"
//Will print Hi there, my last name is Doe.
alert(sayHi2.call(johnDoe));
var johnDoe = {
fName: 'John',
lName: 'Doe',
sayHi: function(){
function message(){ return 'Hi there'; }
return message();
}
};
That's about as good as you're going to get with the object declaration method of creating a 'class' in JavaScript. Just keep in mind that function is only valid within sayHi's scope.
However, if you use a function as a class structure, you have a little more flexibility:
var johnDoe = function(){
this.publicFunction = function(){
};
var privateFunction = function(){
};
};
var jd = new johnDoe();
jd.publicFunction(); // accessible
jd.privateFunction(); // inaccessible
(though both are really considered methods since they have access to the object's scope within).

Categories

Resources