Why is this not working??
var sheep = function(options){
this.options = {sizes: 100,
eat: 100,
colors: 'white',
running: function () {
return this.sizes + this.eat;
}
}
};
var blacksheep = new sheep({colors:'black'});
alert('blackcsheep color is ' + blacksheep.colors);//error undefined
alert('blackcsheep color is ' + blacksheep.options.colors);// it return white
alert('blackcsheep running is ' + blacksheep.running());//error
The syntax:
var sheep = {sizes:100, eat:100, colors:'white',running:function(){
return this.sizes+this.eat;
}
};
is an object literal. It defines an instance of an object, but not the class that defines it. Therefore, there is no way to "new-up" another instance of the object.
Take a look at jQuery's extend functionality:
var blacksheep = {
}
$.extend(blacksheep, sheep, { color: black });
This will copy all the properties of sheep into blacksheep, then merge the third parameter into blacksheep, effectively achieving what you want.
To make another black sheep based on sheep, in this scenario you could do (using jQuery):
var blacksheep = $.extend(sheep, { color: 'black' });
You can create a sheep object like this.
function Sheep(sizes,eat,colors){
this.sizes = sizes;
this.eat = eat;
this.colors = colors;
this.running = function (){
return this.sizes+this.eat;
}
}
Alternatively you can write like this also
function Sheep(sizes,eat,colors){
this.sizes = sizes;
this.eat = eat;
this.colors = colors;
}
sheep.prototype.running = function(){
return this.sizes + this.eat;
}
var sheep1 = new Sheep('100','100','white');
var sheep = function(){
this.sizes = 100;
this.eat = 100;
this.colors = 'white';
this.running = function(){
return this.sizers + this.eat;
}
}
You don't declare objects in JavaScript in the same way as you do in strongly-typed languages. You declare objects by using functions like this:
function sheep() {
this.color = "white";
this.size = 200;
this.speed = 100;
this.running = function () {
return "the sheep is running!";
};
}
var blacksheep = new sheep();
alert('sheep size is ' + blacksheep.size);
alert('sheep running is ' + blacksheep.running());
Your new object does not work because you are creating a new object with a sub-object called options. options contains all of your methods. As such only the second of these three lines that you gave will give you the correct response:
alert('blackcsheep color is ' + blacksheep.colors);
alert('blackcsheep color is ' + blacksheep.options.colors); // Only this one correctly references `options`.
alert('blackcsheep running is ' + blacksheep.running());
in your case sheep is already an object you can not create object of an object.
you can directly use that object with property.
But i think you want something like this
var sheep = {sizes:100, eat:100, colors:'white', running:function(){
return this.sizes+this.eat;
}
}; Object.defineProperty(sheep, 'colors', { value: 'black'
, writable: true });
Thanks
Javascript is prototype based not class based. It does not use classes and is also object orientated.
var whitesheep =new sheep("100","100","white","running");
var blacksheep =new sheep("100","100","black","running");
Related
I am not very sure how to name the question. What i am trying to achieve is this..
I have a set of Global Variable, they will need to be replicated over and over, but assigned with different set's name example. For example
var start
var end
var time
And i have many set/model that i have to create and change, so i am wondering if it is possible to create 1 set and i just have a var modelnumber which then i can just copy and paste them and change the modelnumber so i wont have to change thousands of variable names?
Example
var modelnumber = "1";
var modelstart = modelnumber + "modelstart";
var modelend = modelnumber + "modelend";
var modeltime = modelnumber + "modeltime";
Edit: To provide more info
So i have model1.js , model2.js model3.js and so on....and all the variable names function names are the same, and to save me time, i want to write 1 set of code that i can just change the var modelname at the top of each field so i wont have to change the thousands of variable names and function names..
You can always write a function:
function createVariables(modelNumber) {
window[modelNumber + 'modelstart'] = 1;
window[modelNumber + 'modelend'] = 2;
window[modelNumber = 'modeltime'] = 3;
}
createVariables(1);
Or change it to however you want. :)
UPDATE: (use global in place of window for NodeJS).
I think you're looking for a normal object literal. You can specify the property keys of the object with strings, which will give you the dynamic effect you're looking for.
Here's an example, using a for loop to populate the object.
var models = {};
var number_of_keys = 1000;
for(var i = 1; i < number_of_keys; i++) {
var keyName = 'model' + i;
var model = {
'start': i + 'modelstart',
'end': i + 'modelend',
'time': i + 'modeltime'
}
models[keyName] = model;
}
console.log(models);
Update:
As an example of how you could access your populated models, consider the following:
// You can effectively replace the `1` in this example with any number:
var model1 = models['model1'];
// model1 would be:
// {
// 'start': '1modelstart',
// 'end' : '1modelend',
// 'time': '1modeltime'
// }
var start1 = model1.start;
var end1 = model1.end;
var time1 = model1.time;
// Pseudo-code
var modelN = models['modelN'];
var startN = modelN.start;
var endN = modelN.end;
var timeN = modelN.time;
HTH
You could (should?) use an object or an array of objects.
For example:
// The "Model"
var Model = function(start,end,time) {
this.start = start;
this.end = end;
this.time = time;
}
// One option.
// Assign "Model" to the models
var models = {
'm1': new Model(x,y,z),
'm2': new Model(a,b,c)
}
// Access values
if (models.m1) {
alert("m1 end:["+ models.m1.end +"]");
}
// Add a "new" model
models['ace'] = new Model(r,s,t);
// or even
models.club = new Model(e,f,g);
You could also extend it like so:
Model.prototype.debug = function(id) {
if (id) {
console.log("model id:["+ id +"]");
}
console.log("start:["+ this.start +"]");
console.log("end:["+ this.end +"]");
console.log("time:["+ this.time +"]");
}
Which you would call like so:
models.m1.debug();
Or even:
for(x in models) {
models[x].debug(x);
}
Here is a code snippet example.
var Model = function(start,end,time) {
this.start = start;
this.end = end;
this.time = time;
}
Model.prototype.debug = function(id) {
if (id) {
console.log("model id:["+ id +"]");
}
console.log("start:["+ this.start +"]");
console.log("end:["+ this.end +"]");
console.log("time:["+ this.time +"]");
}
var models = {
'm1' : new Model('x','y','z'),
'm2' : new Model('a','b','c')
};
models.ace = new Model('r','s','t');
for(x in models) {
models[x].debug(x);
}
I’ve made a little sandbox using the p5.js library : http://gosuness.free.fr/balls/
I’m trying to implement a way to deal with the options on the side, which are toggled using keyboard shortcuts.
This is what I tried to do :
var options =
{
Option: function(name, value, shortcut)
{
this.name = name;
this.shortcut = shortcut;
this.value = value;
this.show = function ()
{
var texte = createElement("span",this.name + " : " + this.shortcut + "<br />");
texte.parent("options");
texte.id(this.name);
}
},
toggle: function(shortcut)
{
for (var o in this)
{
console.log(o);
if (o.shortcut == shortcut)
{
o.value = !o.value;
changeSideText("#gravity",gravity);
addText("Toggled gravity");
}
}
}
};
I instantiate each option inside the object options thus :
var gravity = new options.Option("gravity", false,"G");
var paintBackground = new options.Option("paintBackground",false,"P");
When I call the function options.toggle, console.log(o) gives me "Option" "toggle". but what I want is to get for (var o in this) to give me the list of properties of the object options, which are in this case gravity and paintBackground
How do I do that ?
Thanks !
When You create a instance of Option, its not kept within the variable options, but in the provided variable.
var gravity = new options.Option("gravity", false,"G");
Creates an instance of Option located under gravity variable.
Your iterator for (var o in this) iterates over options properties, with the correct output of the object's methods.
If You want your code to store the new instances of Option within options variable, you can modify code like
var options =
{
instances: [],
Option: function(name, value, shortcut)
{
this.name = name;
this.shortcut = shortcut;
this.value = value;
this.show = function ()
{
var texte = createElement("span",this.name + " : " + this.shortcut + "<br />");
texte.parent("options");
texte.id(this.name);
}
options.instances.push(this);
},
toggle: function(shortcut)
{
for (var i in this.instances)
{
console.log(this.instances[i]);
if (this.instances[i].shortcut == shortcut)
{
this.instances[i].value = !this.instances[i].value;
changeSideText("#gravity",gravity);
addText("Toggled gravity");
}
}
}
};
this is your example working as You intend it to, but i wouldnt consider this as a reliable design pattern.
I have a function defined in my JavaScript with two properties: size and url:
function IconInfo() {
this.size = size;
this.url = url;
}
Inside another function I create a new instance of IconInfo and set the properties this way:
function SomeFunction() {
var icon = new IconInfo();
icon.size = 64;
icon.url = "http://somesite.com/image1.png";
}
Isn't there a way to create an instance like the following:
var icon = new IconInfo({
size : 64,
url : "http://somesite.com/image1.png"
});
I like that notation better, it seems more concise and easier to read.
===========================UPDATE================================
Based on Tim's answer of doing it the following way:
var icon = {
size : 64,
url : "http://somesite.com/image1.png"
};
I have the following question.
Let's say I have 2 functions both with the same exact properties and constructor arguments:
function Func1(x) {
this.x = x;
}
function Func2(x) {
this.x = x;
}
And I have a container that holds either type:
function Container() {
this.f = null;
}
If I add one of the functions using that method what type will it actually be?
...
var container = new Container();
container.x = new f { // is f Func1 or Func2?
x: 10;
}
There are a lot of options, but keeping it simple.. you could just do this:
var icon = {
size : 64,
url : "http://somesite.com/image1.png"
};
You don't have to declare a "type", but you could.. sort of like this:
function IconInfo(size, url)
this.size = size;
this.url = url;
);
var icon = new IconInfo(2, "www.google.com");
You can actually make it even more concise. First, you're forgetting to set the variables inside IconInfo; it should be this:
function IconInfo(size, url) {
this.size = size;
this.url = url;
}
To create a new IconInfo in your other function, you'll just need to call it like this:
function SomeFunction() {
var icon = new IconInfo(64, "http://somesite.com/image1.png");
}
I'm doing some Javascript R&D and, while I've read Javascript: The Definitive Guide and Javascript Object Oriented Programming, I'm still having minor issues getting my head out of class based OOP and into lexical, object based OOP.
I love modules. Namespaces, subclasses and interfaces. w00t. Here's what I'm playing with:
var Classes = {
_proto : {
whatAreYou : function(){
return this.name;
}
},
Globe : function(){
this.name = "Globe"
},
Umbrella : new function(){
this.name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
this.name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
this.name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
Im trying to find the best way to modularize my code (and understand prototyping) and separate everything out. Notice Globe is a function that needs to be instantiated with new, Umbrella is a singleton and already declared, Igloo uses something I thought about at work today, and seems to be working as well as I'd hoped, and House is another Iglooesque function for testing.
The output of this is:
Globe
unavailable
Igloo
My House
So far so good. The Globe prototype has to be declared outside the Classes object for syntax reasons, Umbrella can't accept due to it already existing (or instantiated or... dunno the "right" term for this one), and Igloo has some closure that declares it for you.
HOWEVER...
If I were to change it to:
var Classes = {
_proto : {
whatAreYou : function(){
return _name;
}
},
Globe : function(){
_name = "Globe"
},
Umbrella : new function(){
_name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
_name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
_name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
and make this.name into _name (the "private" property), it doesn't work, and instead outputs:
My House
unavailable
My House
My House
Would someone be kind enough to explain this one? Obviously _name is being overwritted upon each iteration and not reading the object's property of which it's attached.
This all seems a little too verbose needing this and kinda weird IMO.
Thanks :)
You declare a global variable. It is available from anywhere in your code after declaration of this. Wherever you request to _name(more closely window._name) you will receive every time a global. In your case was replaced _name in each function. Last function is House and there has been set to "My House"
Declaration of "private" (local) variables must be with var statement.
Check this out:
var foo = function( a ) {
_bar = a;
this.showBar = function() {
console.log( _bar );
}
};
var a = new foo(4); // _bar ( ie window._bar) is set to 4
a.showBar(); //4
var b = new foo(1); // _bar is set to 1
a.showBar(); //1
b.showBar(); //1
_bar = 5; // window._bar = 5;
a.showBar();// 5
Should be:
var foo = function( a ) {
var _bar = a;
// _bar is now visibled only from both that function
// and functions that will create or delegate from this function,
this.showBar = function() {
console.log( _bar );
};
this.setBar = function( val ) {
_bar = val;
};
this.delegateShowBar = function() {
return function( ) {
console.log( _bar );
}
}
};
foo.prototype.whatever = function( ){
//Remember - here don't have access to _bar
};
var a = new foo(4);
a.showBar(); //4
_bar // ReferenceError: _bar is not defined :)
var b = new foo(1);
a.showBar(); //4
b.showBar(); //1
delegatedShowBar = a.delegateShowBar();
a.setBar(6);
a.showBar();//6
delegatedShowBar(); // 6
If you remove the key word "this", then the _name is in the "Globe" scope.
Looking at your code.
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
At last the house will override the "_name" value in globe scope with the name of "My House".
I am new to javascript...
I trying to create an object- "Flower".
Every Flower has it properties: price,color,height...
Can somebody give me an idea how to build it?
Create an object and then change his properties?
:-)
flower= {
price : function() {
console.log('Price is 78 $');
},
color: 'red',
height : 23
};
flower.price();
flower.height ;
Have an object, where you can also bind functions to. The following should be used if you want to have multiple Flower objects, because you can easily create new Flowers and they will all have the functions you have added:
function Flower(price, color, height){
this.price = price;
this.color= color;
this.height= height;
this.myfunction = function()
{
alert(this.color);
}
}
var fl = new Flower(12, "green", 65);
fl.color = "new color");
alert(fl.color);
fl.myfunction();
If you want to have a sort of array just use an object literal, but you need to set the properties and functions for each Object you create.
var flower = { price : 12,
color : "green",
myfunction : function(){
alert(this.price);
}
};
flower.price = 20;
alert(flower.price);
alert(flower.myfunction());
var flower = {"height" : 18.3, "price":10.0, "color":"blue"}
Here is a pattern to create object with public/private section(s)
var MyObj = function()
{
// private section
var privateColor = 'red';
function privateMethod()
{
console.log('privateMethod. The color is: ', privateColor);
}
// The public section
return
{
publicColor : 'blue',
publicMehtod: function()
{
// See the diffrent usage to 'this' keyword
console.log('publicMehtod. publicColor:', this.publicColor, ', Private color: ', privateColor);
},
setPrivateColor: function(newColor)
{
// No need for this
privateColor = newColor;
},
debug: function()
{
this.publicMehtod();
}
};
}
var obj1 = new MyObj();
obj1.publicMehtod();
obj1.setPrivateColor('Yellow');
obj1.publicMehtod();
var obj2 = new MyObj();
obj2.publicMehtod();
var flower = {"propertyName1": propertyValue1, "propertyName2": propertyValue};
To retrieve the values:
var price = flower.price;
To change property values:
flower.price = newPrice;