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.
///////////
4.3. Invocation
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.
4.3.1. The Method Invocation Pattern
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
.
4.3.2. The Function Invocation Pattern
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 value.
Fortunately, there is an easy workaround. If the method defines a
variable and assigns it the value of this
, the inner function will have access to this
through that variable. By convention, the name of that variable is that
:
// Augment myObject with a double method.
myObject.double = function ( ) {
var that = this; // Workaround.
var helper = function ( ) {
that.value = add(that.value, that.value)
};
helper( ); // Invoke helper as a function.
};
// Invoke double as a method.
myObject.double( );
document.writeln(myObject.getValue( )); // 6
4.3.3. The Constructor Invocation Pattern
JavaScript is a prototypal
inheritance language. That means that objects can inherit properties directly from other objects. The language is class-free.
This is a radical departure from the current fashion. Most languages today are classical
.
Prototypal inheritance is powerfully expressive, but is not widely
understood. JavaScript itself is not confident in its prototypal nature,
so it offers an object-making syntax that is reminiscent of the
classical languages. Few classical programmers found prototypal
inheritance to be acceptable, and classically inspired syntax obscures
the language's true prototypal nature. It is the worst of both worlds.
If a function is invoked with the new
prefix, then a new object will be created with a hidden link to the value of the function's prototype
member, and this
will be bound to that new object.
The new
prefix also changes the behavior of the return
statement. We will see more about that next.
// Create a constructor function called Quo.
// It makes an object with a status property.
var Quo = function (string) {
this.status = string;
};
// Give all instances of Quo a public method
// called get_status.
Quo.prototype.get_status = function ( ) {
return this.status;
};
// Make an instance of Quo.
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status( )); // confused
Functions that are intended to be used with the new
prefix are called constructors
. By convention, they are kept in variables with a capitalized name. If a constructor is called without the new
prefix, very bad things can happen without a compile-time or runtime
warning, so the capitalization convention is really important.
Use of this style of constructor functions is not recommended. We will see better alternatives in the next chapter.
4.3.4. The Apply Invocation Pattern
Because JavaScript is a functional object-oriented language, functions can have methods.
The apply
method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value of this
. The apply
method takes two parameters. The first is the value that should be bound to this
. The second is an array of parameters.
// Make an array of 2 numbers and add them.
var array = [3, 4];
var sum = add.apply(null, array); // sum is 7
// Make an object with a status member.
var statusObject = {
status: 'A-OK'
};
// statusObject does not inherit from Quo.prototype,
// but we can invoke the get_status method on
// statusObject even though statusObject does not have
// a get_status method.
var status = Quo.prototype.get_status.apply(statusObject);
// status is 'A-OK'
///////////
Also, even Crockford give us a greate introduction on this tough concept, to be honest, it isn't enough, and I find the wiki page below has a better complementary for it.
http://blog.msmvps.com/luisabreu/2009/08/24/function-invocation-in-javascript-contexts-revisited/
分享到:
相关推荐
C#与JAVASCRIPT函数的相互调用 C#调用JAVASCRIPT函数的调用 JAVASCRIPT调用C#函数的调用
JavaScript 函数调用 JavaScript 函数有 4 种调用方式。 每种方式的不同方式在于 this 的初始化。 this 关键字 一般而言,在Javascript中,this指向函数执行时的当前对象。 Note 注意 this 是保留关键字,你不能...
用javascript代码调用delphi写的函数
一个在HTML中使用Javascript的window.external调用C#内函数的示例程序。该方法可应用于网页程序开发中的网页-程序沟通,例如用C#的IHTMLWindow2.execScript替换HTML默认Javascript方法使其直接与C#传参、通讯。
NULL 博文链接:https://zhangxing119.iteye.com/blog/846867
下面的调用模式就是大家最熟悉的函数调用模式,而函数调用模式的this指向和返回值是什么呢? function fn1 () { console.log(this); }; fn1(); // 在调用函数fn1时,输出的this的结果是Window 在上述代码中,fn1也...
c#代码与javascript函数的相互调用
JavaScript提供了 4 种函数调用: 一般形式的函数调用 作为对象的方法调用 使用 call 和 apply 动态调用 使用 new 间接调用 5.2.2 函数的调用方式 2、函数的调用方式 一般形式的函数调用,是常见的函数调用方式,...
本文实例讲述了JavaScript实现同时调用多个函数的方法。分享给大家供大家参考,具体如下: 这里分析JavaScript 同时调用同一网页内的多个函数的实现方法,点击按钮后执行多次函数,比如连续弹出多次窗口。 具体代码...
本文介绍了在javascript函数中调用com组件的属性和方法的技术。
JavaScript调用window函数.docx
webpack loader,记录JavaScript函数调用堆栈到字符串window.dxj中,该堆栈可格式化进一步对比分析 也可保存不同时刻的对象进行对比分析
vbscript和javascript互相调用方法
Javascript 函数的四种调用模式 1 函数模式 最普通的函数调用 // 声明式函数 function fn1 () { console.log(this); } // 函数表达式函数 var fn2 = function() { console.log(this); }; // 调用 函数中this...
函数有四种调用模式,分别是:函数调用形式、方法调用形式、构造器形式、以及apply形式。这里所有的调用模式中,最主要的区别在于关键字 this 的意义,下面分别介绍这个几种调用形式。 本文主要内容: 1.分析函数的...
主要为大家详细介绍了JavaScript函数的调用模式,包括方法调用模式,构造器调用模式,apply/call调用模式,感兴趣的小伙伴们可以参考一下
javascript嵌套函数和在函数内调用外部函数的区别分析.docx
QT和网页中的JavaScript函数进行相互调用的实现. 有完整的代码举例。 近期刚完成。
Javascript中调用C++函数的代码示例。