What the difference between those two? - javascript

Is there any difference between these two:
var test1 = function () {
this.method1 = function() {}
}
and
var test2 = function() {};
test2.method1 = function() {};

The first snippet takes this object, whatever it is, and assigns a function to its slot (field) named method1. this can represent different objects, depending upon how test1 is called:
when called as a standalone function -- test1() -- this will be window
when called as a constructor -- new test1() -- this refers to the object being created
when called via call or apply -- test1.apply(someObject) -- this refers to the argument
The second snippet takes the object test2 and assigns a function to its slot named method1.

The first way is a constructor that creates more objects and needs to have the new keyword:
var mytest1 = new test1();
mytest1.method1();
The second way is ready to use right away:
test2.method1();

Assuming syntax was correct, the first is a constructor that gives all test1 objects created via new test1() a method called method1. The second just adds a function to the constructor object. In javascript, functions are objects which can have properties (including methods).

The first version actually creates a method available to all objects instantiated like so:
var o = new test1();
o.test1();
The second simply attached a function as an attribute on the test2 function. If you're familiar with other class-based OO languages, this works kinda like a static method. You will not have access to the this pointer in the second example.

The first one:
var test1 = function () {
this.method1 = function() {}
}
Defines the function "test1". Once (and only when) "test1" is called, "this.method1" will be defined as a function, that does nothing.
The second:
var test2 = function() {};
test2.method1 = function() {};
Create the function "test2" and at the same time defines the function "test2.method1", without the need to invoke the first function.

The first one sets the method1 property on whatever invokes test1().
The second one defines an empty function and sets the method1 property on test2

Related

this context bug in javascript - why doesn't this trigger a bug?

I thought this was suppose to trigger a bug when calling a function from within a function using the keyword this. Running Chrome 37.0
S = function () {
this.x = "test";
this.test1 = function () {
console.log("test1");
this.test2();
};
this.test2 = function () {
console.log(this); // output is s object, thought 'this' suppose to be global?
console.log("test2");
};
};
s = new S();
s.test1();
Edit:
I mixed it up with this code:
s = function () {
console.log(this);
var t = function () {
console.log(this);
};
t();
};
x = new s();
Calling a function as part of an expression where you get the function reference from an object property calls the function with this set to the object you got the property from.
So your code:
s.test1();
...will call test1 setting this equal to the object referenced by s, because the call is part of an expression getting the test1 function reference from a property on the object s refers to.
Then in test1, when you do:
this.test2();
...it calls test2 setting this equal to the object referenced by this, because the call is part of an expression getting the test2 function reference from a property on the object this refers to.
Where you'd run into a problem with this not being set correctly would be if you didn't call test1 or test2 via an object property, like this:
var f = s.test1;
f();
Then, within the call to test1, this would be the global object (in loose mode) or undefined (in strict mode). The same sort of thing happens when passing a function as an argument:
foo(s.test1);
If foo calls the function its first argument relates to, we get the same thing (this = global object or undefined).
Since you're not doing that, though, that doesn't happen.
The key thing here is how the function is called, not where it's defined (inside another function or not).
More on this in How Does The this Keyword Work? here on SO, and in Mythical methods and You must remember this on my blog.

