prototype vs apply in javascript - javascript

If I need a object into another for use in a function, which is the best?
function A() {
this.alert = function () {
console.log(b.value);
}
this.alert2 = function () {
console.log(this.value);
}
}
function B() {
this.value = 'test';
}
var a = new A();
var b = new B();
A.prototype.b = b;
// Option 1
`a.alert();`
// Option 2
`a.alert2.apply(b);`
I believe option 2 is better because only use the object (b) in one function.

The prototype is much easier, but I'd use it the other way round:
function B() {
this.value = 'test';
}
B.prototype.alert = function() {
console.log(this.value);
}
var b = new B();
b.alert();
If you want to use a function/method of a different object, you should give it a parameter (instead of using an implicit global b variable like in your a.alert function):
var a = {
alert: function(x) {
console.log(x.value);
}
};
a.alert(b);
or inherit from it when you have a method, like:
var a = {
value: "a test",
alert: function() {
console.log(this.value);
}
};
// =============================
function B() {
this.value = 'test';
}
B.prototype.alert = a.alert; // mixin inheritance
var b = new B();
b.alert();

There isn`t a best option, its about what you have to do.
The first option by putting b in its prototype makes A to be more coupled to b.
The 2nd one you are changing its contests.. you need to know what the function does, if you don`t have the documentation you may pass an object wich doesnt has a property needed for the function, so that is not a good choice to make an api for example.
Algo wouldn`t it be happier to set this.alert to a function which receives a parameter?
It all depende on your needs...

Related

How to call child function which is declared inside another function

Function b is declared inside function a. So, i am trying to call function b outside function a. It is not getting called.
var a = function() {
alert("a");
var b = function() {
alert("b");
}
}
Output:-
function b called
Alert box with message b
You'd need to return b and use that. This will involve calling the function a to begin with, but then you'd have a function which you could call repeatedly to alert b:
var a = function() {
alert("a");
var b = function() {
alert("b");
}
return b;
}
var messageB = a();
messageB();
messageB();
First return that function and call it,
var a = function() {
alert("a");
var b = function() {
alert("b");
}
return b;
}
var b = a();
b();
Try to declare 'b' variable outside 'a' function:
var b;
var a = function() {
alert("a");
b = function() {
alert("b");
};
};
That way, you can access b from outside of a as it is declared outside of it. Before a was called the first time, it will be undefined though, so you can't call b before a. Additionally if you call a twice, the previous b will be overriden., as shown here:
var b;
var a = function(name) {
b = function() { alert(name); };
};
a("first version");
b(); // first version
a("second version");
b(); // second version
If you don't need any inner variables from a inside b, there is no reason to nest the functions though, in that case you should just have two independent functions:
var a = function() { alert("a"); };
var b = function() { alert("b"); };
As mentioned you can simply return function b. Functions in Javascript can be passed around like this, it's a very nice feature of a garbage collected language.
But you can go even better, what if you wanted to expose more than one function.
You can just return an object with methods attached.
function A() {
let value = 0;
return {
inc: () => ++ value,
dec: () => -- value,
show: () => console.log(value)
}
}
const a1 = A();
a1.inc(); a1.inc(); a1.show();
const b1 = A();
b1.inc(); b1.dec(); b1.dec(); b1.show();
Now the above looks very similar to what's called a class but it's not. One disadvantage to this is if you wanted to create thousands of instances, a class would be better as that can put it's methods on the prototype. But saying that, as has been found using React Hooks it's not really that bad then.
One big advantage of the above, is you don't have to get into the muddy world of this context of instances.
For completeness here is a class version.
class A {
value = 0;
inc() { ++ this.value; }
dec() { -- this.value; }
show() { console.log(this.value) }
};
const a1 = new A();
a1.inc(); a1.inc(); a1.show();
const b1 = new A();
b1.inc(); b1.dec(); b1.dec(); b1.show();
It was also said a simple solution is to make a and b both global, but the more you avoid the global the better, so if a and b have some common intent, using closures or even a class would be better.
or if you would need object approch
`var a = function() {
print("a");
this.b = function() {
print("b");
}
return this
}
a().b()`
All the other answer's are great enough, but just in case you may like this approach of directly calling inner function without returning that function.
You can simply wrap your inner function i.e b in your case, as a self invoking function like this,
var a = function() {
alert("a");
var b = (function() {
alert("b");
})()
}
Ref

Javascript class inheritance, not a function

can someone explain to me what I do wrong ?
I want to have a base Object (class) with standard functions and with B i want to overwrite standard functionality to be more specific, so i could change class B with C and have the same functions but underlying other code.
purpose of this all is that I need specific renderers if B or C does not have that function A should provide standard functionality.
in C# you have function overwrite stuff but i cant seem to figure out how it works in javascript.
thanks in advance.
var A = function () {
}
A.prototype = {
sup: function() {
console.log("sup");
},
doSome: function () {
console.log("doSomeA");
}
}
var B = function () {
A.call(this);
}
B.prototype = {
doSome: function () {
console.log("doSomeB");
}
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
var a1 = new B();
a1.doSome();
a1.sup(); // Not a function.
a1.sup(); // Not a function.
You're overwriting your prototype:
B.prototype = { ... }
B.prototype = Object.create(A.prototype);
That's exactly like overwriting any other variable - the latest applies.
And I learned this is the reliable pattern for inheritance:
function B() {
// Call super constructor
A.call(this);
}
// Clone inital properties and methods
B.prototype = Object.create(A.prototype);
// Extend the prototype
B.prototype.foo = "bar"

Is it possible to modify a function itself when its property function is called?

Basically I want to do this:
someFunction() // do something
someFunction.somePropertyFunction()
someFunction() // Now someFunction is modified; it should now exhibit a different behaviour
Is this possible?
EDIT:
I'm not looking for what #Kolink was suggesting. Basically I want to augment a function's functionality by calling one of it's property function.
Specifically, I need to: 1. have access to the original function inside my property function (which is entirely doable using this), and 2. bind a new function to the original function's name (which I'm not sure if it's possible).
Just to be clear, I don't have access to the internal definition of the function that I want to augment. I want to attach a function to Function.prototype (so that it will be available as a property of the function that I want to augment), and then I will call func.augmentThis(), and then func should be augmented. But I'm not sure how, hence the question :P
Easily. Here's an example:
var derp = 123;
someFunction = function() {alert(derp);};
someFunction.somePropertyFunction = function() {derp = 456;};
someFunction(); // alerts 123
someFunction.somePropertyFunction();
someFunction(); // alerts 456
Okay, that's an oversimplified example, but yeah, it's entirely possible.
If your question is whether a function attached as a property to another function has a way to access the function to which it is attached, the answer is no. After all, the same function could be attached to any number of functions of objects.
So one alternative is to explicitly refer to the "mother" function within the function that is attached to it and intended to change its behavior:
function f (n) { alert (n + f.offset); }
f.offset = 0;
f.change_offset = function (i) { f.offset = i; };
f (1); //1
f.change_offset (100);
f (1); //101
Here, f is hard-wired into the definition of change_offset. If this bothers you, or you want something slightly more general, write a little routine to set a function as a property on another function, while binding its this to the function being attached to:
function set_func_as_func_prop ( propname, func_to_set, func_to_set_on ) {
func_to_set_on[propname] = func_to_set.bind(func_to_set_on);
}
Now you can write the function more generally
function change_offset (i) {
this.offset = i;
}
and set it on f or any other function.
set_func_as_func_prop ("change_offset", change_offset, f);
set_func_as_func_prop ("change_offset", change_offset, g);
Sort of:
function someFunction() {
return realFunction.apply(this, arguments);
}
function someFunctionA(name) {
return 'Hello, ' + name + '!';
}
function someFunctionB(name) {
return 'Goodbye, ' + name + '...';
}
var realFunction = someFunctionA;
someFunction.somePropertyFunction = function () {
realFunction = someFunctionB;
};
Sure it's possible. It's not recommended, but it's possible. For example:
function a() {
alert("a");
}
function b() {
alert("b");
}
function c() {
return c.f.apply(this, arguments);
}
c.f = a;
c.toggle = function () {
c.f = c.f === a ? b : a;
};
Now let's test it:
c(); // alerts "a"
c.toggle();
c(); // alerts "b"
See the demo: http://jsfiddle.net/LwKM3/
I want to attach a function to Function.prototype. Then I need to bind a new function to the original function's name (which I'm not sure if it's possible).
That indeed is impossible, you don't know what refers to the function. And you cannot change the internal representation of a function, which is immutable.
The only thing you can do is to create a new function and return that, to let the caller of your method use it somehow - specifically assigning it to the original variable:
somefunction = somefunction.augmentSomehow();
Your method for that will look like this:
Function.prototype.augmentSomehow = function() {
var origFn = this;
return function() {
// in here, do something special
// which might include invoking origFn() in a different way
};
};
Not sure if this helps, but I would implement described problem in following way:
// defined by somebody else - unknown to developer
var someFunction = function() {
alert("this is initial behavior");
}
someFunction(); // returns "this is initial behavior"
// defines parent object on which someFunction() is called
var parentObject = this; // returns window object (as called direclty in the
// browser)
// if you are calling someFunction from some object (object.someFunction())
// it would be:
// var parentObject = object;
// augumentThis definition
someFunction.augumentThis = function() {
var newFunction = function() {
alert("this is changed behavior");
};
parentObject.someFunction.somePropertyFunction = function() {
parentObject.someFunction = newFunction;
parentObject.someFunction();
};
};
someFunction.augumentThis(); // change function behavior
someFunction(); // "this is initial behavior"
someFunction.somePropertyFunction(); // "this is changed behavior"
someFunction(); // "this is changed behavior"

Javascript Prototype Oriented Programming doubts

I want to do the following in Javascript
function A(){
this.B = function() { ... };
this.C = function() { <<I need to call B() here>> } ;
};
I have read the following way of method overloading, but I want to know whether professional programmers would do it this way. I.e. if you would only do this as an exercise or experiment or would actually do this in production code.
function foo(a, b, opts) {
};
foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});
Just call B() from inside C();
function A(){
B = function() {
// Do something here
}
C = function() { B(); }
};
Or, if you just want to create an alias
function A(){
B = function() {
// Do something here
}
C = B
};
The clean way would be :
var A = function() { };
A.prototype.B = function() { };
A.prototype.C = function() { this.B(); };
The prototype is just a static set of properties that is cloned inside every new instance you create.
The difference between what you're doing and this is that in your case, methods are created and added when you are in the "constructor" of the object, while with this method they already are properties of the object before you enter its "constructor", and are only parsed once (when you add them to the prototype) instead of being parsed everytime you create a new instance, which is faster.
I think, correct me if i'm wrong.
var A = function() {
// this scope is what i mean by "constructor".
};

Returning a self executing Function

Say I want to do this:
function z(){return function(){a = 4}
}
function b(){
var a;
c = z();
c();
}
I want to skip the c(); But instead I want to execute the returned function immediatly upon return in the caller scope so I can work with it.
In this example a should get the value 4.
Is there a way?
cheers
You should be able to execute the return function immediately with
z()();
No, that is impossible (without using tricks like eval). You cannot change the scope of the function returned by z.
Your example could be simpler without the closure, what you are asking for is just
function c() {
a = 4;
}
function b() {
var a;
c(); // should change variable a
return a;
}
b(); // is expected to return 4, but does not
You can't alter the scopes of functions, or pass the scope objects (like pointers to the variables). Yet, you can pass an object whose properties will be altered by the function:
function z(obj) {
return function() {
obj.a = 4;
};
}
function b() {
var o = {};
z(o)(); // as mike and others said, this is the same as yours
// - you don't need the c variable
return o.a;
}
b(); // returns 4 now
escaparello did a similar thing, only he did use the object as the thisValue which he did pass to the anonymous function, not to z. I think mine is easier to understand, and makes a better use of the z closure.
Seems very strange, but you want to do something like this?
function z(){
return function() {
this.a = 4;
return this;
}
}
function b(){
var obj = { a : 0 };
var c = z().apply(obj);
console.log(c.a);
}
b();
Try this
function z(){
return function(){
return 4;
}
}
function b(){
var a;
a = z()();
}

Categories

Resources