日期:2014-05-16 浏览次数:20424 次
Function is an important concept in javascript, and its invocation pattern is so hard to understand, fortunately, Douglas Crockford has greate explanation in his book "Javascript: the good parts", below is the snippet from that book on this topic.
?
///////////
Invoking a function suspends the execution of the current function, passing control and parameters to the new function. In addition to the declared parameters, every function receives two additional parameters: this and arguments . The this parameter is very important in object oriented programming, and its value is determined by the invocation pattern . There are four patterns of invocation in JavaScript: the method invocation pattern, the function invocation pattern, the constructor invocation pattern, and the apply invocation pattern. The patterns differ in how the bonus parameter this is initialized.
The invocation operator is a pair of parentheses that follow any expression that produces a function value. The parentheses can contain zero or more expressions, separated by commas. Each expression produces one argument value. Each of the argument values will be assigned to the function's parameter names. There is no runtime error when the number of arguments and the number of parameters do not match. If there are too many argument values, the extra argument values will be ignored. If there are too few argument values, the undefined value will be substituted for the missing values. There is no type checking on the argument values: any type of value can be passed to any parameter.
When a function is stored as a property of an object, we call it a method . When a method is invoked, this is bound to that object. If an invocation expression contains a refinement (that is, a . dot expression or [ subscript ] expression), it is invoked as a method:
// Create myObject. It has a value and an increment // method. The increment method takes an optional // parameter. If the argument is not a number, then 1 // is used as the default. var myObject = { value: 0; increment: function (inc) { this.value += typeof inc === 'number' ? inc : 1; } }; myObject.increment( ); document.writeln(myObject.value); // 1 myObject.increment(2); document.writeln(myObject.value); // 3
?
A method can use this to access the object so that it can retrieve values from the object or modify the object. The binding of this to the object happens at invocation time. This very late binding makes functions that use this highly reusable. Methods that get their object context from this are called public methods .
When a function is not the property of an object, then it is invoked as a function:
var sum = add(3, 4); // sum is 7
?
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, this would still be bound to the this variable of the outer function. A consequence of this error is that a method cannot employ an inner function to help it do its work because the inner function does not share the method's access to the object as its this is bound to the wrong val