Use an object as a blueprint for other objects - javascript

I have created a simple object that want to use as a blueprint for other objects. But something is not going well. Can anyone find out why? When I click one button it should change innerHTML of the div to display the properties of the new objects!
here is a fiddle
var objekt = {
name : "olsi",
surname : "Angjellari",
kot : function () {
return this.name + this.surname
},
print : function () {
id.innerHTML = this.kot()
}
};
http://jsfiddle.net/cTRuL/

There are a number of problems:
When you want to do:
var dana = new objekt();
Then, objekt must be a function, not just an object because an object is not a constructor, only a function can be a constructor. This is one way to do that:
function objekt() {
this.name = "olsi";
this.surname = "Angjellari";
};
objekt.prototype = {
kot : function () {
return this.name + this.surname
},
print : function () {
id.innerHTML = this.kot()
}
};
Second, in your jsFiddle if you're going to put function names in the HTML, then those functions have to be global. To make your code global in the jsFiddle, you have to set the upper left setting to "No wrap - in <body>" or "No wrap - in <head>". As you had your jsFiddle, your code was defined inside an onload handler and therefore NOT reachable by function calls from your HTML.
Third, once you make objekt into a function to fix the previous issue, then you can't call objekt.print() directly. You probably want to call .print on an actual object of type objekt like dana or boi.
You can see it all working here: http://jsfiddle.net/jfriend00/7TbEx/

you want to create a constructor so you can make instances using the new operator like you are trying
function objekt(name,surname){
this.name = name||"olsi";
this.surname = surname||"Angjellari";
this.kot = function () {
return this.name + this.surname
};
this.print = function () {
id.innerHTML = this.kot()
};
}
var obj = new objekt();
var obj2 = new objekt("First","Last");
obj.print();
obj2.print();
You could also make these through the prototype
function objekt(){}
objekt.prototype.name = "";
objekt.prototype.surname = "";
objekt.prototype.kot = function(){
return this.name + this.surname;
};
objekt.prototype.kot = function(){
id.innerHTML = this.kot();
};
var obj = new objekt();
obj.name = "First";
obj.surname = "Last";
var obj2 = new objekt();
obj2.name = "Last";
obj2.surname = "First";
obj.print();
obj2.print();

Related

JavaScript: use an object returned by function without object of object

I am new in JavaScript/jQuery. Wondering if there is any better way to return an object by a function.
//this is the Object creator.
function makeNewPlayer(name, score) {
var player = {};
player.name = name;
player.score = score;
return player;
};
This is how I use the function.
var player_info = makeNewPlayer('Bob' ,100);
However, when I use the object, I need to call it like this:
player_info.player.name
player_info.player.score
It looks stupid, any way to use the object directly like this?
player_info.name
player_info.score
edit:
As I don't know how many object will be created by the function.
Let say there is a for loop to make score_1, score_2 etc.
function makeNewPlayer(name, score) {
var player = {};
player.name = name;
for(i=0, i<number_of_score, i++){
eval("player.score_" + i) = score[i];
};
return player;
};
You can use destructing assignment to declare global or locally scoped variables
//this is the Object creator.
function makeNewPlayer(name, score) {
var player = {};
player.name = name
player.score = score
return player;
};
var player_info = makeNewPlayer("Bob", 100);
{
let {name: _name, score} = player_info;
// do stuff with `_name`, `score`
console.log(_name, score);
}
Use new.
I copied some text from my blog that happened to resolve your doubts:
A constructor is a special function used for creating an object:
Example:
function StarkIndustries(name, birth) {
this.name = name;
this.birth = birth;
}
var iron1 = new StarkIndustries('iron01', 2017);
var iron2 = new StarkIndustries('iron02', 2017);
alert(iron1.name);
alert(iron2.name);
Result:
iron01
iron02
By adding new before a function, the function is turned into a
constructor that constructs an object.
But it is dangerous to call a function designed as a constructor
without new, because it will modify the global object window. So sanity check inside the constructor is required:
if (!(this instanceof StarkIndustries)) {
warn("StarkIndustries is a constructor and should be called with `new`");
}
Back to your code, it should be:
function makeNewPlayer(name, score) {
this.name = name
this.score = score
};
var iron1 = new makeNewPlayer('iron01', 2017);
Aside for the fact that "Bob" should be in quotes, it's working fine for me.
var player_info = makeNewPlayer('Bob', 100);
and then I am able to access it just fine like this:
player_info.name
player_info.score
function makeNewPlayer(name, score) {
return {name, score};
};
let players = [];
// in for loop -- sample code only, you need to supply name & score
{
players.push(makeNewPlayer(name, score));
}
You can use a temporary constructor function inside of your function :
function makeNewPlayer(name, score){
const Player = function(name, score){
this.name = name;
this.score = score;
};
return new Player(name, score);
}
You can also use an external function instead of a nested one.
With no change to your function, i am able to get the output the way you want it
player_info.name
player_info.score
Check out the snippet below
//this is the Object creator.
function makeNewPlayer(name, score) {
var player = {};
player.name = name
player.score = score
return player;
};
var player_info = makeNewPlayer("Bob", 100);
console.log(player_info.name);
console.log(player_info.score);

