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'
Related
I was doing some testing and I got no clue why if using call I inherit from another object like, const objC = funcB.call(objA,'Erades') I got an object, but if I inherit from a function I got a function with wired (to me) behavior.
I don't understand why to get method B I have to do funcC.getLastName()
If anybody can help me to understand this...
TIA
// testing Call to inherit objects / functions
// -------------------------------------------
// we declare our first function
const funcA = function(firstName) {
this.firstName = firstName;
this.getFirstName = function() {
return 'My name is ' + this.firstName;
};
return this;
};
// Create an object out of that function
const objA = new funcA('Rodrigo');
// declare second function
const funcB = function (lastName) {
this.lastName = lastName;
this.getLastName = function() {
return 'My last name is ' + this.lastName;
};
return this;
};
// Create an Object from funcB and ObjectA
const objC = funcB.call(objA,'Erades');
// We get an object
console.log("TYPE OF: ", typeof objC)
console.log('raw:', objC);
console.log('method A: ', objC.getFirstName());
console.log('prop A: ', objC.firstName);
console.log('method B: ', objC.getLastName());
console.log('prop B: ', objC.lastName);
console.log('------------');
// if we don't want to create an object out of a function and an object,
// we could also inherit two functions, but the result really surprise me
const funcC = funcB.call(funcA,'Alonso');
// We get a function !!!!!
console.log("TYPE OF: ", typeof funcC);
console.log('raw:', funcC);
// To get result we need to do this:
console.log('method ==>: ', funcC('Rui'));
console.log('method A: ', funcC('Rui').getFirstName());
console.log('prop A: ', funcC('Maria').firstName);
console.log('method B: ', funcC.getLastName()); // looks like static method ???
console.log('prop B: ', funcC.lastName);
console.log('------------');
You're not inheriting when you use call this way. You are passing an instance in and getting the same instance out with some modifications:
const funcA = function(firstName) {
this.firstName = firstName;
this.getFirstName = function() {
return 'My name is ' + this.firstName;
};
return this;
};
const objA = new funcA('Rodrigo');
const funcB = function (lastName) {
this.lastName = lastName;
this.getLastName = function() {
return 'My last name is ' + this.lastName;
};
return this;
};
const objC = funcB.call(objA,'Erades');
// ObjC IS ObjaA
console.log(objC === objA)
When you use call the object passed in becomes the this of the function. You then add some properties and return this which is the same object you just passed in.
Passing a function to call() is no different. When you write:
funcB.call(funcA,'Alonso');
you are calling the function funcB with Alonso as an argument. Inside that function this will refer to funcA. So you will set a lastName property on funcA and getLastName property pointing to a function, then return funcA which is then assigned to the variable funcC. funcC and funcA point to exactly the same function.
const funcA = function(firstName) {
this.firstName = firstName;
this.getFirstName = function() {
return 'My name is ' + this.firstName;
};
return this;
};
const funcB = function (lastName) {
this.lastName = lastName;
this.getLastName = function() {
return 'My last name is ' + this.lastName;
};
return this;
};
const funcC = funcB.call(funcA,'Alonso');
// the same reference
console.log(funcC === funcA)
// but when you called funcB with it, it added some properties:
console.log("funC lastname:", funcC.lastName)
// they are the same object so this also works:
console.log("also funcA lastname:", funcC.lastName)
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'));
function User() {
this.firstname = null;
get getFirst() {
return this.firstname;
}
}
JavaScript console gives me an error saying "Unexpected Identifier" on line 12
var Jake = new User();
Jake.firstname = "Jake";
document.write(Jake.getFirst);
That's just not the syntax you use to define a getter. You'd use it in an object literal, like this:
var foo = {
get bar() {
return 42;
}
};
foo.bar; // 42
...but that's not where your get is.
To define it where your get is, you'd use defineProperty:
function User() {
this.firstname = null;
Object.defineProperty(this, "first", {
get: function() {
return this.firstname;
}
});
}
Note I called it first, not getFirst, because it's an accessor function, which looks like a direct property access, and so is traditionally not given a name in a verb form:
var u = new User();
u.firstname = "Paul";
u.first; // "Paul"
If you wanted to create a function called getFirst, just get rid of the get keyword:
this.getFirst = function() {
return firstname;
};
// ...
var u = new User();
u.firstname = "Paul";
u.getFirst(); // "Paul"
I believe the issue is that you are using get with a function rather than the object literal as outlined in the documentation.
var User = {
firstName: 'Darren',
get getFirst() { return this.firstName; }
}
alert(User.getFirst);
https://jsfiddle.net/ecao51n0/
get is intended to be called within an object, not a function constructor. If you want to declare getFirst as a function on User, then here's one way you could do it:
function User() {
this.firstname = null;
this.getFirst = function() {
return this.firstname;
}
}
Then you would also need to call getFirst as a function:
var Jake = new User();
Jake.firstname = "Jake";
document.write(Jake.getFirst());
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
This question already has answers here:
Javascript: Do I need to put this.var for every variable in an object?
(6 answers)
Closed 9 years ago.
I am new to javascript. I was doing some hands on "object literals". Below is the code i was trying. BodyLoaded is the event handler for onload event of body tag.
//works - getName returns "bingo"
function BodyLoaded()
{
var dog = {
name: "defaultname",
getName: function () {
return name;
},
setName: function (n) {
name = n;
}
};
dog.setName("bingo");
console.log(dog.getName());
}
//works too - getName returns "bingo"
function BodyLoaded()
{
var dog = {
name: "defaultname",
getName: function () {
return this.name;
},
setName: function (n) {
this.name = n;
}
};
dog.setName("bingo");
console.log(dog.getName());
}
//doesnt work - getName returns ""
function BodyLoaded()
{
var dog = {
name: "defaultname",
getName: function () {
return this.name;
},
setName: function (n) {
name = n;
}
};
dog.setName("bingo");
console.log(dog.getName());
}
The above code returns expected result when calling getName ("bingo"). But if I return this.name in the getName function, it returns and empty string. The strange part is, if i use this.name in both the functions (setName and getName) the code works fine and returns the expected value("bingo"). Trying to understand this behavior.
When you return name from the method, it actually returns the window.name because there is not context involved.
When you call this.name, this points to the dog object which has a name property so it returns that.
If you don't specify this when setting the name value the actual variable that gets set will be window.name. But when you use this.name the actual value that gets set will be dog.name. Just modify the code as given below and see.
function BodyLoaded()
{
var dog = {
name: "defaultname",
getName: function () {
return this.name;
},
setName: function (n) {
this.name = n;
}
};
dog.setName("bingo");
console.log(dog.getName());
}
But as per your given code I couldn't understand the reason for getting an empty string. If should actually output value defaultname.
function Dog() {
var self = this;
this.name = "defaultname";
this.getName = function () {
return this.name;
// same as
// return self.name
}
}
var myDog = new Dog();
myDog.getName(); // defaultname