How to Write JavaScript Object like that - javascript

How to write an Object for using this object like below
var cal = new calculator;
cal.add(10).add(20).miniz(2).div(2);
console.log(cal.result()); // result 14

Here you go, this is one way to do it:
My Example
var calculator = function() {
this.curr = 0;
this.add = function(n) {
this.curr += n;
return this; // returning this at the end of each method is the key to chaining
};
this.miniz = function(n) {
this.curr -= n;
return this;
};
this.div = function(n) {
this.curr = this.curr / n;
return this;
};
this.result = function() {
return this.curr;
};
};
You need to change the instantiation to this:
var cal = new calculator();

Just to get you started:
function Calculator() {
var value = 0;
this.add = function (v) {
value += v;
return this;
};
this.result = function () {
return value;
};
}
var cal = new Calculator;
console.log(cal.add(10).result()); // result 10

may be this is will help some what..
var Calc = function(){
this.value = 0;
};
Calc.prototype.add = function(val){
this.value += val;
return this;
};
then you can use like new Calc().add(100).add(100)
but before make sure understood how prototyping is working,
for ref : a sample

function calculator(){
this.val = 0;
this.add = function(num){
this.val += num;
return this;
};
this.miniz = function(num){
this.val -= num;
return this;
};
this.div = function(num){
this.val /= num;
return this;
};
this.result = function(){
return this.val;
};
}

Related

Uncaught TypeError: calc.init(...).add is not a function

