What is the proper way to read a value from another function? - javascript

Say I have a this function
function name(){
var first_name = "mike";
}
I want to pass the value first_name over to another function -- I know you can do it this way:
function name(){
var first_name = "mike";
getName(first_name);
}
But say I want to access it without passing over like that
function name(){
var first_name = "mike";
getName()
}
In getName how can I access first_name from the name() function?
function getName(){
console.log(this.first_name)
}
In PHP I know you can do it with $this->first_name, how would this be done in javascript? Also If you can calling another function in javascript, is there a proper way to do it like in PHP $this->first_name()
Thank you in advance

function name(){
var first_name = "mike";
return first_name;
}
function getName(){
var get_name=name();
alert(get_name);
}

You can't access that variable from any other function unless you pass it explicitly like in naga's solution because first_name is local, only name has access to it. You may want to use prototypes.
function Person(name) {
this.first_name = name || 'Mike';
}
Person.prototype = {
getName: function() {
return this.first_name;
}
};
var john = new Person('John');
console.log(john.getName()); //=> John

Kind of naughty, but this is one answer to your question...
var first_name = "mike";
function change_name(new_name) {
first_name = new_name;
}
function get_name() {
return first_name;
}
console.log(get_name());
I personally prefer a design pattern like so...
var names = new function() {
// The 'this' context may change within callbacks and such,
// so this is one way to save it for later use
var self = this;
this.first_name = "mike";
this.change_name = function(new_name) {
self.first_name = new_name;
}
this.get_name = function() {
return self.first_name;
}
}
console.log(names.first_name);
console.log(names.get_name());
names.change_name("kevin");
console.log(names.first_name);

Related

How can I add value to a constructor/prototype function?

Lets say I have a constructor looking like this
function Persons(lastName) {
this.lastName = lastName;
this.firstName = [];
}
and then a prototype like this
Persons.prototype.getFirstName = function() {
getName();
return firstName;
}
And the getName function
var getName = function() {
}
If I in getName want to send the value "Andrew" to the array this.firstName = []; how can I do that? Is it even possible?
You can pass the array to the function and fill it there:
Persons.prototype.getFirstName = function() {
getName(this.firstName);
return this.firstName;
}
var getName = function(arr) {
arr.push("Andrew");
}
Or you can return the value from the function and set it in the method:
Persons.prototype.getFirstName = function() {
this.firstName.push(getName());
return this.firstName;
}
var getName = function() {
return "Andrew";
}
Is possible, like so:
var getName = function(person) {
person.firtName.push("Andrew");
};
An then in your prototype:
Persons.prototype.getFirstName = function() {
getName(this);
return firstName;
};
But it doesn't look good. It seems to be a bad practice. Anyway, hope this help.
You can use the method call of a Function, as it follows:
Persons.prototype.getFirstName = function() {
getName.call(this);
}
This way you bind the this reference to the getName function, thus you can safely access it as ti follows:
var getName = function() {
this.firstName.push("Andrew");
}
Here you can find more details about call.

Accessing properties/ methods from objects (javascript)

I am a typical Java programmer with traditional OOPs knowledge. I am trying to learn JS now. I have learned that a function is JS is a first class object, like any other object it has properties and methods. based on this I have written following code:
function Note(name, text)
{
this.name = name;
this.text = text;
function displayNote()
{
alert(this.text);
}
}
I am now trying to access the displayNote function from the not object, with the follwing code:
var note = new Note("a", "c");
alert(note.displayNote);
But it alerts undefined. This may be due to the scope issue. So I tried with this:
function Note(name, text)
{
this.name = name;
this.text = text;
function displayNote()
{
var self = this;
alert(self.text);
}
}
var note = new Note("a", "c");
alert(note.displayNote);
Still the same result. Any explanations?
You need to do:
function Note(name, text)
{
this.name = name;
this.text = text;
this.displayNote = function()
{
alert(this.text);
}
}
It is showing undefined, because you haven't defined the displayNote property.
Also, to call a function you need to do:
var note = new Note("a", "c");
note.displayNote();// it will automatically alert. Otherwise you'll have two alerts. The second one being undefined.
Live Demo
Try this.
this.displayNote = function()
{
alert(this.text);
}
Now it's a property of the Note object. Plus I think you want to do this:
note.displayNote(); // Note the brackets to call.
In here with the code as
alert(note.displayNote);
You are calling the alert twice.
So please just call the function
note.displayNote();
you can use like below
<script language="javascript" type="text/javascript">
<!--
person = new Object()
person.name = "Tim Scarfe"
person.height = "6Ft"
person.run = function() {
this.state = "running"
this.speed = "4ms^-1"
}
//-->
</script>

