I am trying to call a function from outside which is defined with in a window object, but it throws an error.
window.vcm = (function() {
"use strict";
function red(){
alert('red');
}
});
vcm.red();//Error at this line...
I am new to OOPS in javascript. Can somebody tell me how to call this function here.
The value that is vcm does not have a red property.
Perhaps you mean this instead, wherein vcm is an object that has a property red that is function you can call:
window.vcm = {
red: function(){
"use strict";
alert('red');
}
};
It's also a possibility (albeit not somewhat you 'd see in practice) for vcm itself to be a function and for it to have a red property that is a function:
window.vcm = (function() {
"use strict";
var vcm = function() { alert("vcm"); }
vcm.red = function() { alert('vcm.red'); };
return vcm;
})();
vcm(); // "vcm"
vcm.red(); // "vcm.red"
There are two approaches.
Approach 1 :
window.vcm = {
red: function (){
"use strict";
alert('red');
}
};
vcm.red();
Approach 2 :
window.vcm = (function() {
"use strict";
this.red = function(){
alert('red');
}
});
var x = new vcm();
x.red();
red only exist inside the function you assigned to window.vcm and also only when the function is executed. Furthermore, functions don't have a property red.
Consider this simpler example:
function foo() {
function bar() {}
}
bar(); // will throw an error
Calling bar will throw an error because bar is not defined in the scope where it is called.
It seems you want to assign an object to window.vcm, which has a property red:
window.vcm = {
red: function (){
"use strict";
alert('red');
}
};
Here I am using an object literal to create an object with the property red.
More information:
MDN - Working with objects
Related
I am trying to understand some prototypical concepts of JavaScript which I don't use quite often. Here I have two same methods one for Array another for Function. One works, another not. Could you please explain what is the difference here?
var arr = ['test'];
var string = 'test';
Array.prototype.print = function(){
console.log(this);
}
Function.prototype.print = function () {
console.log(this);
}
arr.print(); // logs the arr with value 'test'
string.print(); //logs string.print is not a function
You are 'extending' the Function prototype but calling the print function on a String.
Change your code to:
String.prototype.print = function () {
console.log(this);
}
And it'll work.
The error says the problem in your code, that you are not defined the print function on String prototype instead you did on Function which you are not using at all.
String.prototype.print = function () {
//^^^^^--
console.log(this);
}
var arr = ['test'];
var string = 'test';
Array.prototype.print = function() {
console.log(this);
}
String.prototype.print = function() {
console.log(this);
}
arr.print(); // logs the arr with value 'test'
string.print(); //logs string.print is not a function
The first one works because you did it right. You added print function to Array.
The second one doesn't work because you did it wrong. You need to add print function to String:
String.prototype.print = function () {
console.log(this);
}
string inherit String, you can add print method to String prototype like this:
String.prototype.print = function () {
console.log(this);
}
[Array,Function,String,Object].forEach(n=>n.prototype.print=function(){
console.log(this);
});
A shortform...
If you are trying to extend a function prototype and accessing the String prototype. You are misunderstanding the prototype inheritance concept
var arr = ['test'];
var string = 'test';
var someMethod = function(){ /* some code */ };
Array.prototype.print = function(){
console.log(this);
}
String.prototype.print = function () {
console.log(this);
}
//Extending the prototype of Function
Function.prototype.print = function () {
console.log(this);
}
arr.print(); // logs the arr with value 'test'
string.print(); //logs string.print is not a function
someMethod.print(); // this will trigger the print method
// extended in Function Prototype.
Update
Very interesting point I realised due this post in Javascript. It is
you can treat Function prototype as other prototoypes. Imagine you are
extending the functions of a function itself ( seems like one of a
kind inception ). So there are interesting methods like call, apply ,
bind. So we can extend the functionality of even a function. Correct me if I am wrong, Unlike
in any other language I can think of, where extending function seems
to be impossible. Given that we are not given privilege to touch the
source code of that language. Very powerful feature in JS.
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"
Can someone tell me what object this.onSubmit is referring to in the following code?
(function () {
var _d = vjo.dsf.EventDispatcher;
var _r = vjo.Registry;
function $1(p0) {
return function (event) {
return this.onSubmit(p0, event);
};
};
})();
I apologise if there is not enough context attached to this example.
In JavaScript, the value of this is dynamically set. So to know its value, you need to know how the function is being called/used.
So the generic answer would be that this is referring to whatever was set as the this value of the execution context.
Whatever object is being bound when the function is run.
Example:
(function() {
....
function $1(p0) {
return function (event) {
return this.onSubmit(p0, event);
};
};
var testObj = {
foo: 'bar',
onSubmit: function(x,y) { console.log(x,y); }
};
var func = $1('moep');
func.call(testObj, 'hrhr'); // logs >> moep, hrhr
Here it will be the window object. You can confirm this by adding console.log(this) on the line before.
I know how to access the below member function when it's written like this:
var blady_blah=
{
some_member_function: function ()
{
}
}
I access it from outside doing blady_blah.some_member_function()
But how do I access the member function when it's written like this:
(function() {
some_member_function: function ()
{
}
})();
Braces, { }, are used to define both object literals and function bodies. The difference is:
var name = {}; // Object literal
Which you may also see written as
var name = {
};
That's just the same but with some space in between so it's still an object literal, and unfortunately it looks very similar to:
var name = function () { // Function body
};
An object can have members:
var name = {
member: "string"
};
Whereas a function cannot; a function has statements:
var name = function () {
do_something();
var result = do_something_else();
};
You can't write
var name = function () {
member: "string"
};
Because you've mixed the two uses of { } together.
A variable can be defined within a function, but it can't be seen outside the function - it's within the function scope:
var name = function () {
var something_useful = string;
};
The second example is a closure (it just happens to have a syntax error inside). Minus the bad syntax, your self-evaluating anonymous function looks like this:
(function() {
})();
If you'd like, you can define functions inside this that will be invisible to the outside world. This is useful if you're interested in maintaining a clean global namespace, for example with library code.
(function() {
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
})();
Of course, if you'd like to call any of these functions from the outside world, you're out of luck. Or are you? Actually, there's another way to define a function:
var foo = function() {
}
That's exactly the same as writing:
function foo() {
}
...Except that when written in the second style, you can actually omit the var keyword and create a global variable! Bringing it all together:
(function() {
publicData = "stuff accessible from outside anonymous function";
var privateData = "stuff that stays inside anonymous function";
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
usefulFunctionExport = function() {
utilityFunctionFoo();
utilityFunctionBar();
}
})();
usefulFunctionExport();
You can't access it after the function it's in terminates. It's a local variable that goes out of scope when its parent function ends.
You should make the main function be a constructor so that it returns a new instance of a class (you could name it Blahdy_blah) with the member function as one of its properties.
Look up constructors, their return values, and accessing member variables.
If you want to execute the function you need to return an object that exposes the function.
var LIB = (function() {
var fn = {
member_function : function(){}
};
return fn;
})();
and to call
LIB.member_function();
(function() {
blady_blah.some_member_function();
})();
If you need to add stuff into it you would write it like this.
(function() {
blady_blah.some_member_function(function(){
// Do stuff...
});
})();
I have the following function
var myInstance = (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
what's the difference if I add a new to the function. From firebug, it seems two objects are the same. And as I understand, both should enforce the singleton pattern.
var myInstance = new (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
While the end result seems identical, how it got there and what it executed in is different.
The first version executes the anonymous function with this being in the context of the window object. The second version executes the anonymous function, but this is in the context of a new empty object.
In the end, they both return another object(your Singleton). It's just a slight difference in execution context.
To test this out, but an alert(this); right before the declaration of the privateVar variable.
#Tom Squires: That's not necessarily true and is poor practice not to declare your variables. A script with the "use strict"; directive does cause the JS engine to complain (assuming that the engine supports "use strict";