declare function properties inside - javascript

I know that we can set a function property as below
function f(){}
f['a']=1;//setting function property from outside
alert(f.a)//alert 1
But is it possible to set a property of function as below or is there any other similar way of declaring properties inside a function,rather than from outside?
function f() {
a: 1
}
alert(f.a); //get 1 as output
EDIT:
Looking for some way which does not use any object creation from the function constructor or use prototypes

No, there is not. Inside the function goes only the body, i.e. the code that is executed when the function is called. A function literal / declaration is not an object literal, even if both use curly braces.
If you're looking for a more declarative way than assignment to put static properties on a function, use some kind of extend functionality:
var f = Object.assign(function f() {}, {
a: 1
});
(all of _.extend, $.extend, Object.assign will work for this purpose - otherwise just use f.a =)

The only way this can be done is if the function is invoked with the new keyword:
var f = function() {
this.a = 4;
}
var test = new f();
alert(test.a); // 4
I've published some more tests on this jsfiddle:
http://jsfiddle.net/j4svr90x/2/

Related

What is an instantiation of a constructor function?

function F () {
var color = "red";
this.fun = function f () {
console.log(color);
};
};
var i = new F();
i.fun();
I'm a bit confused to what new F() / new F is.
Here's what I know about the new keyword:
i) It creates {} either in constructor function or somehow related to constructor function.
ii) this in constructor function references this empty object and
iii) makes constructor function return this object unless you specify constructor function to return something else instead. So my first thought is that in the code above, new F() returns { fun: [Function: f] }.
When you console.log(new F()); what comes is slightly different:
F { fun: [Function: f] }
It look like an object, however this behaviour makes it apparent it's more complicated:
i.fun() returns "red". A method of this object is able to access
variables inside the constructor function that made it. If it were
purely a basic object it wouldn't be able to do that.
Right now, my only idea is that new F() is an object that is able to see the scope of the constructor function that made it.
Disclaimer: I am aware of what closures are and I know how function f could see color in F. I thought what was going on was a copy of function f was being added as a value in a brand new object which is assigned to i. Therefore, how does function f, in this brand new object, see the color variable in a completely separate function, F?
For example:
function F (v) {
var v = v;
var color = "red";
this.fun = function f () {
console.log(color);
};
};
var i = {fun: function f() {console.log(color)}};
i.fun() //returns 'color' is not defined.
There's another step when new F() is used:
iv) It sets the prototype of the object to an object like {contructor: F}.
This is why the object is logged as F { fun: [Function f] } instead of just {fun: [Function f] }. Objects with a prototype other than the standard Object prototype are shown with the name of the constructor function as a prefix.
As far as access to the variable color is concerned, it's no different from any other nested function, is a closure that captures variables from the containing environment. It's no different from writing an ordinary function like this:
function F() {
var color = 'red';
let fun = function f() {
console.log(color);
};
return {
fun: fun
}
}
let i = F()
i.fun()
Using new has no effect on the way variables are captured in a closure.
When you assign this.fun = function f ... it just stores the closure in the fun property. JavaScript never makes copies of objects, functions, etc. unless you do so explicitly -- assignments always assign references to the object.
You can even copy the closure to another object, it will still retain its access to the original environment. Since the function doesn't refererence this, it doesn't care how it's called.
var foo = {};
foo.fun2 = i.fun;
foo.fun2() // will log "red"
When you call new F() the following steps are performed (from MDN):
Creates a blank, plain JavaScript object;
Links (sets the constructor of) this object to another object;
Passes the newly created object from Step 1 as the this context;
Returns this if the function doesn't return an object.
So when executing the code var i = new F(); you have the following steps:
Create a new object. {} The prototype of this new object is set to F.prototype.
Set the constructor of this object to the function F. This changes the display to F {}
Bind the function F to the object and execute F. That means this within the body of F() refers to the object F {} we are carrying from Step 2.
The new keyword causes the expression to return that object if the return type of F() is undefined (which it is, as there's no value returned).
During step 3, F is executed, with this as an empty object F {}.
The first line var color = "red"; is executed. It defines and assigns a variable, nothing special.
The second line is executed. this.fun = function f() { ... }; The function must be evaluated first before the assignment.
During the evaluation of the function, a closure is created around all variables in scope. A specific reference to this instance's declaration of the variable color is captured in scope. The function f, even when referenced outside of F, carries this closure with it. Anywhere it is executed, it carries the same closure which was captured during evaluation of this line. This closure has the variable color, so no matter where it's passed around and executed, it still knows what the variable color is. This is how closures work.
Hopefully that last paragraph clears up why this works the way it does for you.
To specifically address your last example:
var i = {fun: function f() {console.log(color)}};
The function f() in this context was not evaluated with color in its scope. The closure captured during the evaluation of this line of code does not include color, because color is a local variable only defined in the scope of a current execution of the function F().
Javascript has constructor functions, you can do:
class F {
constructor() { this.color = "red"; }
fun() {
console.log(this.color);
}
};
Then you have to call that with new F();
When not calling a constructor specifically you can call any function with new, which has the effect of making the this function inside the function apply to the function itself. You can call it with apply and set this to whatever you want.
For that reason a common convention in JS was to name functions that expected to be called with new with CapitalCase, and those that didn't with camelCase. So you could just call fooBar() however you wanted, but would expect bugs if you had new FooBar() without the new.
Therefore, how does function f, in this brand new object, see the color variable in a completely separate function, F?
It doesn't, f is inside F and sees the var color declared across that scope. Functions inherit the scope of anything they're declared inside. f can see the rest of F, but F can't see the closure inside f.
You are able to access color (value: red) beacuse of closure as you mentioned.
Since color variable was available at the time of function f / fun declaration. It saves it value as a closure variable.
If you want separate copies of color variable as well. Define it on this like following:
function F (color) {
this.color = color;
this.fun = function f () {
console.log(this.color);
};
};
var i1 = new F("green");
var i2 = new F("red");
i1.fun(); // green
i2.fun(); // red
In your second code snippet you are getting color as undefined because there is no color variable declared in same scope as function f (inside i object) or globally.

Verifying my understanding of the scope chain

(Question 1)
In Flanagan's JS Definitive Guide, he defines the Function method bind() in case it's not available (wasn't available n ECMAScript 3).
It looks like this:
function bind(f, o) {
if (f.bind) return f.bind(o); // Use the bind method, if there is one
else return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
He illustrates the use of it with an example (which I have modified to change the 3rd line from f.bind(o)):
function f(y) { return this.x + y; } // This function needs to be bound
var o = { x : 1 }; // An object we'll bind to
var g = bind(f, o); // Calling g(x) invokes o.f(x)
g(2) // => 3
When I first saw this, I thought "Wouldn't arguments refer to the arguments variable within the bind function we're defining? But we want the arguments property of the function we eventually apply it to, like g in the example above..."
I verified that his example did indeed work and surmised that the line return f.apply(o, arguments) isn't evaluated until var g = bind(f, o) up above. That is, I thought, when you return a function, are you just returning the source code for that function, no? Until its evaluated? So I tested this theory by trying out a slightly different version of bind:
function mybind2(f, o) {
var arguments = 6;
return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
If it's simply returning tbe unevaluated function source, there's no way that it stores arguments = 6 when later evaluated, right? And after checking, I still got g(2) => 3. But then I realized -- if it's just returning unevaluated code, how is the o in return f.apply(o, arguments) getting passed?
So I decided that what must be happening is this:
The o and the arguments variables (even when arguments equals 6) are getting passed on to the function. It's just that when the function g is eventually called, the arguments variable is redefined by the interpreter to be the arguments of g (in g(2)) and hence the original value of arguments that I tried to pass on was replaced. But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
(Question 2) Earlier on the same page, he defines the following function which makes use the apply method to trace a function for debugging:
function trace(o, m) {
var original = o[m]; // Remember original method in the closure.
o[m] = function() { // Now define the new method.
console.log(new Date(), "Entering:", m); // Log message.
var result = original.apply(this, arguments); // Invoke original.
console.log(new Date(), "Exiting:", m); // Log message.
return result; // Return result.
};
}
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
Question 1
For your first question, let's simplify the example so it's clear what being done:
function bind(func, thisArg) {
return function () {
return func.apply(thisArg, arguments);
};
}
What happens here is that a closure is created that allows the access of the original function and the value of this that is passed. The anonymous function returned will keep the original function in its scope, which ends up being like the following:
var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
About your issue with arguments, that variable is implicitly defined in the scope of all functions created, so therefore the inner arguments will shadow the outer arguments, making it work as expected.
Question 2
Your problem is to your misunderstanding of the late binding of this -- this is one of the more confusing things about JavaScript to people used to more object-oriented languages that also have their own this keyword. The value of this is only set when it is called, and where it is called defines the value of this when it is called. It is simply the value of the parent object from where it is at the time the function is called, with the exception of cases where the this value is overridden.
For example, see this:
function a() {return this;};
a(); // global object;
var b = {};
b.a = a;
b.a(); // object b
If this was set when the function was defined, calling b.a would result in the global object, not the b object. Let's also simplify what happens with the second function given:
function trace(obj, property) {
var method = obj[property]; // Remember original method in the closure.
obj[property] = function () { // Now define the new method.
console.log(1); // Log message.
// Invoke original method and return its result
return original.apply(this, arguments);
};
}
What happens in this case is that the original method is stored in a closure. Assigning to the object that the method was originally in does not overwrite the method object. Just like a normal method assignment, the principles of the this value still work the same -- it will return the parent object, not the function that you've defined. If you do a simple assignment:
var obj = {};
obj.foo = function () { return this; };
obj.foo(); // obj
It does what was expected, returns the parent object at the time of calling. Placing your code in a nested function makes no difference in this regard.
Some good resources
If you'd like to learn more about writing code in JavaScript, I'd highly recommend taking a look at Fully Understanding the this Keyword by Cody Lindley -- it goes into much more detail about how the this keyword behaves in different contexts and the things you can do with it.
But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
No. this and arguments are just special variables which are implicitly set when a function is executed. They don't adhere to normal "closure rules". The function definition itself is still evaluated immediately and bind returns a function object.
You can easily verify this with:
var g = bind(f, o);
console.log(typeof g);
Here is a simpler example which doesn't involve higher order functions:
var arguments = 42;
function foo() {
console.log(arguments);
}
foo(1, 2);
I think you see that the definition of foo is evaluated like you'd expect. Yet, console.log(arguments) logs [1, 2] and not 42.
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
this never refers to the function itself (unless you explicitly set it so). The value of this is completely determined by how the function is called. That's why this is often called "the context". The MDN documentation provides extensive information about this.
Reading material:
MDN - this
MDN - arguments

Javascript: why "this" inside the private function refers to the global scope?

Consider the following code:
function A() {}
A.prototype.go = function() {
console.log(this); //A { go=function()}
var f = function() {
console.log(this); //Window
};
f();
}
var a = new A();
a.go();
Why does 'this' inside function 'f' refers to the global scope? Why it is not the scope of function 'A' ?
JavaScript has a different concept of what the special name this refers to
than most other programming languages do. There are exactly five different
ways in which the value of this can be bound in the language.
The Global Scope
this;
When using this in global scope, it will simply refer to the global object.
Calling a Function
foo();
Here, this will again refer to the global object.
ES5 Note: In strict mode, the global case no longer exists.
this will instead have the value of undefined in that case.
Calling a Method
test.foo();
In this example, this will refer to test.
Calling a Constructor
new foo();
A function call that is preceded by the new keyword acts as
a constructor. Inside the function, this will refer
to a newly created Object.
Explicit Setting of this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // array will expand to the below
foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3
When using the call or apply methods of Function.prototype, the value of
this inside the called function gets explicitly set to the first argument
of the corresponding function call.
As a result, in the above example the method case does not apply, and this
inside of foo will be set to bar.
Note: this cannot be used to refer to the object inside of an Object
literal. So var obj = {me: this} will not result in me referring to
obj, since this only gets bound by one of the five listed cases.
Common Pitfalls
While most of these cases make sense, the first one is to be considered another
mis-design of the language because it never has any practical use.
Foo.method = function() {
function test() {
// this is set to the global object
}
test();
}
A common misconception is that this inside of test refers to Foo; while in
fact, it does not.
In order to gain access to Foo from within test, it is necessary to create a
local variable inside of method which refers to Foo.
Foo.method = function() {
var that = this;
function test() {
// Use that instead of this here
}
test();
}
that is just a normal variable name, but it is commonly used for the reference to an
outer this. In combination with closures, it can also
be used to pass this values around.
Assigning Methods
Another thing that does not work in JavaScript is function aliasing, which is
assigning a method to a variable.
var test = someObject.methodTest;
test();
Due to the first case, test now acts like a plain function call; therefore,
this inside it will no longer refer to someObject.
While the late binding of this might seem like a bad idea at first, in
fact, it is what makes prototypal inheritance work.
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
When method gets called on a instance of Bar, this will now refer to that
very instance.
Disclaimer: Shamelessy stolen from my own resources at http://bonsaiden.github.com/JavaScript-Garden/#function.this
The reason why is you are invoking f as a function and not a method. When invoked as a function this is set to window during the execution of the target
// Method invocation. Invoking a member (go) of an object (a). Hence
// inside "go" this === a
a.go();
// Function invocation. Invoking a function directly and not as a member
// of an object. Hence inside "f" this === window
f();
// Function invocation.
var example = a.go;
example();
The scope of all functions is window.
To circumvent that, you can do this:
function A() {}
A.prototype.go = function() {
var self = this;
console.log(self); //A { go=function()}
var f = function() {
console.log(self); //A { go=function()}
};
f();
}
Because function f() is not called without any object reference. Try,
f.apply(this);

Please explan this javascript function definition and their best use (Module Pattern)

What type of function is the following and which is their best use?
var f = function (){
var a = 0;
return {
f1 : function(){
},
f2 : function(param){
}
};
}();
I tried to convert it to:
var f = {
a : 0,
f1: function (){
},
f2: function (param){
}
}
But seems does not works the same way.
It's just a plain old function that is invoked immediately, and returns an object which is then referenced by f.
The functions referenced by object returned retain their ability to reference the a variable.
No code outside that immediately invoked function can reference a so it enjoys some protection since you control exactly what happens to a via the functions you exported.
This pattern is sometimes called a module pattern.
Regarding your updated question, it doesn't work the same because a is now a publicly available property of the object.
For the functions to reference it, they'll either do:
f.a;
or if the function will be called from the f object, they can do:
this.a;
Like this:
var f = {
a : 0,
f1: function (){
alert( this.a );
},
f2: function (param){
this.a = param;
}
}
f.f2( 123 );
f.f1(); // alerts 123
But the key thing is that a is publicly available. Any code that has access to f can access f.a and therefore make changes to it without using your f1 and f2 functions.
That's the beauty of the first code. You get to control exactly what happens to a.
Basically that creates a "class" - JS doesn't have classes so a class is basically a function such as your function f.
The interesting thing about the code you posted is that it creates a private variable a and two public functions f1 and f2. They are public because the constructor - the outer function - returns them.
This is a common pattern for organising and encapsulating JS code.
You can read more about it here
It's a simple function to create and return an object. It's immediately executed, and its result is saved to your variable f
It first declares a local (or private) variable a, visible only withing the scope of the function. Then it constructs an object which has members f1 and f2, both of which are functions. Since this return object is declared within the same scope that a is declared, both f1 and f2 will have access to a.
Your conversion simply creates a single object. Where before you had a function that would create endless objects, you now have a single object, and no more. I'm not sure exactly why it doesn't work, but one major difference is that a is now visible to the world, where before it was private to the return object.

Can someone explain this OOP javascript structure

Can someone explain this OOP javascript structure?
I realize it is how you create 'objects' in javascript, just need some explanation on the notation and what it means:
var vote = function(){
return {
P1: function() {
alert('P1');
},
P2: function() {
alert('P2');
}
};
}();
vote.P1();
vote.P2();
Why are the public methods in the return call? How is this possible? Separated by commas?
Why does the end of the 'object' have to be (); ?
Naming convention for internal methods and public methods?
Are public properties and methods the same structure? What is the difference?
var vote = function(){
var privateMember = 3; // lets define a private member, this will only be available inside the function scope, so we can't do "vote.privateMember" because we're not returning it below
// It's returning an object, {}
// these are considered public because they are returned by the function, making them available outside the function scope using the "dot" operator, "vote.P1()"
return {
// first value of the object is a function
// so we can call this like "vote.P1()"
// we're calling a privateMember in here
P1: function() {
alert('P1');
alert(privateMember);
},
// second value of the object is a function
// so we can call this like "vote.P2()"
P2: function() {
alert('P2');
}
};
}(); // () means it will execute the function, so "vote" will store the return value of this function, it's a shorthand for `var vote = function(){}; vote = vote();
Naming convention for private methods is usually to put an underscore before the method/property name _privateMethod: function(){}.
It's returning the object/hash. Notice that right after the return is a { which is the beginning of the object/hash.
to run the anonymous function that returns the object.
I don't know what you mean.
Yes they are the same. A property can be a function because javascript has first class functions.
This code is contrived so it's hard to say anything useful about it. I'm not sure what the authors intent was. It looks like he may have been aiming to create a class like thing, as opposed to the way javascript does prototype based OO. This code could have just as easily been written.
var vote = {
P1: function() {
alert('P1');
},
P2: function() {
alert('P2');
}
};
Three important concepts: anonymous functions, object literals, closure.
Anonymous Functions
You can declare and execute a function without assigning it to a variable. In you example, foo isn't a function, it's the result of calling:
var item = function(){ /*function code here*/ }**()**; <- Because the function is being executed, item is the object the function returned, not the function.
Object Literals
Say you did this: var a = new Object(); a.foo = 'bar';
Object literal notation would look like this: var a = {foo: 'bar'};
In you example, your anonymous function is returning a new object with two functions, P1 and P2. It's just a different notation for specifying objects.
Closure
When a function returns an object, that object retains access to the functions scope - this is called a closure. So, if you do this:
var a = function(){
var _pvt = 'foo';
return {
aFunc: function(){alert(_pvt);}
};
}();
a.aFunc();
_pvt's scope is the anonymous function. This function returns a new object with one method (aFunc). The anonymous function's scope is available to this object through closure, so when a.aFunc() is called, _pvt will be available.
Best place to learn about this is the Douglas Crockford videos on YUI Theater: http://video.yahoo.com/watch/111585/1027823
This is JSON (javascript object notations). It's similar to dictionary format in python.
Arrays can be defined inline using
[1,2,3,4,5]
and objects can be defined inline using
{ field1: value1, field2: value2, field3: value3 }
A function can be defined inline too,
var a = function() { .... } //a is a function
The () after the function is used to call the function immediately after its definition! Because the function is defined inline, it's like saying:
x = function() { ... }
y = x();
but condensed as:
y = function(){...} ();
As far as I know, there's no public or private, it's all public, and functions are no different from variables, it's just that their type is a function.

Categories

Resources