I have some task, to do function-constructor that creates a calculator object with method.
init(), add(), mul(), div(), sub()
My code:
const calc = new Calculator();
console.log(
calc
.init(2)
.add(2)
.mul(3)
.div(4)
.sub(2).result // 1
);
calc.alert();
function Calculator() {
let result = 0;
this.alert = function() {
setTimeout(() => alert(result), 5000);
};
this.init = function(i) {
return result = i;
};
this.add = function(i) {
return result += i
};
this.mul = function(i) {
return result = result * i;
};
this.div = function(i) {
return result = result / i;
};
this.sub = function(i) {
return result = result - i;
};
}
But I don`t understand, how to fix error.
You are trying to achieve Javascript Chaining Method Pattern here. Here I'm adding a better solution.
var Calculator = function() {
this.result = 0;
};
Calculator.prototype.init = function(i) {
this.result = i;
return this;
};
Calculator.prototype.add = function(i) {
this.result = this.result + i;
return this;
};
Calculator.prototype.mul = function(i) {
this.result = this.result * i;
return this;
};
Calculator.prototype.div = function(i) {
this.result = this.result / i;
return this;
};
Calculator.prototype.sub = function(i) {
this.result = this.result - i;
return this;
};
Calculator.prototype.alert = function() {
setTimeout(() => alert(this.result), 5000);
return this;
};
const calc = new Calculator();
console.log(
calc
.init(2)
.add(2)
.mul(3)
.div(4)
.sub(2).result // 1
);
calc.alert();
Please try this.
const calc = new Calculator();
console.log(
calc
.init(2)
.add(2)
.mul(3)
.div(4)
.sub(2).result // 1
);
calc.alert();
function Calculator() {
let result = 0;
this.alert = function() {
setTimeout(() => alert(result), 5000);
};
this.init = function(i) {
this.result = i;
return this;
};
this.add = function(i) {
this.result += i;
return this;
};
this.mul = function(i) {
this.result = this.result * i;
return this;
};
this.div = function(i) {
this.result = this.result / i;
return this;
};
this.sub = function(i) {
this.result = this.result - i;
return this;
};
}

For-Loop using function from a Constructor

I'm going through Codecademy's lesson on building a Blackjack game with Javascript.
I'm having trouble coming up with code to put in the for-loop. I'm supposed to write a "score" method in the Hand constructor. It should loop over all of the cards in the Hand, summing up the result of the "getValue" call to each and return that sum.
Can someone help me out please? Thank You.
Here's my attempt, the relevant code is inside the for-loop at the bottom:
// Card Constructor
function Card(s, n) {
var suit = s;
var number = n;
this.getSuit = function() {
return suit;
};
this.getNumber = function() {
return number;
};
this.getValue = function() {
if (number >= 10) {
return 10;
} else if (number === 1) {
return 11;
} else {
return number;
}
};
};
//deal function
var deal = function() {
var randNum = Math.floor(Math.random() * 13) + 1;
var randSuit = Math.floor(Math.random() * 4) + 1;
console.log(randNum, randSuit);
return new Card(randSuit, randNum);
};
function Hand() {
var handArray = [];
handArray[0] = deal();
handArray[1] = deal();
this.getHand = function() {
return handArray;
};
this.score = function() {
var sum;
for (var i = 0; i < handArray; i++) {
sum += handArray[i].getValue;
return sum;
}
};
};
Well something like this should work :
this.score = function() {
return handArray.reduce( function( memo, val){
return memo + val.getValue();
});
};
I think you need to return the score, outside of the loop, like so:
this.score = function() {
var sum;
for (var i = 0; i < handArray; i++) {
sum += handArray[i].getValue();
}
return sum;
};
This fixed it. Thanks for your help!
this.score = function(){
var sum =0;
for(var i =0; i<handArray.length; i++){
sum += handArray[i].getValue();
};
return sum;
};

JavaScript way to define variable

Hello I saw "this" (now I just simplified it) code on a website source.
The question is:
Why is this._position defined with m(p) instead of just p ?
does it have some logical explanation ?
var emptyFunction = function j() {};
emptyFunction.thatReturnsValue = function(j) {
return j;
};
var m = emptyFunction.thatReturnsValue;
function o(){
this._position = 'left';
}
o.prototype.setPosition = function(p) {
'use strict';
this._position = m(p);
return this;
};
o.prototype.getPosition = function(){
return this._position;
}
function calculatePosition(oInst){
var position;
//( do some math to figure out the best position)
position = 'right';
oInst.setPosition(position);
}
function realWork(){
var orientation = new o();
calculatePosition(orientation);
console.log(orientation.getPosition());
}
empty function is used for more things:
**
function h(j) {
return function() {
return j;
};
}
var emptyFunction = function j() {};
emptyFunction.thatReturns = h;
emptyFunction.thatReturnsFalse = h(false);
emptyFunction.thatReturnsTrue = h(true);
emptyFunction.thatReturnsNull = h(null);
emptyFunction.thatReturnsThis = function() {
return this;
};
emptyFunction.thatReturnsValue = function(j) {
return j;
};
**

Where toString fails to work?

function dTree() {
return {
init : function(data) {
this.data = data;
},
node : function(i){
return '' + i;
}
}
};
dTree.prototype.toString = function() {
var str = '';
for(var i = 0; i < this.data.length; i++)
{
str += this.node(this.data[i]);
};
return str;
}
dTree1 = new dTree();
dTree1.init([1,2,3]);
alert(dTree1+'')
I'm expecting it to output 123
How to do it the right way?
That's not how you make constructors. Constructors don't return anything, they manipulate the this object:
function dTree() {
this.init = function(data) {
this.data = data;
};
this.node = function(i){
return '' + i;
};
}
You could also stick the definition of toString into the constructor as well, unless you're doing something special with it:
function dTree() {
this.init = function(data) {
this.data = data;
};
this.node = function(i) {
return '' + i;
};
this.toString = function() {
var str = '';
for(var i = 0; i < this.data.length; i++)
{
str += this.node(this.data[i]);
};
return str;
};
}
You are returning a plain new object from your constructor, the this object inside your constructor is not used at all, and that object is the one that has the right prototype object assigned.
function dTree() {
this.init = function(data) {
this.data = data;
};
this.node = function(i){
return '' + i;
};
}
dTree.prototype.toString = function() {
var str = '';
for(var i = 0; i < this.data.length; i++) {
str += this.node(this.data[i]);
};
return str;
};
dTree1 = new dTree();
dTree1.init([1,2,3]);
alert(dTree1 + '');

How to implement JavaScript Cascades..?

I'm reading "JavaScript the Good Parts" and it mentions cascades as a way to do method chaining in JavaScript but I can't find any code that explains how these methods should be implemented.
getElement('myBoxDiv').
move(350, 150).
width(100).
height(100).
color('red').
border('10px outset').
padding('4px').
appendText("Please stand by").
on('mousedown', function (m) {
this.startDrag(m, this.getNinth(m));
}).
on('mousemove', 'drag').
on('mouseup', 'stopDrag').
later(2000, function ( ) {
this.
color('yellow').
setHTML("What hath God wraught?").
slide(400, 40, 200, 200);
}).
tip('This box is resizeable');
The trick is that the method itself should only return this. That way, each time you chain these methods together, the object itself is the base of the call.
SomeObj.width(40) would then return just SomeObj, so adding the call .height(50) would function, and continue along.
In a cascade, we can call many methods on the same object in sequence in a single statement.
Lets try this example,
var Calc = function(){
this.result=0;
this.add = function(){
for(var x=0; x<arguments.length; x++){
this.result += arguments[x];
}
return this;
};
this.sub = function(){
for(var x=0; x<arguments.length; x++){
this.result -= arguments[x];
}
return this;
};
this.mult = function(){
if(this.result==0)this.result = 1;
for(var x=0; x<arguments.length; x++){
this.result *= arguments[x];
}
return this;
};
this.div = function(){
if(this.result==0) return this;
for(var x=0; x<arguments.length; x++){
this.result /= arguments[x];
}
return this;
};
this.eq = function(){
return this.result
};
}
var cal1 = new Calc();
cal1.add(3).sub(1).add(2) // Here result = 4;
These methods always return the object they belong to this, e.g.:
var txtProcesor = {
txt: '',
removeWhite: function () {
this.txt = this.txt.replace(/\s+/g, '');
return this;
},
evenToUp: function () {
var res = "";
for (var i = 0; i < this.txt.length; i++) {
if (i % 2 == 0) res += this.txt[i].toUpperCase();
else res += this.txt[i];
}
this.txt = res;
return this;
}
}
txtProcesor.txt = " abc def ";
alert(txtProcesor.removeWhite().evenToUp().txt);
This is basically the way JQuery works. The idea is to make each of those functions return objects which contain those functions again so to speak.
EDIT: You can download JQuery and look at the source code for it, because this is exactly what is going on in that library.
Here is a demo combine cascade with callback, and the usage, hope this will help.
let calNum = function(num) {
this.num = num;
this.add = function(dif, callback) {
this.num = this.num + dif;
callback(this.num);
return this;
}
this.sub = function(dif, callback) {
this.num = this.num - dif;
callback(this.num);
return this;
}
this.multi = function(m, callback) {
this.num = this.num * m;
callback(this.num);
return this;
}
return this;
};
calNum(3).add(3,function(result) {
console.log(result);
}).multi(2, function(result) {
console.log(result);
}).sub(1, function(result) {
console.log(result);
}); // The final result is 11
I was also going through the same book but didn't find any implementation of the concept. However I found this nice and short blog on this.
Here is how you can enable cascades:
function number(value) {
this.value = value;
this.plus = function (sum) {
this.value += sum;
return this;
};
this.return = function () {
return this.value;
};
return this;
}
console.log(new number(5).plus(1).return());

Categories

Resources