How to create constructor function Count? - javascript

Function count() return 1, 2, 3... How to create constructor function Count?
var count = new Count();
count(); // 1
count(); // 2

function Count() {
var c = 1;
return function() {
return c++;
}
};
var count = new Count(); // count is now a function that adds and returns
count(); // 1
count(); // 2

function Count() {
this.x = 0;
this.count = function() {
return (this.x += 1);
};
}
counter = new Count();
counter.count(); //1
counter.count(); //2

Declare a variable globally:
var counter=0;
Create a function to return the value:
function count() {
return ++counter;
}

A constructor needs to return an object for the most part,
so returning a number in the constructor will just return the instance of that function,
not the number. You can explicitly return an object, however, so the closest you can get is:
;(function() {
var count = 0;
window.Count = function() {
return new Number(count += 1);
}
})()
var a = +new Count // 1
var b = +new Count // 2
Of course, you could just do:
window.count = (function(){
var i = 0;
return function() {
return i += 1;
}
})()
var a = count() // 1
var b = count() // 2
Which makes more sense in most cases.

Related

For loop without using for statement

I'm trying to write a program where you print a decrement by 1 loop, so if the value is 3 the output should be 3,2,1. But the output I get from this code is 3,2,1,0. Are there any ways I can fix this?
function loop(value) {
while(greaterThanZero(value) == true) {
printValue(value);
value = reduceOne(value);
console.log(value);
value--;
}
}
var value = 3;
var greaterThanZero = function (n) {
return n > 0;
}
var reduceOne = function (n) {
return n - 1;
}
var printValue = function (n) {
console.log(n)
}
You're doing the same thing twice in each iteration (logging and decrementing). Remove the two duplicate statements so you can break out immediately instead of going two at a time.
function loop(value) {
while(greaterThanZero(value) == true) {
console.log(value);
value--;
}
}
var greaterThanZero = function (n) {
return n > 0;
}
loop(3)
The function seems to be working as expected but you are seeing 0 because of this console.log(value). It is just logging the value after decrementing it
var value = 3;
var greaterThanZero = function(n) {
return n > 0;
}
var reduceOne = function(n) {
return n - 1;
}
var printValue = function(n) {
console.log(n)
}
function loop(value) {
while (greaterThanZero(value) == true) {
printValue(value);
value = reduceOne(value);
//console.log(value);
//value--;
}
}
loop(value)

Reseting a counter of a protected/nested variable in JavaScript

My intention is to create a safe counter and reset it by calling a function. I tried this code:
function ZeroCounter () { var c = 0 ; return function() { return ++c } };
const Counter = ZeroCounter();
But didn't work as I expected. ZeroCounter doens't reset var C. I noticed that function() return creates a new object.
var m = ZeroCounter(); var n = ZeroCounter();
m === n //return false
I tried a new code for ZeroCounter.
function ZeroCounter () { var c = 0 ; ret = function() { return ++c }; return ret };
In fact, no reasons for new results. So, What can I do to reach my intention: create a resetable nested variable? Or is it not possible in this way?
Basically, you're re-creating c each time you execute ZeroCounter. To get around that, move c outside of ZeroCounter.
var c = 0;
function ZeroCounter() {
return ++c;
}
var m = ZeroCounter();
var n = ZeroCounter();
console.log(m);
console.log(n);
If you want to contain c within ZeroCounter but still want the effect, use an Immediately Invoked Function Expression or IIFE
var ZeroCounter = (function () {
var c = 0;
return function () {
return ++c;
};
}());
var m = ZeroCounter();
var n = ZeroCounter();
console.log(m);
console.log(n);
You could use the parameter of the function and reset to a wanted value.
function counter() {
var c = 0;
return function(v) {
if (v !== undefined) c = v;
return ++c
};
}
const counterA = counter();
console.log(counterA());
console.log(counterA());
console.log(counterA());
console.log(counterA(0));
console.log(counterA());
console.log(counterA());

Is it possible to use module pattern for more objects

var modularpattern = (function () {
var sum = 0;
return {
add: function () {
sum = sum + 1;
return sum;
},
}
} ());
var c = modularpattern;
c.add(); // 1
var d = modularpattern;
d.add(); // 2 but I want to be 1
console.log(modularpattern.add()); // alerts: 3
Is it possible to have more objects not only one? I want to have private fields but at the same time also having more that just one object?
Yes, that's easily possible by dropping the IIFE invocation to get a normal function instead. Only it's called factory pattern then, no longer module.
function factory() {
var sum = 0;
return {
add: function () {
sum = sum + 1;
return sum;
}
}
}
var c = factory();
c.add(); // 1
var d = factory();
d.add(); // 1
console.log(c.add()); // logs: 2
You can use the module pattern to create a factory which uses the module pattern to create more objects. Using your original example, it would look something like this:
var moduleFactory = (function() {
return {
create: function() {
return (function() {
var sum = 0;
return {
add: function() {
sum = sum + 1;
return sum;
}
}
})();
}
}
}
)();
var c = moduleFactory.create();
console.log(c.add()); //1
var d = moduleFactory.create();
console.log(d.add()); //1