Passing arguments to anonymous function of module

$(document).ready(function () {
var patient = (function (options) {
var age = options.age;
var name = options.name;
function getName() {
return this.name;
}
function setName(val) {
name = val;
}
function getAge() {
return this.age;
}
function setAge(val) {
age = val;
}
return {
getAge: getAge,
setAge: setAge,
getName: getName,
setName: setName
}
})();
});
I realize that I'm never passing any options in my example here.
If I try to do something like patient.setAge('100') and then console.log(patient.getAge()) I get an error saying cannot read property Age of undefined. The overarching theme that I'm trying to get at is within a module, how can I emulate consturctors to instantiate a new patient object while keeping all the OOP goodness of private variables and all that jazz.
I've seen some examples of constructors in a module pattern on here and I haven't understood them very well. Is it a good idea in general to have a constructor in a module? Is its main purpose similarity with class-based languages?
This is a constructor:
function Patient(options) {
options = options || {};
this.age = options.age;
this.name = options.name;
}
$(document).ready(function () {
var patient = new Patient();
});
You can put it inside a module if you want. What you shouldn’t do is provide getters and setters, especially ones that don’t do anything. If you’re exposing a variable through two properties to get and set it, it should just be one property.
Try this
function Patient (options) {
options = options || {};
var age = options.age;
var name = options.name;
function getName() {
return name;
}
function setName(val) {
name = val;
}
function getAge() {
return age;
}
function setAge(val) {
age = val;
}
return {
getAge: getAge,
setAge: setAge,
getName: getName,
setName: setName
}
}); // pass empty object
$(document).ready(function () {
var p1 = new Patient({});
var p2 = new Patient();
var p3 = new Patient({age:20});
var p4 = new Patient({name:"abcd"});
var p5 = new Patient({age:21, name:"abcd"});
});

Javascript OOP - declaring methods of an object

