Functions
Function as normal function
function add(a, b) {
return a + b;
}Function as method
var Rectangle = {
x: 2,
y: 4,
perimeter : function() {
return (this.x+this.y)*2;
}
}
Rectangle.perimeter(); // 12
Function as constructor
function Rectangle(x, y) {
this.x = x;
this.y = y;
}
var rect = new Rectangle(1, 2);function declaration
VS
function expression
Function declaration
function functionName([parameters]){
//functionBody
};
add(2, 4); // works
function add(x, y) {
return x + y;
}Function declaration
alert(x); // prints function body
var x = 10;
alert(x); // 10
x = 20;
function x() {};
alert(x); // 20Anonymous function expression
variableName = function([parameters]){
//functionBody
};
add; //undefined
add(2, 4); // this raises a TypeError
var add = function(x, y) {
return x + y;
}Named function expression
variableName = function functionName([parameters]){
//functionBody
};
var foo = function bar() {
bar(); // works
}
bar(); // ReferenceError
New function
variableName = new Function(
/*
parameters
*/,
functionBody
);
var add = new Function(“x”, “y”, “return x + y”);Strategy of passing arguments to function
Primitive types are manipulated by value.
Object types are manipulated by sharing.
function func(obj){
obj.prop1 = 5;
obj = {};
}
var data = {};
func(data);
console.log(data); // {prop1: 5}
First-class functions
A first-class function is one that may participate as a normal data, i.e. be created literally at runtime, be passed as an argument, or be returned as a value from another function.
Function as data
function square(x) { return x * x; }
var pointerToSquare = square;
Assert(pointerToSquare(3) == 9);
var newArray = ["a", "b", "c", pointerToSquare];
Assert(newArray[3](4) == 16);
var obj = { "square": square };
Assert(obj.square(5) == 25);Static members
function MyMath() {
//math here...
}
MyMath.Pi = 3.14;
function getNewId() {
if (!getNewId.lastId) getNewId.lastId = 0;
return ++getNewId.lastId;
}return statement
return expression;
return; // return undefinedIf there is no expression, then the return value is undefined.
Except for constructors, whose default return value is this.
Function arguments
- If a function is called with too many arguments, the extra arguments are ignored.
- If a function is called with too few arguments, the missing values will be undefined.
Optional arguments and argument types
function NodeText(/*domNode|String*/ node, /*String?*/ text) {
if (typeof node == “string”){
node = document.getElementById(node);
if (!node) return;
}
if(text != null) {
node.innerHTML = text;
} else {
return node.innerHTML ;
}
}Options objects
var printEmployeeInformation = function (info) {
var firstName = info.firstName || "";
var lastName = info.lastName || "";
var position = info.position || "";
var office = info.office || "K1";
var phone = info.phone || "911";
var internalPhone = info.internalPhone || "";
var manager = info.manager || "";
///…
}
var info = { firstName: “Bruce", lastName: "Wayne", internalPhone: “111" };
info.office = "K1/5";
printEmployeeInformation(info);
info.office = "K1";
printEmployeeInformation(info);Pseudo parameters
- arguments
- this
The "arguments" object
arguments contains the following properties:
- callee – reference to the current function
- length – quantity of real passed arguments
- properties-indexes – parameters from the invocation
It is an array-like object.
foo(10, 20);
function foo(x, y, z) {
// quantity of defined function arguments (x, y, z)
alert(foo.length); // 3
// quantity of really passed arguments (only x, y)
alert(arguments.length); // 2
// reference of a function to itself
alert(arguments.callee === foo);
// parameters sharing
alert(x === arguments[0]); // true
alert(x); // 10
alert(arguments[2]); // undefined
}The "arguments" object
function sum() {
var n = arguments.length;
var total = 0;
for (var i = 0; i < n; i++) {
total += arguments[i];
}
return total;
}
var ten = sum(1, 2, 3, 4);This
determined on runtime and immutable
This
function Car(model, color) {
this.model = model;
this.color = color;
this.changeGear = function (value) {
this.currentGear = value;
//....
}
}This in the global context
var x = 20;
console.log(x == window.x);
console.log(this.x == x);
console.log(this.x == window.x);This in the function context
function foo() {
console.log(this.bar);
}
var x = { bar: 1 };
var y = { bar: 2 };
x.foo = foo;
y.foo = foo;
x.foo(); // 1
y.foo(); // 2
var bar = 3;
foo(); //3
new foo(); // undefinedValue of this in function is determined by the form on invocation but not context of definition.
Function form
foo();
function foo(){
this === window; // Fixed in ES5/Strict
}Method form
var test = {
“name”: “Max”,
“foo”: function(){
alert(this.name);
}
};
test.foo(); //this === test
test[“foo”](); // this === test
var foo = test.foo;
foo(); // this === window
Constructor form
function Car(model, color) {
this.model = model;
this.color = color;
this.changeGear = function () {
//…
}
}
var bmw1 = new Car(“z1", “black")
bmw1.changeGear();Constructor form
function Car(model, color) {
this.model = model; // this === window
this.color = color;
this.changeGear = function () {
//…
}
}
var bmw1 = Car(“z1", “black"); // without new
bmw1.changeGear();Constructor form
function Car(model, color) {
var that = {};
that.model = model;
that.color = color;
that.changeGear = function () {
//…
}
return that;
}
var bmw1 = Car(“z1", “black"); // without new
bmw1.changeGear();Inner form
function Car(model, color) {
this.model = model;
this.color = color;
this.changeGear = function () {
var that = this;
var inner = function() {
//this === window
// Use that instead of this here
}
inner();
}
}Explicit setting of this
foo.apply(thisObject,[arguments])
foo.call(thisObject, / *arguments */);A function’s apply or call method allows for calling the function, explicitly specifying this.
Arguments / apply
var array = [1,2,368,10,45];
Math.max.apply(Math,array); //368Borrowing methods
notmyobj.doStuff.call(myobj, param1, p2, p3);
notmyobj.doStuff.apply(myobj, [param1, p2, p3]);
function f() {
var args = [].slice.call(arguments, 1, 3);
return args;
}
f(1,2,3,4,5,6); // [2, 3]
Bind
var x = 9; // global variable
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX(); // 9, because in this case, "this" refers to the global object
// Create a new function with 'this' bound to module
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
Lexical (or Static) Scope
function f() {
var x = 2;
function g() {
alert(x);
}
}Static structure of a program determines the scope of a variable.
Lexical (or Static) Scope
var z = 10;
function foo() {
alert(z);
}
foo();
(function () {
var z = 20;
foo();
})();Closures
var inner;
function outer(){
var local = 1;
inner = function(){
return local;
};
}
inner();
outer();
inner();Closures
function doNTimes(n, action) {
function doNTimesRec(x) {
if (x >= 1) {
action(); // (1)
doNTimesRec(x-1);
}
}
doNTimesRec(n);
}Functions Stay Connected to Their Birth Scopes
function createInc(startValue) {
return function (step) {
startValue += step;
return startValue;
};
}
var inc = createInc(5);
inc(1); // 6
inc(2); // 8Closures
function sayHello() {
var text = "Hello #1";
var sayAlert = function() { alert(text); }
text = "Hello #2";
sayAlert();
}Private Members
var obj = new function () {
var privateVariable;
function privateFunction(x) {
// privateVariable
}
return {
firstMethod: function (a, b) {
// access to privateVariable
},
secondMethod: function (c) {
// access to privateVariable
// access to privateFunction()
}
};
};Immediately-Invoked Function Expression
(function () { // open IIFE
// inside IIFE
}()); // close IIFE
(function (x, y) {
console.log(x + y);
}(2,4));why IIFE ?
Avoiding global variable or hiding variables from global scope.
(function () {
var x = 2;
var y = 4;
}());
typeof window.x === “undefined”;
typeof window.y === “undefined”;Avoiding variable sharing.
function f() {
var result = [];
for (var i=0; i<3; i++) {
var func = function () { return i; };
result.push(func);
}
return result;
}
console.log(f()[0]()); // 3
console.log(f()[1]()); // 3
console.log(f()[2]()); // 3Avoiding variable sharing.
function f() {
var result = [];
for (var i=0; i<3; i++) {
(function () { // step 1: IIFE
var pos = i; // step 2: copy
var func = function () { return pos; };
result.push(func);
}());
}
return result;
}
console.log(f()[0]()); // 0
console.log(f()[1]()); // 1
console.log(f()[2]()); // 2Functions
By andrei_bibik
Functions
- 478