I need more clarification for this problem.I have an object and it has two functions as like this.
<script type="text/javascript">
obj =
{
f1 : function ()
{
var k = this. f2(param1 , param2 , param3);// I don't know whether it is correct
},
f2 : function (par1 , par2 , par3)
{
return param1 + param2 + param3;
}
}
</script>
How can I call function f2 from f1? Can I declare f1 in f2? If yes, how is it? Which is the best method?
Not to replace the above answers, but to provide an alternative: when I write definitions of objects that have methods I prefer to use function constructor so that I can hide "private" closure variables and have some resemblance to OOP.
var myClass = function() {
/******** PRIVATE **********/
var _s = "foo"; // Private member
var _f = function() {}; // Private method
/******** PUBLIC **********/
this.s = "bar"; // Public member
this.f1 = function() { // Public method
console.log(_s + " " + this.s); // Concat private and public
}
this.f2 = function() {
this.f1();
}
}
var myObject = new myClass();
myObject.f2(); // prints "foo bar"
You can use it by the code you have given,but be care of the scope.
Please consider the output of following two part of code.
obj =
{
f1 : function () {
var k = this. f2(1 , 2 , 3);
},
f2 : function (par1 , par2 , par3){
console.log(this);
return par1 + par2 + par3;
}
}
obj.f1();
and
obj =
{
f1 : function () {
var k = this. f2(1 , 2 , 3);
},
f2 : function (par1 , par2 , par3){
console.log(this);
return par1 + par2 + par3;
}
}
function MyClass () {
return this;
}
MyClass.prototype = obj;
var tmp = new MyClass();
tmp.f1();
You also can declare f1 in f2,but if you want to use f1 at the other place,you must write f1 agian.
To share this, the functions would be better to be added to obj.prototype.
obj = {};
obj.prototype = {
f1: function(){
},
f2: function(params){
}
};
Something like this may give you a better idea. I have tested it it runs fine.
obj =
{
f1 : function ()
{
console.log("in F1");
obj.f2();
},
f2 : function ()
{
console.log("in F2");
}
};
console.log(obj.f1());
Here is the fiddle to it => http://jsfiddle.net/CJ7Uz/
calling f2 like this:
<pre>
<script type="text/javascript">
obj =
{
f1 : function ()
{
var k = this.f2(1 , 2 , 3);// it is correct :)
alert(k);
},
f2 : function (par1 , par2 , par3)
{
return par1 + par2 + par3;
}
}
obj.f1();
</script>
</pre>
and check the link below to find the answer of your second question
http://www.phpied.com/3-ways-to-define-a-javascript-class/
Going off of Barmar's suggestion, here's what the code would look like:
<script type="text/javascript">
var obj = {
f1: function () {
var k = this.f2(param1 , param2 , param3);
},
f2: function (par1 , par2 , par3) {
return par1 + par2 + par3;
}
};
</script>
Also, bad idea to stick a space after this. in your code. :)
your problem is resolved:
Click
obj =
{
f1 : function ()
{
alert('f1');
var param1=param2=param3=0;
var k = this.f2(param1 , param2 , param3);
},
f2 : function (param1 , param2 , param3)
{
alert('f2')
return param1 + param2 + param3;
}
}
For demo visit this link DEMO
Related
I would like to write curring function for object methods. I want to make this possible:
Function.prototype.curry = function (){
var originalFunction = this;
var args = ...; // here goes logic embracing arguments
var bind = ???; //how to get reference to someObject ???
return function(){
return originalFunction.apply(bind, args);
}
}
var someObject = {
doSomething : function (param1, param2, param3){
//do something with params
return param1 + ' ' + param2 + ' ' + param3;
}
}
someObject.doSomethingCurried = someObject.doSomething.curry('param1 value', 'param2 value');
//I want to be able to do:
someObject.doSomethingCurried('param3 value')'
There are some tricks, but in fact you should just pass context as a first argument, like native bind.
// Code goes here
Function.prototype.curry = function (context,arg){
var originalFunction = this;
var args = Array.prototype.slice.call(arguments,1) ; // here goes logic embracing arguments
var bind = context; //how to get reference to someObject ???
return function(){
return originalFunction.apply(bind, args.concat(Array.prototype.slice.call(arguments)));
}
}
var someObject = {
myObj:"Myobj",
doSomething : function (param1, param2, param3){
console.log(this);
//do something with params
return param1 + ' ' + param2 + ' ' + param3;
}
}
someObject.doSomethingCurried = someObject.doSomething.curry(someObject,'param1 value', 'param2 value');
//I want to be able to do:
console.log(someObject.doSomethingCurried('param3 value'));
function condition(){
this.expression = "";
this.toString = function(){
return this.expression;
}
};
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop.prototype = condition.prototype;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());
it is expected to see "1 and 2" as output but this is what happened:
"[object Object]"
You are transfering the prototype of condition to nop's prototype. The problem is that your condition.toString is not declared in the prototype... Here:
function condition(){
this.expression = "";
};
condition.prototype.toString = function(){
return this.expression;
}
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop.prototype = condition.prototype;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());
OR
function condition(){
this.expression = "";
this.toString = function(){
return this.expression;
}
};
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop = condition;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());
you aren't overriding the toString method, because the constructer of condition is never called! try doing this;
condition.prototype.toString=function(){
return this.expression;
}
try passing strings into your and function, as at the moment you are trying to concatenate integers to a string var a =new and("1","2");
it should be like this
function condition(){
this.expression = "";
};
condition.prototype.toString = function(){
return this.expression;
}
Ok, so the problem here is you are mixing two inheritance patterns (http://davidshariff.com/blog/javascript-inheritance-patterns/) the pseudo-classical with the functional patterns.
You can create an object by adding methods on the constructor function:
function MyClass() {
var privateProperty = 1;
this.publicProperty = 2;
function pivateMethod() {
// some code ...
}
this.publicMethod = function() {
// some code ...
};
}
// inheritance
function SubClass() {
MyClass.call(this);
this.newMethod = function() { };
}
Here when you create a instance of this class you are creating every method again.
Then you have the prototype pattern:
function MyClass() {
this._protectedProperty = 1;
this.publicProperty = 2;
}
MyClass.prototype._protectedMethod = function() {
// some code ...
};
MyClass.prototype.publicMethod = function() {
// some code ...
};
// inheritance
function SubClass() {
MyClass.call(this);
}
SubClass.prototype = new MyClass();
SubClass.prototype.newMethod = function() { };
// OR
function SubClass() {
MyClass.call(this);
}
function dummy() { }
dummy.prototype = MyClass.prototype;
SubClass.prototype = new dummy();
SubClass.prototype.newMethod = function() { };
Yhen you must choose one of those two patterns, not both·
I've fixed your code on this fiddle: http://jsfiddle.net/dz6Ch/
I have something like this:
dog = function () {
this.age;
this.name;
this.dog1 = new dog.shepherd();
}
dog.prototype = {
bark : function () {
alert( (this.getName()) + " is barking." );
},
[3]**getName** : function () {
return this.name;
}
}
dog.shepherd = function () {
this.something;
}
dog.shepherd.prototype = function () {
guard : function () {
alert( ([2]**parent.getName()**) + " is barking." );
}
}
window.onload = function () {
var n = new dog();
[1]**n.guard()**;
}
How can I use a function which is prototyped to the dog from dog.speherd prototype?
In other words, when [1] is executed, then [2] is written in pseudo-code, to call [3].
I know this code shouldn't work; it's just to help me explain what I want.
Your title says you want to use composition, but your question body implies inheritance. Here's how you would do this with composition, which is probably the better option. A shepherd "is not a" dog after all (nor vice versa) so inheritance probably isn't right here.
Also, you usually don't want to set the entire prototype of a function like you're doing; just add the functions you want. And constructor functions by convention start with a capital letter.
function Shepherd(mydog) {
this.dog = mydog;
}
Shepherd.prototype.guard = function () {
alert( this.dog.getName() + " is barking." );
}
function Dog(age, name) {
this.age = age;
this.name = name;
}
Dog.prototype.getName = function () {
return this.name;
}
Dog.prototype.bark = function () {
alert(this.getName() + " is barking." );
}
window.onload = function () {
var someDog = new Dog(4, "Ubu");
var someShepherd = new Shepherd(someDog);
someShepherd.guard();
}
jsfiddle
I don't know why you need such code, but you can try this:
dog = function () {
this.age;
this.name;
this.dog1 = new dog.shepherd(this);
var d = this.dog1;
for (var i in dog.shepherd.prototype) {
this[i] = function(){
return this.dog1[i].apply(d, arguments);
}
}
}
dog.prototype = {
bark : function () {
alert( (this.getName()) + " is barking." );
},
getName : function () {
return this.name;
}
}
dog.shepherd = function (parent) {
this.parent = parent;
this.something;
}
dog.shepherd.prototype = {
guard : function () {
alert( (this.parent.getName()) + " is barking." );
}
}
window.onload = function () {
var n = new dog();
n.guard();
}
I am confused about the return statement in a function that serves as a class. See the example code below:
<html>
<body>
<script type="text/javascript">
function test() {
this.abc = 'def';
return 3;
}
var mytest = new test();
document.write(mytest + ', ' + (typeof mytest) + ', ' + mytest.abc);
</script>
</body>
</html>
The code out put: [object Object], object, def.
Here is my question. I wrote 'return 3' in the test() function. Is this statement ignored when 'new test()' is called?
Thanks.
When you call a function with new, you're invoking it as a constructor which automatically returns the new object it constructs.
Your return 3; statement is ignored. What is returned is effectively:
{ abc:'def' }
...with an implicit reference to a prototype object, which in your example doesn't have any enumerable properties because you haven't given it any.
If you did:
mytest instanceof test;
...it would evaluate to true.
If you did:
function test() {
this.abc = 'def';
}
test.prototype.ghi = 'jkl';
var mytest = new test();
...you could then do:
mytest.ghi;
...which would give you the value 'jkl'.
When you use the new operator, you're using the function as a constructor, in that case for the return value:
if it's not an object, it is ignored (like in your example)
if it is an object, the object returned becomes the result of the whole new expression
So if you were to write
Test = function(arg) {
this.a = 1;
return arg;
}
var t1 = new Test(10);
var t2 = new Test({b: 2});
console.log(t1, t2)
// output:
// Test {a:1} Object {b: 2}
The new operator instantiates and returns an object. Here are some examples with its output:
(...)
var mytest = test();
document.write(mytest + ', ' + (typeof mytest) + ', ' + mytest.abc);
// 3, number, undefined
Or:
function test() {
this.abc = 'def';
this.getvalue = function(){
return 3;
}
}
var mytest = new test();
document.write(mytest.getvalue() + ', ' + (typeof mytest) + ', ' + mytest.abc);
// 3, object, def
you can do
function test(){
this.abc = "def"
this.ghi = function(){
return "jkl"
}
}
or
function test(){
this.Class = function(){
this.def = "abc"
this.jkl = "ghi"
}
this.abc = "def"
this.ghi = function(){
return "jkl"
}
}
How do I access 'a' below?
var test = function () {
return {
'a' : 1,
'b' : this.a + 1 //doesn't work
};
};
You can't do it this way. When you are in the process of constructing an object (that's what you actually do using the curly braces), there is no way to access it's properties before it is constructed.
var test = function () {
var o = {};
o['a'] = 1;
o['b'] = o['a'] + 1;
return o;
};
var t = function ()
{
return new x();
};
var x = function ()
{
this.a = 1;
this.b = this.a + 1; //works
}
abstract a layer
edited for formatting, and noting that this is shifting from OLN
You can't Object Literal Notion does not support this access
var test = function () {
//private members
var a = 1;
var b = a + 1;
//public interface
return {
geta : function () {
return a;
},
getb : function () {
return b;
}
}
}();