Understanding JavaScript function declaration syntax [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
After using JavaScript for a while, I came up with some questions.
The way to declare a function is:
var myFunction = function(param){//code here}
But there is also another way to declare a function which is
function myFunction(param){//some code}
What's the difference between the two methods to declare a function?
My second question is, I've understood that you can create an object from a function that's declared as:
function Person(name){this.name=name;}
And then, you can have another function declared like this:
function Speak(){console.log(this.name);}
How does the function Speak knows that it's related to the Person Object?
The first one is expression
var myFunction = function(param){//code here}
Second is declaration
function myFunction(param){//some code}
see this article
http://kangax.github.io/nfe/
When u use the word var, your'e declaring a variable realtive to where it's defined, and cannot be accesed from out wheres, and if its inside a function, it's destroyed at the end of the execution, and if you dont use it, you're defining on global ambit, and the variable still exists after the function execution.
The second thing is for programming OOP
Yo can use functions as same as it they were pure objects:
var person = {
name: null,
setName: function (name) {
this.name = name
}
}
Then you can access it's property
person.setName('john');
console.log(person.name);
in the shape of a function
function Person(name){
this.name = null;
}
var john = new Person('John');
console.log(john.name);
When you use this syntax:
function f1(){}
then f1 can be used everywhere in the current scope:
// we can call f1 even before definition of the function
f1(); // it works
function f1(){}
But, When we use this syntax:
var f1 = function(){};
then f1 is like as a pointer to an anonymous function which can be used after the point of assignment:
// we can't call it before assignment of our var
//f1(); // f1 is undefined here!
var f1 = function(){}
// we can call it here
f1(); // works
The second syntax is make more sense when you consider that every function is also an object. for example, we can have a function be a property of an object, like this:
var myObject = new Object();
myObject.say = function(x) {alert(x);};
// myObject now has a property/method named "say"
myObject.say("Hello");
About the second question: the this keyword. can you give the (outer) scope of your code which defines your Person and Speak functions? the code you wrote won't work as it is written. If you want to set proper reference for this in Speak function, you have to write something such as below:
function Person(name){ this.name=name; }
function Speak(){ alert(this.name); }
Person.prototype.DoSpeak = Speak; //here we attach DoSpeak to Speak function
var p = new Person("Saeed");
p.DoSpeak(); //this will work
Both are declaration
1) var myFunction = function(param){//code here}
This is a declaration that is assigned to 'myFunction' local variable
You can set an identifier for that function for debug or recursion purposes
var myFunction = function myFunctionIdentifier(param){ console.log(myFunctionIdentifier.toString())}
But to call this function you have to use 'myFunction ' variable
Another way to perform nested call is by using the arguments.callee that points to the function itself
var myFunction = function(param){ console.log(arguments.callee.toString())}
2) function myFunction(param){//some code}
This is a declaration that is assigned to the scope variable
in case you are in the global area it will be assign (for example in the browser) to the window object
So in fact window["myFunction"]() is valid
* About this question...
function Person(name){this.name=name;}
function Speak(){console.log(this.name);}
The reason that Speak 'knows' Person name is all about JavaScript scope.
Since both using the same scope, both functions 'speak' with the same this.
For example: if you code both functions in the global scope, this == window object thus
console.log(window['name']); will give you the name.
You don't want to code in that way .. since another function using this.name will override you existing logic.
If you will instantiate the Person entity
var person = new Person();
Then person variable will be this, this == person object
And the you can assign Speak in two or more ways:
inline:
function Person() {
...
this.Speak = function ...
}
outside the code, since person assign to (Person)this
person.Speak = function() ...
or the best way, use the prototype object:
Person.prototype.Speak = function() ...

What does "Object.call" mean?

function bb_graphics_GraphicsContext(){
Object.call(this);
this.bbdevice=null;
this.bbmatrixSp=0;
this.bbix=1.000000;
this.bbiy=0;
this.bbjx=0;
this.bbjy=1.000000;
this.bbtx=0;
this.bbty=0;
this.bbtformed=0;
this.bbmatDirty=0;
this.bbcolor_r=0;
this.bbcolor_g=0;
this.bbcolor_b=0;
this.bbalpha=0;
this.bbblend=0;
this.bbscissor_x=0;
this.bbscissor_y=0;
this.bbscissor_width=0;
this.bbscissor_height=0;
this.bbmatrixStack=new_number_array(192);
}
What does Object.call(this) mean?
Functions in JavaScript are full-fledged objects. They also, when passed as an argument to another function, don't retain their scope. So, in the following code...
var obj1 = {
property1: "blah",
method1: function () {
alert(this.property1);
// do stuff
}
};
function func1 (passedFunction) {
passedFunction();
// do other stuff
}
func1(obj1.method1);
... func1 will call obj1.method1, but it won't alert the value of obj1's property1, because all we've done is pass the function object, not its this context. That's where call and apply come in. They allow you to inject scope, tell the function what the meaning of this will be. The following example works:
var obj1 = {
property1: "blah",
method1: function () {
alert(this.property1);
// do stuff
}
};
function func1 (passedObject, passedFunction) {
passedFunction.call(passedObject);
// do other stuff
}
func1(ob1, obj1.method1);
Now, we've forced or explicitly told obj1.method1 what its context will by invoking call, and passing it the object it's to use as this.
call and apply are almost identical, except for how they handle additional arguments to the function being invoked. See these articles on MDN for more information: call, apply and Function.
All of this having been said, bb_graphics_GraphicsContext is a constructor. (Which you've probably guessed.) You invoke it by using the new keyword, var obj1 = new bb_graphics_GraphicsContext();. When it reaches line 1 of the function, it takes the this object, and calls the generic Object constructor, explicitly injecting the new object this (in the bb_graphics_GraphicsContext constructor) as the this of the Object constructor. I'd assume the writer of this function/constructor was doing this to make sure that the newly created object in bb_graphics_GraphicsContext was getting all the base methods of the base Object. But I don't know why this would be necessary, as if you call bb_graphics_GraphicsContext with the new keyword it will grab all these properties naturally.
Object.call will execute a certain function under the provided context, it can be used to call functions from one object on an other.
The mozilla dev network provides a very good explanation
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
This will do absolutely nothing except wasting resource and memory allocation.
If the Object.call(this) will have been assigned to a variable or property of the function constructor bb_graphics_GraphicsContext
this.myObject = Object.call(this)
The only thing that you get in that instance is an empty object "THAT DO NO HOLD THE PROVIDED CONTEXT"
function MyConstructor(){
this.test01 = 0;
var b = Object.call(this); // similar to b = {}; or b = new Object()
console.log(b); // log object
console.log(b.test); // log undefined
this.test = 1;
}
var myObject = new MyConstructor();
console.log(myObject, window.test01)
Although Object.call will probably do nothing as expressed here, the concept might be important. Basically, the example you will see on inheritance in the Node.js documentation is:
const util = require('util');
const EventEmitter = require('events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
The util.inherits will make a new MyStream inherit (have the same prototype as) EventEmmiter. This could be enough if we are interested in MyStream having access to the functions inherited through the EventEmmiter prototype. But what if there are variables passed on construction? What if we have:
function MyObject() {
this.code = "2nV_ahR";
}
In this case, the code variable is passed on runtime when MyObject gets instantiated. Therefore, a subclass needs to pass:
function MySubObject() {
MyObject.call(this);
}
In order to inherit the code variable. What call does accept a parameter that sets the this variable. So... when I do var o = new MySubObject(), the this inside of MySubObject refers to o, which is then passed to the call method, so that when MyObject does this.code = ... it is actually passing the code to o!
Every JavaScript function has a toString(), call() and apply().
Read more about them on this odetocode.com article

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);

Set "this" variable easily?

I have a pretty good understanding of Javascript, except that I can't figure out a nice way to set the "this" variable. Consider:
var myFunction = function(){
alert(this.foo_variable);
}
var someObj = document.body; //using body as example object
someObj.foo_variable = "hi"; //set foo_variable so it alerts
var old_fn = someObj.fn; //store old value
someObj.fn = myFunction; //bind to someObj so "this" keyword works
someObj.fn();
someObj.fn = old_fn; //restore old value
Is there a way to do this without the last 4 lines? It's rather annoying... I've tried binding an anonymous function, which I thought was beautiful and clever, but to no avail:
var myFunction = function(){
alert(this.foo_variable);
}
var someObj = document.body; //using body as example object
someObj.foo_variable = "hi"; //set foo_variable so it alerts
someObj.(function(){ fn(); })(); //fail.
Obviously, passing the variable into myFunction is an option... but that's not the point of this question.
Thanks.
There are two methods defined for all functions in JavaScript, call(), and apply(). The function syntax looks like:
call( /* object */, /* arguments... */ );
apply(/* object */, /* arguments[] */);
What these functions do is call the function they were invoked on, assigning the value of the object parameter to this.
var myFunction = function(){
alert(this.foo_variable);
}
myFunction.call( document.body );
I think you're looking for call:
myFunction.call(obj, arg1, arg2, ...);
This calls myFunction with this set to obj.
There is also the slightly different method apply, which takes the function parameters as an array:
myFunction.apply(obj, [arg1, arg2, ...]);
If you want to 'store' the this value to a function so that you can call it seamlessly later (e.g. when you don't have access to that value anymore), you can bind it (not available in all browsers though):
var bound = func.bind(someThisValue);
// ... later on, where someThisValue is not available anymore
bound(); // will call with someThisValue as 'this'
My search on how to bind this brought me here so I am posting my findings: In 'ECMAScript 2015' we can also set this lexically using arrow functions to.
See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Instead of:
function Person() {
setInterval(function growUp() {
// The callback refers to the `self` variable of which
// the value is the expected object.
this.age++;
}.bind(this), 1000);
}
We can now do:
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
Setting the this keyword in javascript.
Javascript has 3 built in methods for setting the this keyword conveniently. They are all located on the Function.prototype object so every function can use them (since every function inherits from this prototype via prototypal inheritance). These functions are the following:
Function.prototype.call(): This function takes the object which you want to use as this as a first argument. Then the remainder of the arguments are the respective arguments of the function which is called.
Function.prototype.apply(): This function takes the object which you want to use as this as a first argument. Then the second argument is an array which contains the values of the arguments of the function which is called (first element of array is first argument of the function, second argument of the array is second argument of function etc.).
Function.prototype.bind(): This function returns a new function which has a different value of this. It takes the object which you want to set as the this value as a first argument and then returns a new function object.
Difference between call/apply and bind:
call and apply are similar in the fact that they immediately call the function (with a predefined value of this)
bind is different from call and apply in the fact that this function returns a new function with a different binding of the this value.
Examples:
const thisObj = {
prop1: 1,
prop2: 2,
};
function myFunc(arg1, arg2) {
console.log(this.prop1, this.prop2);
console.log(arg1, arg2);
}
// first arg this obj, other arguments are the
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');
// first arg this obj, other argument is an array which
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);
// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);
// now we can call the function like a normal function
newMyFunc('first', 'second');

Categories

Resources