Accessing 'this' inside an independent function in a Constructor

I have a Dog Constructor as follows:
var Dog = function(name,type)
{
this.name = name;
this.type = type;
this.normalObjFunc = function()
{
this.name = "kl";
}
var retfunc = function()
{
return this.name;
}
return retfunc;
}
In the retfunc function() , I am trying to access this.name in the following way.
var dogObj = new Dog("hj","labrador");
alert(dogObj());
In the output , I get as "result" in the alert messageBox, I am not getting what does the o/p "result" ,means?
I have purposely not included retfunc to "this" object, does it mean I cant access this.name inside retfunc() because a SEparate "this" would be created?
I am also aware of the fact that assigning var self =this solves the problem.
I just want to know what is "result" which is the output and why not undefined ideally?
The issue is because the scope of this within the functions will be the window. You need to cache the object reference in a variable and call that, like this:
var Dog = function(name, type) {
var _this = this;
this.name = name;
this.type = type;
this.normalObjFunc = function() {
_this.name = "kl";
}
var retfunc = function() {
return _this.name;
}
return retfunc;
}
var dogObj = new Dog("hj", "labrador");
console.log(dogObj());
Alternatively you can prototype the functions to keep the scope of this, however you would need to change your logic as it means that the return value of Dog() could not be the function.
var Dog = function(name, type) {
this.name = name;
this.type = type;
}
Dog.prototype.normalObjFunc = function() {
this.name = "kl";
}
Dog.prototype.retfunc = function() {
return this.name;
}
var dogObj = new Dog("hj", "labrador");
console.log(dogObj.retfunc());

How to use object oriented without using keyword ('new')

What am I trying to do is as following:
var Person = function(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
// This will return error;
console.log(Person('John').getName());
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());
Am I misunderstanding something?
// This will return error;
console.log(Person('John').getName());
it returns an error bcoz Person() by default returns undefined ,but if you use new it will return the newly created object.
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());
this works bcoz a new object with __proto__ set to Person.prototype is returned and since there is a getName() on it , it works as expected.
you may use scope safe constructor for your constructor to work without explicit new.
function Person(name) {
if(this instanceof Person) {
this.name = name;
} else {
return new Person(name);
}
}
http://www.mikepackdev.com/blog_posts/9-new-scope-safe-constructors-in-oo-javascript
If you don't want to have the new keyword all over your code (and I can't think of a good reason to want that, you would be basically hiding an important information), you could just do something like:
var pPerson = function(name) {
this.name = name;
};
pPerson.prototype.getName = function () {
return this.name;
};
var Person = function (name) {
return new pPerson(name);
};
You can use Object.create() if you don't want to use the new keyword. Here's an example from MDN:
// Animal properties and method encapsulation
var Animal = {
type: "Invertebrates", // Default value of properties
displayType : function(){ // Method which will display type of Animal
console.log(this.type);
}
}
// Create new animal type called animal1
var animal1 = Object.create(Animal);
animal1.displayType(); // Output:Invertebrates
// Create new animal type called Fishes
var fish = Object.create(Animal);
fish.type = "Fishes";
fish.displayType(); // Output:Fishes
If you really really hate your self, you can do this
var Person = function(name) {
var This = {};
This.name = name;
//See note
Object.setPrototypeOf(This, arguments.callee.prototype);
return This;
}
Person.prototype.getName = function () {
return this.name;
}
var p = Person('John');
console.log(p.getName());
Note
You absolutely have to read about this.
You can try creating prototype functions as a part of parent function itself.
var Person = function(name) {
this.name = name;
this.get_name = function() {
return this.name;
}
return this;
}
Person.prototype.getName = function() {
return this.name;
}
// This will return error;
console.log(Person('John').get_name());
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());

New Object Creation issues