JSON and scope. Using a closure

I am trying to understand why the variable index is being updated ( added and subtracted ) when my function returns an object.
var init = (function() {
var index = 0;
return function() {
return {
subtract: index -= 1,
add: index = index + 1,
getIndex: index
}
}
})();
console.log(init().getIndex); // 1
console.log(init().add); // 2
console.log(init().getIndex); //2
Instead 0 is returned. This is because when the object is returned all of the properties in that returned object are execute. SO my question is how do i prevent that from happening.
I highly doubt it returns 0. It should return undefined:
var f = init();
// f is now the returned function. Therefore:
f.getIndex; // should be undefined
f().getIndex; // should be 1
Therefore, the to get the expected output, change your code to:
console.log(init()().getIndex); // 1
console.log(init()().add); // 2
console.log(init()().getIndex); //2
var init = (function() {
var index = 0;
return function() {
return {
subtract: function() { return --index; },
add: function() { return ++index; },
getIndex: function() { return index; }
}
}
})();
console.log(init().getIndex()); // 0
console.log(init().add()); // 1
console.log(init().getIndex()); // 1
subtract, add and getIndex aren't being initiated as functions. They are receiving the values -1, 0 and 0.
To return operations set
var init = (function() {
var index = 0;
return {
subtract: function () { index -= 1 },
add: function () { index + 1 }, // Should probably be += here
getIndex: function () { return index; }
}
}();

Set length property of JavaScript object

Let's say I have a JavaScript object:
function a(){
var A = [];
this.length = function(){
return A.length;
};
this.add = function(x){
A.push(x);
};
this.remove = function(){
return A.pop();
};
};
I can use it like so:
var x = new a();
x.add(3);
x.add(4);
alert(x.length()); // 2
alert(x.remove()); // 4
alert(x.length()); // 1
I was trying to make .length not a function, so I could access it like this: x.length, but I've had no luck in getting this to work.
I tried this, but it outputs 0, because that's the length of A at the time:
function a(){
var A = [];
this.length = A.length;
//rest of the function...
};
I also tried this, and it also outputs 0:
function a(){
var A = [];
this.length = function(){
return A.length;
}();
//rest of the function...
};
How do I get x.length to output the correct length of the array inside in the object?
You could use the valueOf hack:
this.length = {
'valueOf': function (){
return A.length;
},
'toString': function (){
return A.length;
}
};
Now you can access the length as x.length. (Although, maybe it's just me, but to me, something about this method feels very roundabout, and it's easy enough to go with a sturdier solution and, for example, update the length property after every modification.)
If you want A to stay 'private', you need to update the public length property on every operation which modifies A's length so that you don't need a method which checks when asked. I would do so via 'private' method.
Code:
var a = function(){
var instance, A, updateLength;
instance = this;
A = [];
this.length = 0;
updateLength = function()
{
instance.length = A.length;
}
this.add = function(x){
A.push(x);
updateLength();
};
this.remove = function(){
var popped = A.pop();
updateLength();
return popped;
};
};
Demo:
http://jsfiddle.net/JAAulde/VT4bb/
Because when you call a.length, you're returning a function. In order to return the output you have to actually invoke the function, i.e.: a.length().
As an aside, if you don't want to have the length property be a function but the actual value, you will need to modify your object to return the property.
function a() {
var A = [];
this.length = 0;
this.add = function(x) {
A.push(x);
this.length = A.length;
};
this.remove = function() {
var removed = A.pop();
this.length = A.length;
return removed;
};
};
While what everyone has said is true about ES3, that length must be a function (otherwise it's value will remain static, unless you hack it to be otherwise), you can have what you want in ES5 (try this in chrome for example):
function a(){
var A = [],
newA = {
get length(){ return A.length;}
};
newA.add = function(x){
A.push(x);
};
newA.remove = function(){
return A.pop();
};
return newA;
}
var x = a();
x.add(3);
x.add(4);
alert(x.length); // 2
alert(x.remove()); // 4
alert(x.length); // 1
You should probably use Object.create instead of the function a, although I've left it as a function to look like your original.
I don't think you can access it as a variable as a variable to my knoledge cannot return the value of a method, unless you will hijack the array object and start hacking in an update of your variable when the push/pop methods are called (ugly!). In order to make your method version work I think you should do the following:
function a(){
this.A = [];
this.length = function(){
return this.A.length;
};
this.add = function(x){
this.A.push(x);
};
this.remove = function(){
return this.A.pop();
};
};
These days you can use defineProperty:
let x = {}
Object.defineProperty(x, 'length', {
get() {
return Object.keys(this).length
},
})
x.length // 0
x.foo = 'bar'
x.length // 1
Or in your specific case:
Object.defineProperty(x, 'length', {
get() {
return A.length
}
})
function a(){
this.A = [];
this.length = function(){
return this.A.length;
};
this.add = function(x){
this.A.push(x);
};
this.remove = function(){
return this.A.pop();
};
};

Categories

Resources