Can a function be declared as a variable in JavaScript? - 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'));

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.

this keyword vs object name when adding method to existing object

function Foo(name, age){
this.name = name;
this.age = age;
this.announce = function(){
alert(this.name + " is " + this.age + " years old");
};
}
var myFoo = new Foo("John", 42);
Lets say I want to add a method to this particular instance of Foo (not to the others).
Should I use this keyword to modify the age property
myFoo.becomeYounger = function(){
this.age--;
};
or should I refer to the object by its name since it already exists?
myFoo.becomeYounger = function(){
myFoo.age--;
};
Which one is better/faster or is there any difference whatsoever?
They both work, but there are some risks about using the object name, look at this:
let user = {
name: "John",
age: 30,
sayHi() {
alert( user.name ); // leads to an error
}
};
let admin = user;
user = null; // overwrite to make things obvious
admin.sayHi(); // Whoops! inside sayHi(), the old name is used! error!
By using this, the code would worked correctly, just take care about this kind of scenarios.
Also if you like to do reusable code, using this fits better:
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// use the same functions in two objects
user.f = sayHi;
admin.f = sayHi;
// these calls have different this
// "this" inside the function is the object "before the dot"
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (dot or square brackets access the method – doesn't matter)
To learn more, here:
https://javascript.info/object-methods

Getting access to scoped objects

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

What am I doing wrong when combining objects with the module pattern

This Possible duplicate did not help me, I failed on an interview because of a similar question.
The idea is to create a person Object that is a father of teacher and grandfather of Manager using module pattern and inheritance.
Something like that Manager->Teacher->Person
My code looks like that(My Plunk):
(function(undef)
{
/**Waiting till document is ready before applying next functions*/
$(document).ready(function(){
var person = new APP.Person('Aria Stark','223232');
document.write(person.getDetails());
})();
var APP = {};
APP.Person =(function() {
function Person(name, ID) {
this.name = name;
this.ID = ID;
}
Person.prototype.getDetails = function() {
return " name: " + this.name + " ID: " + this.ID;
};
return Person;
});
APP.Teacher =(function () {
function Teacher(name, ID, salary, hatColor) {
APP.Person.call(this, name, ID);
this.salary = salary;
this.hatColor = hatColor;
}
Teacher.prototype = new APP.Person();
Teacher.prototype.getDetails = function() {
return APP.Person.call(this) + " Salary: " + this.salary + " Hat: " + this.hatColor;
};
return Teacher;
});
APP.Manager =(function () {
function Manager(name, ID, salary, hatColor, car) {
APP.Teacher.call(this, name, ID, salary, hatColor);
this.car = car;
}
Manager.prototype = new APP.Teacher();
Manager.prototype.getDetails = function() {
return APP.Teacher.call(this) + " Car: " + this.car;
};
return Manager;
});
})();
I get an error on the first line:
var person = new APP.Person('Aria Stark','22323');
The error is: Uncaught TypeError: object is not a function
Can someone help me with with that? I'm also open to hear other improvements to this code.
This is how you create (and call) a self-executing function or IIFE:
(function () {})();
Simply writing (function () {}) does not call the function, it actually has no real effect in this case. With your way APP.Person will be a function, that returns another function (the constructor for Person) when called - it will not operate well with new.
Also, for the documentready, you don't want to execute the result of the .ready call, just pass the function as a parameter, it will be called when the event triggers:
$(document).ready(function(){
}); //removed () from here
Plunk with these changes
All your objects are declared like this:
APP.X=(function() {
function Y() {}
Y.prototype.method= function() {};
return Y;
});
That is not wrong in itself, though it is a bit odd. What you want to have is this:
APP.X=(function() {
function X() {}
X.prototype.method= function() {};
return X;
})(); // actually call the anonymous function you used to encapsulate variables
Then again, why do you bother with an IIFE? You might just as well do this:
APP.X = function () {}
X.prototype.method= function() {};
Encapsulating them brings absolutely nothing, there is nothing private you are hiding from the outer scope.
Also, my post might be better suited for CodeReview than StackOverflow, but your inheritance model has significant issues. Your Teacher.prototype is an instance of Person created with no parameters. Only under highly restrictive circumstances will that be safe.
A better model would be this one:
Teacher = function(){
Person.call(this /*, person parameters*/);
}
Teacher.prototype = Object.create(Person.prototype);
There are many good answers on SO dealing with this specific issue, here is one from me.
There is no need of jQuery to create these things. Well, I have not very good exposer on this, but I tried to show the things you want to know:
// Creating Person Class
var Person = function(name, id){
this.name = name;
this.id = id;
};
Person.prototype.getInfo = function(){
return "name: " + this.name + ", id: " + this.id;
};
// Instance of Person
var x = new Person("Ashish", 1);
x.getInfo();
// Creating Teacher Class
var Teacher = function(name, id, salary, hatColor){
Person.call(this, name, id);
this.salary = salary;
this.hatColor = hatColor;
};
// Inheriting Persons methods
Teacher.prototype = new Person();
// Adding new method to it
Teacher.prototype.getFullDetails = function(){
return this.getInfo() + ", salary: " + this.salary + ", Hatcolor: " + this.hatColor;
}
// Instance of Teacher Class
var teacher = new Teacher("John", 2, 15000, "red");
teacher.getInfo(); //output: "name: John, id: 2"
teacher.getFullDetails(); // output : "name: John, id: 2, salary: 15000, Hatcolor: red"
console.log(teacher.salary); // output : 15000
So, above you can see:
- A Person class is created with 2 properties and one method.
- and then we created a Teacher class and inherited the method from Person class in it.
- and then added another method called getFullDetails() in it which accesses the method coming from Person class.
And this is what you are doing in the DOM.ready:
alert(x.getInfo()); // in my example:
In your example:
var APP = {};
APP.Person = function Person(name, ID) {
this.name = name;
this.ID = ID;
}
APP.Person.prototype.getDetails = function () {
return " name: " + this.name + " ID: " + this.ID;
};
var person = new APP.Person('Aria Stark', '223232');
alert(person.getDetails());

How to define a getter property, for an already defined JavaScript object?

Consider this code:
// Creating an empty object, without inheriting (binding) to any prototype
var human = Object.create(null);
human.firstName = 'Saeed';
human.lastName = 'Neamati';
Now, I want to add a fullName property to this object, which returns the firstName + ' ' + lastName of the object.
Using object literal notation, I can simply write a getter function this way:
var human = {
firstName: 'Saeed',
lastName: 'Neamati',
get fullName() {
return this.firstName + ' ' + this.lastName;
}
}
But I can't figure out how to attach a getter property to an object, which is already built somewhere else.
You can use Object.defineProperty
Object.defineProperty(<object>, <property-name>, <descriptor>);
Where <descriptor> can be something like:
// from the example:
{ value: 0x9f91102,
get: function() { return 0xdeadbeef; } }
try this :
Human = function(){
human.firstName = 'Saeed';
human.lastName = 'Neamati';
};
human.prototype.getFullName = function(){
return this.firstName + ' ' + this.lastName;
}
var humanOne = new Human();
alert(humanOne.getFullName());
Hope it helps :)

Categories

Resources