This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Here I have two "classes" made Cards and card. Cards is essentially an array with specific methods:
add card
remove card
sort and shuffle
Card is an object used for holding a suit a value and outputting a string concatenating both.
My problem here is trying to run this code, namely setup() on a button click.
I find that when I just create a card, it still runs. I know this because the output still changes to hello world.
But when I try to add a card to the cards class, or deck. the script stops running. I don't know why this is, I have a feeling that it doesn't like how I used an Array.
Thats question one.
My second question is that when I
var temp= new card('c','2');
alert(temp.getvalue());
This also fails.
Any insight as to what I did wrong here would help and be appreciated.
function setup() {
var temp = new card('c', '2');
var textbox = document.getElementById("output");
textbox.value = "Hello, world!";
};
Array.prototype.shuffle = function () {
for (var i = this.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = this[i];
this[i] = this[j];
this[j] = tmp;
}
return this;
}
function card(s, v) {
this.suit = s;
this.value = v;
this.getvalue = function () {
return (suit.toString() + value.toString());
};
this.getSortOrder = function () {
var factor;
if (this.suit == 'c') {
factor = 0;
}
else if (this.suit == 'd') {
factor = 1;
}
else if (this.suit == 'h') {
factor = 2;
}
else if (this.suit == 's') {
factor = 3;
}
else {
factor = -2;
}
return (this.value + 13 * factor);
};
};
function Cards() {
this.list = new Array();
this.Addcard = function (c) {
list.push(c);
};
this.removeCard = function (c) {
list.splice(list.indexOf(c), 1);
};
this.lookat = function (i) {
return list[i];
};
this.sort = function () {
list.sort();
};
this.shuffle = function () {
list.shuffle();
};
this.prototype;
};
Here's one thing:
this.getvalue = function () {
return (suit.toString() + value.toString());
};
You need to access suit and value with this:
this.getvalue = function () {
return (this.suit.toString() + this.value.toString());
};
Edit:
There's a lot more like that in your code (see Cards function). Javascript does not automagically place "this" there for you like other language, because it doesn't have classes, it has prototypes.
Whenever you try to access a "member variable", give it some context, use this.
Other code style tips:
use [] instead of new Array()
comment large blocks of code with /* and */
constructors should be capitalized (Card, not card) and functions should be camel case (addCard, not Addcard)
Related
I'm currently learning about memoization. As a simple exercise I implemented memoization with a fibonacci. However I'm having problems as to why when I do not rename the memoized function it takes slower to complete than when I rename it. Take a look at the code.
This doesn't work correctly and doesn't cache correctly.
function memoize(func) {
const cache = {};
return function(args) {
const cacheKeys = Object.keys(cache).map(el => +el);
if (cacheKeys.includes(args)) {
return cache[args];
}
cache[args] = func(args);
return cache[args];
};
}
function wrapped_fibonacci(n) {
if (n <= 2) {
return 1;
}
return wrapped_fibonacci(n - 1) + wrapped_fibonacci(n - 2);
}
const fibonacci = memoize(wrapped_fibonacci); // <== I do not rename the function.
for (let i = 1; i <= 40; i++) {
console.log(fibonacci(i));
}
However, when I write my code like this. It works correctly and is performant
function memoize(func) {
const cache = {};
return function(args) {
const cacheKeys = Object.keys(cache).map(el => +el);
if (cacheKeys.includes(args)) {
return cache[args];
}
cache[args] = func(args);
return cache[args];
};
}
function fibonacci(n) {
if (n <= 2) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
fibonacci = memoize(fibonacci); //<== I rename the function
for (let i = 1; i <= 40; i++) {
console.log(fibonacci(i));
}
As you can see. I just reassigned the function name.
I'm doing these tests on node.js v8.3.0
The results of the first is as such.
time node fib.js
real 0m2.413s │~
user 0m2.400s │~
sys 0m0.008s
The results of the second goes as such
time node fib.js
real 0m0.263s │~
user 0m0.252s │~
sys 0m0.008s
THATS 1.8S DIFFERENCE
Anyone able to shed some light on this?
In the working example, you're replacing fibonacci with a memoized function also called fibonacci. The recursive calls are using this memoized function, because fibonacci-the-original was replaced by fibonacci-the-memoized.
In the non-working example, you're creating a memoized function fibonacci from wrapped_fibonacci, but that function still calls wrapped_fibonacci, the unmemoized original, recursively.
If you'd also replace wrapped_fibonacci, it would speed up again:
const fibonacci = wrapped_fibonacci = memoize(wrapped_fibonacci)
Can this be written without complexing things with prototypes?
Why? The current code does what I want, but it bothers me how trixy it is to follow and how error prone it is, also seems to be performance wasting since things are duplicated.
Aim? The more I spend using prototype and this I get the sense the code would be simpler and more to the point if this was not the case.
Especially if the this-functions in SystemBlueprint can be rewritten to take an instance as argument instead. And if object Function Log() and Out could just be plain objects somehow? How can Log or Out be extracted outside of SystemBuilder?
Full code in Jsbin
https://jsbin.com/pigosijaxo/edit?js,console (Updated)
// Local for each System object
var SystemData = {
name: '?',
id: 1,
actions: [],
destinations: []
}
// Variables shared among all Systems
const SystemShare = {
global: 1
}
// this-Functions shared among all Systems
function SystemBlueprint() {}
SystemBlueprint.prototype = {
run() {
var length = this.actions.length
for (var i = 0; i < length; i++) {
var result = this.actions[i](arguments, this)
if (result && this.destinations.length > 0) {
for (var n = 0; n < this.destinations.length; n++) {
this.destinations[n].call(null, result)
}
}
}
},
does(algorithm) {
this.actions.push(algorithm)
return this
},
random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
function SystemBuilder(name) {
// copy shared methods
var system = Object.create(SystemBlueprint.prototype)
Object.assign(system, JSON.parse(JSON.stringify(SystemData))) //deep copy
system.name = name
system.id = SystemShare.global++
function Log() {}
Log.prototype.local = () => console.log('fields: ' + JSON.stringify(Object.keys(system))),
system.log = new Log()
function Out(){}
Out.prototype.into = (destination) => {
system.destinations.push(destination)
return system
}
system.out = new Out()
system.trigger = {}
function OnEvent(trigger){
if(trigger === undefined) return
trigger.call(null, system.run.bind(system))
return system
}
system.trigger.on = new OnEvent()
return system
}
var system = new SystemBuilder()
system.my = 'Testing'
system.log.local()
system.does( () => 'printing output...')
system.out.into(console.log)
system.run()
Partial Answer, implementation from comment suggestion by #Bellian, a bit on the way for sure, thanks!
Where? Inside function SystemBuilder(...):
Instead of
function Log() {}
Log.prototype.local = () => console.log('fields: ' + JSON.stringify(Object.keys(system))),
system.log = new Log()
Do this
function _local(system){
console.log('fields: ' + JSON.stringify(Object.keys(system)))
}
system.log = {local: _local.bind(this, system)}
Right now I am attempting to build a JavaScript library, albeit, it is very juvenile and I'm sure that it can be reworked to perform better. However, I'm currently storing some of my more common functions that I routinely use (while rendering HTML5 Canvas animations) and I have aforementioned JavaScript functions stored within their own flat file named canvasLab.js. My current structure is this:
var canvasLab = {
setCanvas: function(elem) {
if (elem == undefined) {
return Modernizr.canvas;
}
return document.getElementById(elem);
},
set2D: function(elem) {
return elem.getContext('2d');
},
... and everything works fine until I attempt to declare a function within another function:
getColorGradient: function(freqR,freqG,freqB,phaseA,phaseB,phaseC,center,width,length) {
if (center == undefined) center = 128;
if (width == undefined) width = 127;
if (length == undefined) length = 50;
colorArray=[];
frequency = 0.3;
amplitude = 127;
center = 128;
byte2Hex: function(n) {
nybHexString = '0123456789ABCDEF';
return String( nybHexString.substr( ( n >> 4 ) & 0x0F, 1 ) ) + nybHexString.substr(n & 0x0F, 1);
},
getRgb: function(r,g,b) {
return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
},
getGradientArray: function() {
for (var i=0; i<length; ++i) {
red = Math.sin(freqR * i + phaseA) * width + center;
green = Math.sin(freqG * i + phaseB) * width + center;
blue = Math.sin(freqB * i + phaseC) * width + center;
result = getRgb(red,green,blue);
this.colorArray[i] = result;
}
}
}
when I receive an 'unexpected token (' error at line 45:
byte2Hex: function(n) {
I'm sort of new to making JavaScript libraries (or Lib Objects), and I am still unsure about the best method(s) and syntax to use while developing a library. My hugest concern is that it is light weight internally, on the client's machine and in the browser. In either case, I do not understand why I cannot create a new method (i.e.: byte2Hex()) and have it instantiated through the parent object. Any criticism would surely be appreciated.
Your are defining your function as if it was in scope of an object
byte2Hex: function(n)
This line should say
byte2Hex = function(n)....
These two functions below also have the same issue
If you want to return them as methods then they should be wrapped in an object.
return {
getRgb: function(r,g,b) {
return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
},
getGradientArray: function() {//...
}
};
You also have a ton of references that are not scoped using the var statement.
To help you find, track these types of errors try pasting your code into:
http://www.jshint.com/
Sorry for being vague and confusing everyone, Im grateful for all the feedback but let me explain what i am trying to do.
I want to create an object called Multiplier with two methods: multiply and getCurrentValue
multiply should initially return the number supplied * 1 and from then on whatever the
current value is times the number supplied, getCurrentValue should return the last
answer returned from multiply.
Hey everyone I am having a little trouble grasping this concept.
Here is my code so far:
var multiplier = {
function multiply(){
alert("Input a number to be multiplied by 1")
var a = prompt("Input your desired number");
var b = a * 1;
return alert(b);
}
}
multiply();
any help or further explaining on how i would go about this would be appreciated
var multiplier = {
lastValue: null,
getCurrentValue: function() {
return lastValue;
},
multiply: function() {
alert("Input a number to be multiplied by 1")
var a = prompt("Input your desired number");
var b = a * 1;
lastValue = b;
return alert(b);
}
}
This should do what you want. You're defining an object named multiplier, that has two functions and a variable to save the last value.
Of course, there are other ways to accomplish this, but your question is a little vague.
A more object oriented approach would be like so.
function Multiplier() {
var lastValue = null;
this.getCurrentValue = function() {
return lastValue;
};
this.multiply = function() {
alert("Input a number to be multiplied by 1");
var a = prompt("Input your desired number");
var b = a * 1;
lastValue = b;
return alert(b);
}
}
With this approach, your lastValue variable is private. You've only exposed the two functions. Now you can create a new one of these objects whenever you need one, like so.
var myMultiplier = new Multiplier();
And you can call functions on that multiplier like so.
myMultiplier.multiply();
After different paradigms used to create HTML5 game engines, I'm very curious about the Component/Entity/Systems paradigm ; after a friend which is very skillful, told me about it.
If you don't know about it, it's rather simple:
An empty object called an entity
function GameEntity(){
this.components = {};
this.createComponent = function(name, args) {
this.components[name] = new componentList[name](this, args);
}
}
Contains elements which are modular in their nature and as independant as possible
'position': function(parentEntity){
this.entity = parentEntity;
var x = 50;
var y = 50;
this.setPosition = function(newX, newY) {
x = newX;
y = newY;
}
this.getPosition = function() {
return {"x" : x, "y" : y};
}
this.setX = function(value) {
x = value;
}
this.setY = function(value) {
y = value;
}
this.getX = function() {
return x;
}
this.getY = function() {
return y;
}
},
Which are acted upon by systems, each proper to a component
for (var i =0 ; i<game.ent.entityCounter ; i++){
game.ent.entities[i].components['mouvement'].update();
game.ent.entities[i].components['graphics'].update();
}
I've been trying to follow Unity's logic, so far.
Even though it's not a very precise question, how can I improve this little engine?
http://jsfiddle.net/5etgx/2/
It's very basic, but that's mostly the structure that focuses my attention, rather than the functionnality.
Let me know if you think anything is not done in a good manner.