This is the most basic JS object example I can think of that illustrates my questions.
Question 1.
How can I reference functions within a class so that in other code I could call a method? This gives me an error.
var name1 = new Name();
name1.render();
Question 2.
What is the difference between declaring functions in-line like this vs. using var getByID = function() ...?
Example object:
function Name(user_id, container_id) {
this.userID = user_id;
this.containerID = container_id;
this.firstName = null;
this.lastName = null;
function getByID(userID) {
// An ajax call that takes a userID to get a name.
}
function setName() {
// An ajax call to get the name from db.
name_record = this.getByID(this.userID); ????? this returns an error that getByID is undefined.
this.firstName = name_record.firstName;
this.lastName = name_record.lastName;
}
function render() {
$(this.containerID).val(this.firstName + ' ' + this.lastName);
}
}
You can declare an object like you done in your second question, it's valid because a function is an object too. Or other ways like:
var Name = {
render: function() {
}
}
Name.render();
Or with prototype:
function Name() {
}
Name.prototype.render = function() {
}
// or
Name.prototype = {
getByID: function() {
},
setName: function() {
}
}
var n = new Name();
All these snipets are a valid object declaration.
Your second question may answer the first ones. When you declare a function like this:
function Name() {
function render() {
}
}
var n = new Name();
It is like render() be a private method. if you call outside the function name n.render(), you will see an error thrown because render is not recognized. But if you change to this...
function Name() {
this.render = function() {
}
}
... then n.render() will work like render() being a public method. See this and this for further information about public and private methods.
Now, the difference between declaring a function "in-line" or setting it to a variable is that with this:
function Name() {
}
You can do:
var n1 = Name();
var n2 = Name();
var nn = Name(); // and so on...
But with:
var n = function Name() {
}
Is that n() will work and Name() will not. Even var a = Name() will throw an exception.
Here's a good article about this subject that worth a read. I hope it can help.
Question 1:
A "Class" in Javascript is nothing more than an object. An object has properties which you can access. Those properties are either variables, functions, or other objects. By declaring your function like:
function render() {
$(this.containerID).val(this.firstName + ' ' + this.lastName);
}
You are declaring a function within the scope of function Name() but that function isn't a property of Name. It's just a private method. There are multiple ways you could make it a part of Name(), such as:
function Name(user_id, container_id) {
this.userID = user_id;
this.containerID = container_id;
this.firstName = null;
this.lastName = null;
this.render = function() {
console.log('hello world');
}
}
var name1 = new Name();
name1.render();
Question 2:
There is no difference. They are simply two different syntax's that achieve the same result. The second way (declaring a var and defining the function) immediately gives you a reference to the function, but that can be achieved just as well the first way.
Answer to your first question:
Functions getByID,setName and render are local to the constructor and cannot be called by class object. You have to use prototypal inheritance.
for eg.
function Name(user_id, container_id) {
this.userID = user_id;
this.containerID = container_id;
this.firstName = null;
this.lastName = null;
}
Name.prototype = {
getByID :function(userID) {
// An ajax call that takes a userID to get a name.
}
setName:function() {
// An ajax call to get the name from db.
name_record = this.getByID(this.userID);
this.firstName = name_record.firstName;
this.lastName = name_record.lastName;
}
render:function() {
$(this.containerID).val(this.firstName + ' ' + this.lastName);
}
};
Answer to your second question:
in case of
abc();//Error
function abc(){
}
this function is created at run time , so you can call it only after declaration
however, this
abc();
var abc = function(){
};
is created at parse time so you can call it before declaration.

Question about create object in JavaScript

I've learned that you can create your own 'class' in this way:
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.foo = function(){
// do something
}
Person.prototype.foo2 = function(){
// do something
}
var wong2 = new Person("wong2", "20");
Now if foo and foo2 both need to call another function named foo3, where should I add it to?
I don't want foo3 to be called by wong2, so I can't just use
Person.prototype.foo3 = function(){
// something else else
}
But if I define it in the global scope, I don't think it's very nice. Any suggestions?
You can define foo3 inside a closure that foo1 and foo2 have access to, something like
function() {
function foo3() { ... }
Person.prototype.foo = function(){
foo3();
}
...
}();
Try to look at this SO question and article about Private Members in JavaScript.
Don't know if this is exactly what you are looking for, but this acts as a static function.
Person.foo3 = function() {
// something else else else but not inherited by wong2
}
why not create your own namespace? try
var person = {};
person.createPerson=function (name,age){
this.name=name;
this.age=age;
if (age<18){
this.status = 'cannot Marry';
}else{
person.addMarriageStatus('married');
}
}
person.addMarriageStatus = function(status){this.status=status};
person.createPerson('Jack',2);
//person
I get the impression you want something like a static function, where foo3 belongs to Person, but not to wong2 and certainly not to the global scope.
If so, just assign a function to Person.foo3 as i have below.
http://jsfiddle.net/audLd/1/
function Person(name, age){
this.name = name;
this.age = age;
}
Person.foo3 = function() {return 10;};
Person.prototype.foo = function(){
return Person.foo3();
}
Person.prototype.foo2 = function(){
return Person.foo3()*2;
}
var wong2 = new Person("wong2", "20");
alert("" + wong2.foo() + ", " + wong2.foo2()); //works
alert("" + Person.foo3()); //works. this is the distinction between what I'm loosely calling static and private
alert(foo3()); //doesnt work
alert(wong2.foo3()); //doesnt work
If you want a 'private' member thru closures then that is an entirely different animal.

Categories