In this example below is onlaod a function or a method? I would assume this is a method as that is associated with the img object.
Can anyone clarify this?
img.onload = function () {
ctx.drawImage(img, 10, 10);
ctx.drawImage(img, 170, 90);
ctx.drawImage(img, 170, 170);
};
Many thanks,
P
A "method" in JavaScript is just a property on an object that refers to a function. From the specification:
method
function that is the value of a property
So in that sense, what you've shown is both a "method" and a "function."
In another sense, if you define "method" as "a function tied exclusively to a given object or class of objects," JavaScript doesn't really have methods at all (but keep reading). (More about that on my blog: Mythical methods.)
For instance, you could consider slice a method of Array objects, but it can be used on any other object you like (as long as that object is array-like, since otherwise slice doesn't know what to do):
var o = {
0: "zero",
1: "one",
2: "two",
length: 3,
slice: Array.prototype.slice
};
console.log(o.slice(1));
That said, some functions will fail with an error if they're called with this not referring to the kind of object they expect (for instance, Number#toString), which in some sense makes them true methods.
In any case, it's very common indeed to use the term "method" to refer to a property that refers to a function. In fact, the specification does it when talking about things like this:
// ES2015+
let obj = {
method() {
}
};
and this:
// ES2015+
class Foo {
method() {
}
}
Methods are properties that are type Function
Without formal language specific definition one should alway defer to the common usage implicit meaning.
In computer programing;
A method is a function that is a part of a class, it may or may not return a value.
A function is set of statements that returns a value.
A procedure is a set of statements that do not return a value.
But if there is a language scoped formally explicitly defined meaning one should use it.
Javascript's function and method
Javascript "ECMAScript 6" formally defines the term Function as.
...and a function is a callable object.
and Method as
A function that is associated with an object via a property is called a method.
Reference ecma-262 7.0, Ecmascript Overview
Which sucks as I have always used function and now have to emend all my documents to the correct term.
Contradiction
It also creates contradiction in regard to the lexical syntax used to describe and document javascript code.
All callable functions/methods are Function objects and have the Function.prototype. In the strict sense there are only functions when describing what a variable is referencing (or anonymously).
For example consider
var poo = function(){}; // Method window.poo, function poo.
function Foo(){ // this is a function?
var tic = function(){}; // tic is a function
this.Bar = function(){ // this is a function as well as a method
this.poo = poo; // This is a method, it is also function
}
this.Boo = function(){
this.poo = function(){ return poo}; // anon function returns the poo
// to create the method Boo.poo
}
}
Top is a function as it is a callable object. but it is also a property of the top scope window (or context top level scope), and is thus a method of window.
Thus as defined by the Javascript standard Foo, Bar, and Boo are functions and at the same time methods. This ambiguity in programing can be a problem that could lead to bugs, or worse design reviews if pedantic programmers like me are forced adhere to the design spec.
Suggested lexical usage of "method" and "function"
Personally I will opt to the following useage of the words function, and method.
All callable statement lists are functions, that is their type.
I will call them functions unless I referance the object they are a property of.
I will call them a method when I referance without ambiguity the object they are a property of.
If documenting with scope including JavaScript implementation language (usually c++) I will call internal (hidden from Javascript's context) callable code as methods or functions depending on if they return a value or not
From above code.
Foo, Bar, Boo, and poo are functions
Foo is a method of window.
Bar is Foo's method.
Bar's method poo does nothing
Boo.poo is a method.
poo is a function, that is its type.
poo is a function common to both window, Bar and Boo *
'tic' is a function
There is no method named tic.
The method Bar.poo is declared in the function Bar
The method Bar.poo is defined as an anonymous function
The method Bar.poo is a referance to a function
The method. Boo.poo is a referance to the method window.poo
*as there is ambiguity to the object that poo is a property of, refer to it as a function
The referance to the object that methods belong to can be a contextually explicitly reference.
CanvasRenderingContext2D is an object used to render to the canvas , drawImage and clearRect are 2 of its methods.
Or contextually implicitly referred
After getting the context from the canvas, the methods drawImage and fillRect can be used to overwrite all pixels.
Getters and setters are functions. They are methods of the object they are a property of but should only be called functions when referring to the declaration and defining statement list. Or as simply properties of the object. Calling them methods implies the function calling syntax name()
Anonymous functions can not be methods as they can not be accessed via a named property.
To answer the OP
onload is a property of Image. It is never a function or a method of Image
The object of type Image will have the method onload if defined, called when image has loaded. If the method onload is not defined then nothing will happen when the image has loaded.
img.onload is a method. Or onload is a method of img. True only after it has been assigned a function
drawImage is a function, that is its type.
ctx.drawImage is a method.
drawImage is ctx's method,and it is a method of CanvasRenderingContext2D
I would tend to say every function in Javascript is a method. But I'm not sure if this is justified. Please correct me if I'm wrong.
So, a method has a "this", that is the object that was affected.
In your example this = img
img.onload = function () {
console.log(this);
...
}
Well, any function has "window" as "this", unless it has something else as this.
Related
I have this function here, I need to work with this other function called OrderRepository in another file.
main.js
function main() {
var orderRepo = new OrderRepository();
// Your code here
}
orderrepository.js
function OrderRepository() {
}
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
These were given as examples to use, 1 question rolled into 2 parts:
1) var orderRepo = new OrderRepository();
Can you initialize a function like this?
2) In the orderrepository.js:
function OrderRepository() {
}
is being called in main.js, but nothings inside of it, this was given as-is in the assignment, is this just a typo and really they meant to throw everything inside that function or am I missing something?
Shouldn't it look like this?
Expected
function OrderRepository() {
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
}
Diving deeper into JavaScript, the language is hard to understand. JavaScript is not really OOP (imho), at least it does not implement the common OOP concept. Some call it object-based language. There are no classes. Recent ECMA Script standards do implement the class keyword, however, it is syntax sugar. Used with the new keyword it builds the same objects as you can achieve by 'constructor' functions.
Everything in JavaScript is an object, even numbers and functions. Every function can act as constructor function. The new keyword call a constructor function with a newly creates empty object as the function's this context. The function can do what it wants. If it does not return anything, its this context is returned by the new expression.
Since there are no classes, there is no inheritance. Some inheritance-like behavior is achieved by the prototype concept. In most cases the constructor will return nothing and sometimes modify the this object by adding properties. Methods are properties holding a function object. The object in the new context of a constructor call will have a prototype object reference as the __proto__ property. This is copied by the new operator from the prototype property of the called constructor function. The default is an empty object.
// empty constructor function
function OrderRepository() {
}
// define a function property on the constructor's prototype object
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [ /* array of objects */ ],
return yesterdaysOrders;
};
// create an empty object with a `__proto__` property holding a
// reference to the object { getYesterdaysOrders: function(){/*code*/} }
var obj = new OrderRepository();
Now, when the method invocation obj.getYesterdaysOrders() is tried, JavaScript will look if there is such a property defined in obj. If not, it looks if there is a reference in obj.__proto__ and the property name is searched the properties of obj.__proto__. If not, the same step is repeated until it was found or the __proto__ property in the chain is null. Since obj.__proto__.getYesterdaysOrders is defined, it is checked if it is a callable function object and finally invoked with a this context of obj since we called obj.getYesterdaysOrders(). Otherwise an error is thrown.
NOTE: Even if the major browsers do expose the __proto__ property, it is not part of the standards. Do not use it directly (except for debugging at development time) and even more important: do not manipulate it. If you really need to get or manipulate a prototype (__proto__) of an object instance after construction, use the methods of the builtin Object object.
Upon your last edit: Your expected code would define a new function object in prototype on each instantiation (and thus constructor invocation). This is not what you want, it's just needless overhead.
Regarding the first part, it looks like this assignment is dealing with how to create instances of objects in JavaScript as that is what the new operator does.
You can find more information regarding new on the MDN.
Regarding the second question, it is dealing with how to create objects that inherit methods. So, yes it is empty, until you get to the prototype expression.
The expected code would not give you the inheritance in this case. Notice how OrderRepository is repeated inside the function, which would be invalid. Javascript requires you to add inheritance to the special prototype property. Code that is added to the function declaration, would be scoped to the function only in that case.
You can find more information about prototype on the MDN.
I have heard different opinions about the usage of var at a situation like this:
function(maybeUndefined) {
if(typeof maybeUndefined === 'undefined')
var maybeUndefined = 'bob';
}
Is it necessary to notate var, or not, because maybeUndefined is an argument of function?
You do not need the var in this case, as mayBeUndefined is already allocated within the scope of the function (hint: listing argument variables in a function definition causes those variables to be declared locally). That var is therefore completely optional, though completely pointless (and a drain on readability).
Example:
function func ( arg1, arg2 ) {
var local1, local2;
function nested1 () {}
function nested2 () {}
// other code
}
Here we have a function declaration. When this declaration is parsed into a function object, a lexical environment (= scope) is created for that function with the following bindings:
arg1
arg2
local1
local2
nested1
nested2
this
arguments
(Notice how there also are two special, built-in bindings: this and arguments. These are always created for all function objects.)
These names are defined as local bindings. (This process is specified in "Declaration binding instantiation". Warning: this algorithm is not meant to be read by humans :-)) Therefore, when a name is defined as a parameter, it is not necessary to declare it as a local variable. This mechanism is independent of whether a value (argument) is passed for that parameter when the function is invoked.
So, even if you invoke the function like so:
func(123);
the name arg2 will still be defined (as a binding in the function's environment), although its value will initially be undefined for that particular invocation.
Btw, if you use the strict language (recommended!), function environments are static which means that the above bindings are garanteed to be the only bindings in the function's environment. The default language, on the other hand, provides certain mechanisms to, dynamically, add/remove bindings from the function's environment. Example:
(function () {
// the name "temp" does not exist as a binding in the function's environment
eval('var temp');
// now it does
delete temp;
// and it's gone again
}());
You should not use var again, it is bad for readability, and the variable will already be scoped locally as a result of being an argument.
Also, you should note that it is not a part of this. this will only be scoped to the function object if the new keyword has been used, and as you do not have a named function, that seems unlikely in this case. Without new, this refers to window (or is undefined if use strict; is used), of which your variable is definitely not a part of as a result of the argument having a local scope.
Interfacing
Including a function argument is effectively the same as scoping a variable (in other words, it's effectively the same thing as defining a function-level reference using the var keyword). The main reason for providing function arguments (in JavaScript) is for your own interfacing preference.
The arguments object
Arguments may still be passed to functions without parameters, and will still be accessible in the 'hidden' arguments object -- which is sort of a "pseudo-array" (if you will), in that it is functionally an array, but is not equipped with the same APIs JavaScript equips the Array (pseudo-type) with:
// The following functions do the same thing, but one is "more readable"
function foo() {
return arguments;
}
function bar(baz, qux) {
return arguments;
}
Evaluation (interface) vs Execution (implement)
When both functions are evaluated (on file 'load'), the arguments object is undefined in every function definition; the object doesn't become "defined" until the function body executes the code therein; to visualize that using pseudo-code, it'd look something like this:
// Function bodies (as objects)
foo : {
arguments : new Array // [undefined]
__proto__ : Empty() // the super-object that allows this object to inherit "functionality"
}
bar : {
arguments : new Array(baz, qux) // [undefined, undefined]
__proto__ : Empty()
}
Function invocation
So when you invoke a function, it "implements" or "executes" its body (its "object"). When it does that, if the objects that have been pushed into the arguments object are defined, then the function can reference them. If not, a reference error will be thrown, logging that the variables are undefined in that scope.
In short:
It isn't necessary to interface function-scope-level variables (aka "private members") using var because the language already attaches the arguments object to all function body objects.
More reading:
JavaScript Memoization: "Function-caching" multiple arguments for better performance:
http://decodize.com/javascript/javascript-memoization-caching-results-for-better-performance/
"The this keyword always refers to the object that the containing function is a method of."
Great, sounds simple enough, but here's what I'm wondering about...
For example:
function func1() {
function func2() {
alert(this == window); // true
}
func2();
alert(this == window); // true
}
func1.func3 = function () {
alert(this == window); // false
alert(this == func1); // true
};
func1();
func1.func3();
Now, since func1 is actually a method of the global (window) object (a function object assigned to the property func1 of the global object) it makes sense that this inside func1 refers to the global object, and since func3 is a method of func1's function object it makes sense that this inside func3 refers to func1's function object.
The thing that bothers me is func2. I know that this inside a nested function is also supposed to reference the global object, but I'm not sure why since func2 is NOT a method of the global object. As far as I understand (and this is the part I might be completely wrong about) func2 is a method of func1's call (activation / variable) object. Now, if I'm right about this (and I'm not sure that I am) then shouldn't this inside func2 refer to func1's call object instead of the global object?
So, I guess my question would be: Is a nested function a method of the call (activation) object of the function it is nested in, and if so, shouldn't this refer to that call object instead the global object?
The this keyword always refers to the object that the containing function is a method of.
No. Unfortunately, it is not easy as that. The documentation of the this keyword at MDN gives a good overview. It is set to the object when the function is called as a method on it, but there are other possibilies. The default is that this is undefined when it is called without anything special, like you do with func1 and func2. For sloppy (non-strict) mode functions undefined (and null) are not used though, this does point to the global object (window in browsers) for them in that case - what you are observing.
But it could also point to fresh object instances when the function is called as a constructor (with the new keyword), or to an event target (like a DOM element) when used as a handler. Last, but not least, it could be set manually with call, apply or bind…
this has nothing to do with nesting. Nesting function declarations/expressions only affects the scope ("privacy", availability) of variables. While the variable scope of a function never changes, the value of this can be different on every invocation - it is more like an extra argument.
The meaning of the this keyword inside a function depends on the way the function is invoked. There are 4 different function invocation patterns in JavaScript.
function invocation pattern foo()
method invocation pattern o.foo()
constructor invocation pattern new foo
call/apply pattern foo.apply(...) or foo.call(...)
Only in #2 is it the case that this inside the function refers to the object of which the function is a method.
You are invoking func2() with the function invocation pattern. When doing so, this refers to the global object.
As suggested by #Bergi, see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this for more detail on the meaning of this and the different function invocation patterns.
but I'm not sure why since func2 is NOT a method of the global object.
Any thing defined inside a function is local to the scope of that function. So func2 belongs to the local scope of func1 and therefore is not attached to window.
In Javascript, the value of this is generally based on how you call the function. When you call a function without any leading object, this is usually set to the global parent object, which is window.
You can explicitly set the value of this in three ways:
myObj.func(a, b); //this set to myObj implicitly because myObj is the parent
func.call(myObj, a, b); //this set to myObj explicitly; the first argument
//to call sets the value of this for that function
func.apply(myObj, [a, b]); //this set to myObj explicitly; the first argument
//to apply also sets the value of this for that
//function.
this can be a tricky concept. MDN has a good article about this.
Please help me to understand below code. This is the script for drag and drop object. I am trying to explore it but struck at one thing.
URL for Reference (Complete Script)
I dont understand how this method creation work, like get x(), set x() etc. Is get and Set is predefined object? will it actually set object value or get specific value of object, like we have in date object.
Also there is one space between its declaration set x(), why?
I am new to java script, i really appreciate your help.
// position strings are "x,y" with no units
get x()
{
return parseInt(this._position.split(',')[0]);
},
set x(inX)
{
var comps = this._position.split(',');
comps[0] = inX;
this.position = comps.join(',');
},
get y()
{
return parseInt(this._position.split(',')[1]);
},
set y(inY)
{
var comps = this._position.split(',');
comps[1] = inY;
this.position = comps.join(',');
},
Let's start by calling the language 'JavaScript' not 'java script'; the language is standardized as Ecmascript.
Look up creation of methods in Ecmascript (JavaScript). The functions set(inX) and get() are methods be of some prototype - the clue is the this reference referencing the current instance. However, one should write function get(), and function set(inX) instead.
From Wikipedia:
Prototype-based
prototypes
JavaScript uses prototypes instead of classes for inheritance. It
is possible to simulate many class-based features with prototypes in
JavaScript. functions as object constructors
Functions double as object constructors along with their typical
role. Prefixing a function call with new creates a new object and
calls that function with its local this keyword bound to that object
for that invocation. The constructor's prototype property determines
the object used for the new object's internal prototype. JavaScript's
built-in constructors, such as Array, also have prototypes that can be
modified. functions as methods
Unlike many object-oriented languages, there is no distinction
between a function definition and a method definition. Rather, the
distinction occurs during function calling; a function can be called
as a method. When a function is called as a method of an object, the
function's local this keyword is bound to that object for that
invocation.
I asked a question on Javascript this points to Window object regarding "this" points to Window object.
here is source code
var archive = function(){}
archive.prototype.action = {
test: function(callback){
callback();
},
test2: function(){
console.log(this);
}
}
var oArchive = new archive();
oArchive.action.test(oArchive.action.test2);
Tim Down wrote "but that function is then called using callback(), which means it is not called as a method and hence this is the global object".
What are differences between calling a function by its actual name and callback() as shown on the source code?
How does console.log(this) in test2 points to Window when it is inside archive.action???
In JavaScript you can invoke functions using 4 different invocation patterns:
Function invocation
Method invocation
Apply/Call invocation
Construction invocation
The patterns mainly differ in how the this parameter is initialized.
When you use oArchive.action.test2(), you would be invoking the test2() function with the method pattern, and in this case this would be bound to the action object. JavaScript will use the method pattern whenever the invocation expression contains a refinement (i.e. the . dot expression or the [subscript] expression).
On the other hand, when a function is not the property of an object, then it is invoked using the function pattern. In this case, the this parameter is bound to the global object, and in fact this is how JavaScript is invoking your callback() function.
Douglas Crockford in his Good Parts book, describes this as a mistake in the design of the language, and suggests some possible workarounds. In you case, one easy workaround would be to invoke the callback using call() or apply(), as Tim Down suggested in your previous question:
callback.call(this);
This works because the Apply/Call invocation pattern lets you choose the value of this, which is what you require.
In javascript the this keyword is set to the owner of a function. Function objects do not maintain their ownership themselves, instead the ownership is deduced from the way we call a function.
eg:
var foo = function() {
alert('hello');
};
var abc = {};
abc.bar = foo;
Simply calling the function like
foo();
gives the interpreter no clue about what object the function might be attached to. It may be attached to multiple objects, it may be a variable etc. So the interpreter sets this to the global object.
But however, when calling a function like
abc.bar();
the interpreter knows that function is attached to abc object, therefore this is set to abc. Even if both bar and foo refer to the same function object, the difference in the calling pattern causes this to behave differently.