Hi I'm trying to implement a LinkedList in Javascript. When i assign a value to my node it doesn't seem to store it when I use my getter. For example:
var Node =function() {
var _data;
var _next ={};
var that = this;
that.getData = function() {
return _data;
};
that.setData = function(data) {
that._data = data;
};
that.getNext = function() {
return _next;
};
that.setNext = function(next) {
that._next = next;
};
return that;
};
Will not work with:
var nodeObj = new Node();
nodeObj.setData("hello");
console.log(nodeObj.getData());
_data is not the same as that._data, you must do this:
that.getData = function() {
return that._data;
};
OR you could do this instead:
that.setData = function(data) {
_data = data;
};
the benefit of the second approach being that you're simulating a private variable (because you cannot do nodeObj._data in the second case but you can in the first)
also var that = this; is unnecessary, you can simply do this._data in this case.
For your case here, you can assume that if you're calling a function like yourObject.someFunction(), then within someFunction the value of this equals yourObject. (And this isn't always true in javascript but since you're starting off you should think about it this way for now. If you pass a function to another function as a variable and then call it then this wouldn't be the case).
I have now officially spent all day trying to assign a variable in JavaScript!
Forgive me for asking this same question 4 different ways, but here's what I started out with this morning, and this works. I just need to add a second method to it now.
Application = {};
(function() {
var closure = {};
Application.myFirstMethod = function() {
if (arguments.length) {
closure = arguments[0];
} else {
return closure;
}
}
})();
Application.myFirstMethod(3.14);
result = Application.myFirstMethod();
log(result);
So my question is: and please be patient with me, if I add mySecondMethod to Application, then how do I keep the value of arguments[0] without using the variable that is currently called closure?
How about this, it defines a function that takes a string and returns a getter/setter function. The string is used to indicate what property to get/set the value as in variables.
Demo
Application = {};
(function() {
var variables = {};
Application.myFirstMethod = makeGetterSetter('myFirst');
Application.mySecondMethod = makeGetterSetter('mySecond');
function makeGetterSetter(name) {
return function () {
if (arguments.length) {
variables[name] = arguments[0];
} else {
return variables[name];
}
};
}
})();
Application.myFirstMethod(4);
result1 = Application.myFirstMethod();
Application.mySecondMethod(5);
result2 = Application.mySecondMethod();
console.log(result1);
console.log(result2);
If you wanted to have a getter or setter with custom logic in it before either event then it would be easiest to just define them separately. Stick with the this[property] pattern to keep all your fields in one spot.
Application.myCustomMethod = function() {
if (arguments.length) {
// some logic
variables['custom'] = arguments[0];
} else {
// some logic
return variables['custom'];
}
}
It looks like you are searching for adding properties to objects, in the Prototype-Oriented Programming Language sense of the term; just use the "this" object, which stands for the current calling context, and which will be set to your Application object when calling the methods:
Application = {};
(function() {
Application.myFirstMethod = function() {
if (arguments.length) {
this.foo = arguments[0];
} else {
return this.foo;
}
};
Application.mySecondMethod = function() {
if (arguments.length) {
this.bar = arguments[0];
} else {
return this.bar;
}
};
})();
Application.myFirstMethod(3.14);
console.log(Application.myFirstMethod());
Application.mySecondMethod(2097);
console.log(Application.mySecondMethod());
console.log(Application.myFirstMethod());
Here's what I figured out. I probably need to use the word new somewhere though.
Application = {};
(function() {
Application.myFirstMethod = FirstMethod();
Application.mySecondMethod = SecondMethod();
function FirstMethod() {
var closure = {};
return function(myArgument) {
if (arguments.length) {
closure.result = arguments[0]; // myArgument
} else {
return closure.result;
}
}
}
function SecondMethod() {
var closure = {};
return function(myArgument) {
if (arguments.length) {
closure.result = arguments[0]; // myArgument
} else {
return closure.result;
}
}
}
})();
Application.myFirstMethod(3.14);
result = Application.myFirstMethod();
log(result);
Application.mySecondMethod(2013);
result = Application.mySecondMethod();
log(result);
Code:
var test = {
con: true
};
var conrun= function(){
return this.con;
};
Function.prototype.curry = function(scope){
var fn = this;
var scope = scope||window;
return function(){
fn.apply(scope,arguments);
}
}
conrun = conrun.curry(test);
alert(conrun());
//result:undefined
"curry" method, the function will return, "conrun" fonkiyonuna "test" add to the scope of...
What should I do ?
Your curry loses the return value. Change that line to:
return fn.apply(scope, arguments);
I know you can create literal objects with subobjects and functions:
var obj = {
val : 1,
level1 : {
val : 2,
val2 : 3,
func : function(){
return this.val2
}
}
}
console.log(obj.val);
console.log(obj.level1.val);
console.log(obj.level1.func());
outputs:
1
2
3
What I would like to do is do the same thing with methods in a object, something similar to:
function objType() {
this.val = 1;
this.func = function(){
return this.val;
}
this.level1 = function(){
this.val = 2;
this.func = function(){
return this.val;
}
this.level2 = function(){
this.val = 3;
this.func = function(){
return this.val;
}
}
};
};
then i would expect:
var obj = new objType();
console.log(obj.func());
console.log(obj.level1.func());
console.log(obj.level1.level.func());
to output:
1
2
3
However, only the first console.log outputs before the script throws an error.
Is there any way to have sub methods in Javascript?
--edit--
My goal is to create a class i can use for showing a box in the middle of the screen, for displaying messages, questions(to get a yes/no response), and forms. I was thinking a good way to structure it would be with sub methods, so that it could then be referenced with:
function box() {
this.show = function(){
//multiple sub methods here
}
this.hide = function(){
//code to hide window here
}
}
var aBox = new box();
aBox.show.message('the message');
aBox.hide();
aBox.show.question('the question');
aBox.hide();
--edit--
thanks #Sean Vieira
For completeness I'll put the modified version of my code here using his solution:
function objType() {
this.val = 1;
this.func = function(){
return this.val;
}
this.level1 = {
val : 2,
func : function(){
return this.val;
},
level2 : {
val : 3,
func : function(){
return this.val;
}
}
}
var obj = new objType();
console.log(obj.func());
console.log(obj.level1.func());
console.log(obj.level1.level.func());
that outputs
1
2
3
you can do this easily with chaining
function Box() {
this.show = function(){
//your code goes here
return this;
},
this.message = function(message){
//code goes here
return this;
}
}
var aBox = new Box();
aBox.message('the message').show()
Your issue is that this in JavaScript refers to the containing scope -- which in the case of a function invoked with the new operator is a new Object and this applies everywhere within the scope of that function (unless you create a new scope in some way.)
So in your code we can replace this with an imaginary "new" object ... let's call it that.
function objType() {
var that = {}; // This is what `new` does behind the scenes
// (Along with a few other things we won't replicate here).
that.val = 1;
that.func = function(){
return that.val;
}
// Do additional things with `that` here
return that;
}
However, whenever you deal with a function that you are not calling as a "class" (as in a free-standing function or a "method" of an object) then this is set dynamically at runtime.
This means that:
function log_this() {
console.log(this,
"Type:", typeof this,
"IsObject:", this instanceof Object,
"IsFunction:", this instanceof Function);
}
log_this() // window (i.e. global scope)
log_this.apply({"some":"object"}) // {"some":"object"}
log_this.apply(function(){}) // Anonymous function function(){}
var test_object = { fun: log_this };
test_object.log_this() // test_object
This might work for level1:
var obj2 = new obj.level1();
console.log(obj2.func());
This is what I'm doing right now.
var foo = function() {
var x = someComplicatedComputationThatMayTakeMoreTime();
this.foo = function() { return x; };
return x;
}
It works but only if foo is called as a function like so
foo();
But what if I want to call it as a normal variable with a value? I could modify the code to be
var foo = function() {
var x = someComplicatedComputationThatMayTakeMoreTime();
this.foo = x;
return x;
}
That would allow me to only call it once as a function and after that as a regular variable. But it's still not what I want. Plus it gets complicated if it accidentally gets called as a function again, returning an error.
Is this even possible in JavaScript?
BTW, this is for a Chrome/Firefox extension, so IE compatibility does not matter.
Ended up using toString because getters don't allow me to redefine the whole attribute, a function must be associated with it. And toString has cleaner syntax.
How about using toString?
var foo = function() {
function someComplicatedComputationThatMayTakeMoreTime() {
//your calculations
}
return {
toString: function() {
return someComplicatedComputationThatMayTakeMoreTime();
}
}
}
More about Object-to-Primitive Conversions in JavaScript
EDIT based on comment. Use a singleton (I think it's called):
myObject.prop = (function(){
function someComplicatedComputationThatMayTakeMoreTime() {
//your calculations
}
return {
toString: function() {
return someComplicatedComputationThatMayTakeMoreTime();
}
}
})()
If only Internet Explorer didn't exist, you could use getters and setters as described by John Resig in this blog article:
John Resig: JavaScript Getters and Setters
... They allow you to bind special functions to an object that look like normal object properties, but actually execute hidden functions instead.
Using a function is your best option for now, however the new JavaScript standard (ECMAScript 5th Ed.) which is being implemented now by all major browser vendors, gives you a method to create accessor properties, where you can define a property with a get and set functions that will be internally called, without worrying to treat this properties as functions, e.g.:
var obj = {};
Object.defineProperty(obj, 'foo', {
get: function () { // getter logic
return 'foo!';
},
set: function (value) {
// setter logic
}
});
obj.foo; // "foo!", no function call
This new standard will take some time to be implemented for all browsers, (the IE9 preview version really disappointed me), and I wouldn't recommend you to use it for production, unless you have total control on the environment where your application will be used.
What I think you want is a lazily instantiated variable, which can be implemented like this.
var myProperty = null;
function getMyProperty() {
return (myProperty = myProperty || builder());
}
This is not practical on the web because IE does not support it, but you can look at
https://developer.mozilla.org/en/defineGetter for examples how to do this.
There are a couple ways to do it, here is one example:
var data = {};
data.__defineGetter__("prop",
(function () {
var value = null;
return function () {
if (null == value) {
value = getYourValueHere();
}
return value;
};
})());
and now you can use it like:
var a = data.prop;
var b = data.prop;
I would recommend a variation on ChaosPandion's answer, but with a closure.
var myProperty = (function () {
var innerProperty = null;
return function() {
return (innerProperty = innerProperty || someComplicatedComputationThatMayTakeMoreTime());
};
})();
and then use myProperty() every time you need to access the variable.
You could define a JavaScript getter. From the Apple JavaScript Coding Guidelines:
myObject.__defineGetter__( "myGetter", function() { return this.myVariable; } );
var someVariable = myObject.myGetter;
See John Resig's post, JavaScript Getters and Setters, and the Defining Getters and Setters page at the Mozilla Developer Centre for more information.
I would use explicit lazy evaluation. Here's my implementation of it based on Scheme's take:
var delay, lazy, force, promise, promiseForced, promiseRunning;
(function () {
var getValue = function () {
return this.value;
};
var RUNNING = {};
var DelayThunk = function (nullaryFunc) {
this.value = nullaryFunc;
};
DelayThunk.prototype.toString = function () {
return "[object Promise]";
};
DelayThunk.prototype.force = function () {
if (promiseRunning (this)) {
throw new Error ("Circular forcing of a promise.");
}
var nullaryFunc = this.value;
this.value = RUNNING;
this.value = nullaryFunc ();
this.force = getValue;
return this.value;
};
var LazyThunk = function (nullaryFunc) {
DelayThunk.call (this, nullaryFunc);
};
LazyThunk.prototype = new DelayThunk (null);
LazyThunk.prototype.constructor = LazyThunk;
LazyThunk.prototype.force = function () {
var result = DelayThunk.prototype.force.call (this);
while (result instanceof LazyThunk) {
result = DelayThunk.prototype.force.call (result);
}
return force (result);
};
delay = function (nullaryFunc) {
return new DelayThunk (nullaryFunc);
};
lazy = function (nullaryFunc) {
return new LazyThunk (nullaryFunc);
};
force = function (expr) {
if (promise (expr)) {
return expr.force ();
}
return expr;
};
promise = function (expr) {
return expr instanceof DelayThunk;
};
promiseForced = function (expr) {
return expr.force === getValue || !promise (expr);
};
promiseRunning = function (expr) {
return expr.value === RUNNING || !promise (expr);
};
}) ();
Example Syntax:
var x = lazy (function () { return expression; });
var y = force (x);
var z = delay (function () { return expression; });
var w = force (z);
Note values are stored once evaluated, so repeated forcing will not do extra computations.
Example usage:
function makeThunk (x, y, z) {
return lazy (function () {
// lots of work done here
});
}
var thunk = makeThunk (arg1, arg2, arg3);
if (condition) {
output (force (thunk));
output (force (thunk)); // no extra work done; no extra side effects either
}
You can use the javascript Proxy class for creating such functionality.
var object = {};
var handler = {
resolvers: {},
get ( target, property, proxy ) {
if ( ! target.hasOwnProperty( property ) && this.resolvers.hasOwnProperty( property ) ) {
// execute the getter for the property;
target[ property ] = this.resolvers[ property ]();
}
return target[ property ];
},
set ( target, property, value, receiver ) {
// if the value is function set as a resolver
if ( typeof value === 'function' ) {
this.resolvers[property] = value;
// otherwise set value to target
} else {
target.property = value;
}
},
has ( target, property, receiver ) {
//true when proxy handler has either a resolver or target has a value;
return this.resolvers.hasOwnProperty( property ) || target.hasOwnProperty( property );
}
};
var lazyObject = new Proxy( object, handler );
Now you can use it like this:
'exampleField' in lazyObject; //returns false
lazyObject.exampleField = function(){ return 'my value' }; // add a resolver function
'exampleField' in lazyObject; //returns true
lazyObject.exampleField; //executes your resolver function and returns 'my value'
This example is to demonstrate the working. You can change after your needs.
Here is a fiddle with a demonstration