Ok so the following function acts as a constructor to create an Employee object(no problem with that). But when I use this function to create 3 new employees I am messing up somewhere.
I know I'm supposed to set the properties and print the employee's name and phone number, but I am missing something or something is in the wrong place.
Thanks in advance for your help.
function Employe() {
var = name;
var = phone;
this.getName = function () {
return this.name;
}
this.setName = function (name, phone) {
this.name = name;
this.phone = phone;
};
}
var emp1 = newEmployee;
this.Name = 'jo';
this.Phone = ' 555-5551'
document.write(Employee.name Employee.phone);
var emp2 = newEmployee;
this.Name = 'jim';
this.Phone = '555-5552';
document.write(Employee.name Employee.phone);
var emp3 = newEmployee;
this.Name = 'jon';
this.Phone = '555-5553';
document.write(Employee.name Employee.phone);
In the following:
> var emp1 = newEmployee;
The variable on the left will be assigned the result of evaluating the expression on the right. There is no identifier newEmployee, so you will get an error. What you probably meant to write is:
var emp1 = new Employee();
That will call the constructor, which will return a new instance, a reference to which will be assigned to emp1.
Then you have:
> this.Name = 'jo';
The value of this is set when entering an execution context. For global code, it always references the global object (which is equivalent to window in a browser). So the above line creates a Name property of the global object and assigns the value 'jo';
What you wanted is probably:
emp1.setName('jo','555-5551');
The name of that method seems inappropriate given that it sets both the name and phone number.
> document.write(Employee.name Employee.phone);
Since you added the properties to the instance (emp1), likely that's the properties you want to read:
document.write(emp1.name + ' ' + emp1.phone);
or to use the getName method:
document.write(emp1.getName() + ' ' + emp1.phone);
and so on.
There's a lot wrong with your code example. The constructor is misspelled. The employee instances should be created like:
var emp1 = new Employee();
The instance properties should be set like:
emp1.setName('John');
You've also combined two setters into one, which is confusing.
To access the instance properties, you should use:
emp1.getName();
Not:
Employee.Name
Yes you have a lot of errors I think this is basically what you want to achieve.
function Employee(){
this.name;
this.phone;
this.getName = function(){
return this.name;
};
this.setName = function(name, phone){
this.name = name;
this.phone = phone;
};
}
function employ(){
var emp1 = new Employee();
emp1.name = 'jo';
emp1.phone = ' 555-5551' ;
alert(emp1.getName());
}
http://jsfiddle.net/umNTs/

Define a "nested" object constructor in JavaScript?

Is it possible to define an object within another object? I'm thinking something like this:
function MyObj(name) {
this.name = name;
function EmbeddedObj(id) {
this.id = id;
}
}
And I could then create an EmbeddedObj like this:
var myEmbeddedObj = new MyObj.EmbeddedObj();
Meme for bonus points: Objectception! :o
Yes, and no.
function MyObj(name) {
this.name = name;
}
MyObj.EmbeddedObj = function EmbeddedObj(id) {
this.id = id;
}
new MyObj.EmbeddedObj(42);
Would run, but it might not yield the expected results for "embedded object" (see comment).
Note that in the case of new expr the expression is evaluated first so, in this case it creates a new object using the function-object evaluated from MyObject.EmbeddedObj as a constructor. (There is a silly rule with parenthesis in the expression, but that's another story.)
Now, if a "parent" and "child" relationship was desired, that could be done, using a more round-about method:
function Parent (name) {
this.name = name;
var parent = this; // for closure
this.Child = function Child () {
this.Parent = parent;
}
}
// create new parent object
var parent = new Parent();
// each new parent has a different Child constructor and
// any function-object can be used as a constructor
var child = new parent.Child();
// true: child is "bound" to parent
child.Parent === parent;
function MyObj(name) {
this.name = name;
}
MyObj.EmbeddedObj = function(id) {
this.id = id;
}
var myEmbeddedObj = new MyObj.EmbeddedObj();
Does that look like what you're after?
Here is example of nested constructor.
function cimdb(name,review,year) {
function nestedConstructor(name,review,year) {
this.name = name;
this.review = review;
this.year = year
};
this.name = name;
this[name] = new nestedConstructor(name,review,year);
}
var lionking = new cimdb("The Lion King", "The lion King review ..", 2015);
I guess this is what you mean by nested object constructor.
The easiest way to nest other objects in a constructor is to create its field and then create a new object when invoking the constructor. Below is an example:
function Product(name, price, category, producer) {
this.name = name;
this.price = price;
this.category = category;
// nested constructor
this.producer = producer;
}
function Producer(contributor, address) {
this.contributor = contributor;
this.address = address;
}
let prod1 = new Product("Milk", 2.5, "Dairy", new Producer("Nestle", "Warszawa"));

Categories