I have this code and as i use the display method it keeps giving me:
url is undefined
name is undefined
description is undefined
I don't know why i'm getting errors even though I am providing it will all the proprieties. Can somebody please identify the problem for me?
function website(name,url,description)
{
//Proparties
this.name=name;
this.url=url;
this.description=description;
// Methods
this.getName=getName;
this.getUrl=getUrl;
this.getDescription=getDescription;
this.display=display;
// GetName Method
function getName(name)
{
this.getName=name;
}
// GetUrl Method
function getUrl(url){
this.getUrl=url;
}
// getDescription
function getDescription(description){
this.getDescription=description;
}
function display(name,url,description){
alert("URL is :" +url +" Name Is :"+name+" description is: "+description);
}
}
// Set Object Proparites
web=new website("mywebsite","http://www.mywebsite.com","my nice website");
// Call Methods
var name = web.getName("mywebsite");
var url = web.getUrl("http://www.mywebsite.com");
var description = web.getDescription("my nice website");
web.display(name,url,description);
I think you're pretty confused about how functions work. In your code you have:
this.getName=getName; // this sets a "getName" method on the "this" object
// to be some function that will be implemented below
function getName(name) // i believe this function shouldn't have any parameter...
{
this.getName=name; //now, you're overriding the "getName" that you set above,
// to be something completely different: the parameter you sent when calling this function!
// instead, you should do:
return name;
}
Your getter functions are setters that overwrite themselves (?). Change them to
function getName(){
return this.name;
}
function getUrl(){
return this.url;
}
function getDescription(){
return this.description;
}
and
function setName(name){
this.name = name;
}
function setUrl(url){
this.url = url;
}
function setDescription(description){
this.description = description;
}
If you want your setters to return the set value, add return keywords before the assignments.
You wanted to write this? :
function setName(name)
{
this.name=name;
}
As I understood, you are setting, not getting properties. So:
var name = web.setName("mywebsite");
I should declare it as
function () {
//property
this.name
//method
this.setName = function ( name ) {
this.name = name
}
}
They way your implementing it, asks for context problems
Your getters should return a value instead of reassigning the getter itself e.g.
function getName() {
return this.name;
}
You should made return for the value as the following on each method:
// GetName Method
function getName() {
return this.getName = name;
}
// GetUrl Method
function getUrl() {
return this.getUrl = url;
}
// GetDescription Method
function getDescription() {
return this.getDescription = description;
}
Related
I am not sure about differences between object literal and constructor function.
function user() {
this.name="john"
this.getName=function (){
return this.name;
};
}
var johnUser=new user();
console.log(johnUser.getName()); // Will console john
What if I want to call getName without creating any objects something like in Java static method/function?
If I can add
user.sayName=function() {
console.log("Hey there");
}
console.log(user.sayName()); //will console Hey there.
How I can access constructor function properties?
The answer is You can't.
You should have read about how context of function works in JS.
When You are using new operator, empty object is being passed as context, that's why You can assign properties of this (which is reference to function context)
When You are calling a function without new operator, context of Your function is eiter global object (window) or undefined. You can print this in function to see what context You have ATM.
What You (probably) want is to create an prototype
Object literal
var user = {
name: "John",
getName: function(){
return this.name;
}
};
Alternatively, this approach won't define an object.
function sayName()
{
return "just a string";
}
function user() {
this.name = 'john';
}
user.prototype.getName = function(){ return this.name; }
var johnUser = new user();
console.log( johnUser.getName() ) // john
console.log( user.prototype.getName()); // undefined
user.prototype.getName = function(){ return 'just a string' }
console.log( johnUser.getName() ) // just a string
console.log( user.prototype.getName());// just a string
user.prototype.getName = function(){ return this.name || 'just a string'; }
console.log( johnUser.getName() ) // john
console.log( user.prototype.getName());// just a string
When using get in an object like this, get works:
var people = {
name: "Alex",
get sayHi() {
return `Hi, ${this.name}!`
}
};
var person = people;
document.write(person.sayHi);
But with a function I get an error. How to use Getters and Setters in a function like this?
function People2() {
this.name = "Mike";
get sayHi() {
return `Hi, ${this.name}!`;
}
};
var user = new People2();
document.write(user.sayHi);
You can use the actual get and set keywords only in classes (ES2015) and object literals.
ECMAScript 5
In ES5, your would typically use Object.defineProperty to implement what you're trying to achieve:
function People2() {
this.name = "Mike";
}
Object.defineProperty(People2.prototype, "sayHi", {
get: function() {
return "Hi, " + this.name + "!";
}
});
ECMAScript 2015
In ES2015, you could also use classes to achieve the desired behavior:
class People2 {
constructor() {
this.name = "Mike";
}
get sayHi() {
return `Hi, ${this.name}!`;
}
}
You can try this
<script>
function People2(name) {
this.name = name;
};
People2.prototype = {
get sayHi() {
return `Hi, ${this.name}!`;}
};
var user = new People2('Alex');
document.write(user.sayHi);
</script>
or this one...
<script>
function people(name) {
this.name = name;
};
Object.defineProperty(people.prototype, 'sayHi', {
get: function() { return `Hi, ${this.name}!`; }
});
var person = new people('Alex');
document.write(person.sayHi);
</script>
For the case you want to define a property like as name for a function with more control, we can use Object.defineProperty on function itself as following:
function people(name) {
//this.name = name; //this can be modified freely by caller code! we don't have any control
var _name = name; //use a private var to store input `name`
Object.defineProperty(this, 'name', {
get: function() { return _name; }, //we can also use `return name;` if we don't use `name` input param for other purposes in our code
writable: false, //if we need it to be read-only
//... other configs
});
};
var person = new people('Alex');
console.log(person.name); //writes Alex
For example, use this:
function People2() {
this.name = "Mike";
this.__defineGetter__("sayHi", function() {
return `Hi, ${this.name}!`;
});
};
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.
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);
I had written this code to simulate OOP inheritance and calling baseclass in javascript and it works:
function Animal(name,age)
{
this._name = name;
this.setName = function (name) { this._name = name }
this.getName = function() { return this._name }
}
function Cat(name,age)
{
Animal.call(this,name,age); // call baseclass constructor
this.getName = function() { return Cat.prototype.getName.call(this)+", a cat" }
}
Cat.prototype = new Animal(); // will create the baseclass structure
/// ***** actual execution *****
var puss = new Cat("Puss",3);
var cheshire = new Cat("Cheshire",10);
// do some actions
console.log ( puss.getName() );
// change cat's name
puss.setName("Puss in boots");
alert ( "new name -->"+puss.getName() );
problem is that, for each instance of "new Cat()" the "getName" and "setName" functions are replicated.
I have read a lot of articles on prototyping but none addressed the issue of calling the baseclass function.
You should assign the methods to the prototype of the function, for example,
function Animal(name, age) {
this._name = name;
this._age = age;
}
Animal.prototype.getName = function () { return this._name; }
Animal.prototype.setName = function (value) { this._name = value; }
function Cat(name, age) {
Animal.call(this, name, age);
}
Cat.prototype = new Animal();
Cat.prototype.getName = function () {
return Animal.prototype.getName.call(this) + ", a cat";
}
Are you looking for __proto__ which stores prototype data?
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/Proto
If you do a console.log(puss.__proto__.getName) you'll get what seems to be the "baseclass" function but I'm not sure how cross-browser is this.
From http://phrogz.net/js/classes/OOPinJS2.html
Javascript does not have any sort of 'super' property, which would
point to its parent class. Instead, you use the call() method of a
Function object, which allows you to run a function using a different
object as context for it. If you needed to pass parameters to this
function, they would go after the 'this'.
In your case it works the same for functions as "methods", so you can do:
Animal.prototype.setName.call(this, name);