`
alexgreenbar
  • 浏览: 87649 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

javascript里的函数调用模式

阅读更多

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/

 

 

0
0
分享到:
评论
1 楼 alexgreenbar 2011-01-28  
function User(name) {
    this.name = name;
    //do some other stuff
    function addSomething() {
        this.name = this.name + "++";
    }
    addSomething();
}
var a = new User("luis");
alert(a.name);  //luis
alert(window.name); //++

相关推荐

    C#与JAVASCRIPT函数的相互调用 C#调用JAVASCRIPT函数的调用 JAVASCRIPT调用C#函数的调用

    C#与JAVASCRIPT函数的相互调用 C#调用JAVASCRIPT函数的调用 JAVASCRIPT调用C#函数的调用

    JavaScript中函数对象调用模式总结

    这篇博客通过深入分析JavaScript中的函数调用模式,帮助开发者更好地理解和掌握这些概念。 首先,JavaScript是一种动态类型语言,其中函数不仅是一种数据类型,还能够作为值进行传递和存储。这种特性被称为“函数是...

    JS 四种函数调用模式

    了解并熟练掌握这些函数调用模式对于编写高效、可维护的 JavaScript 代码至关重要。它们在处理对象间的交互、继承和上下文绑定时尤其有用。在实际开发中,你需要根据场景选择合适的调用方式,以便更好地控制代码的...

    JavaScript函数的调用以及参数传递

    JavaScript 函数调用 JavaScript 函数有 4 种调用方式。 每种方式的不同方式在于 this 的初始化。 this 关键字 一般而言,在Javascript中,this指向函数执行时的当前对象。 Note 注意 this 是保留关键字,你不能...

    javascript调用delphi中的函数

    标题“javascript调用delphi中的函数”涉及到的技术领域是跨语言通信,具体是JavaScript与Delphi之间的交互。这种交互通常发生在Web应用程序与桌面应用程序的集成,或者在浏览器扩展和本地资源之间。以下是对这一...

    在javascript函数中调用com组件的属性和方法

    在javascript函数中调用com组件的属性和方法 在JavaScript函数中调用COM组件的属性和方法是指在JavaScript代码中使用COM组件提供的属性和方法来实现各种功能。本文将介绍如何在JavaScript函数中调用COM组件的属性和...

    JavaScript函数调用堆栈loader

    JavaScript函数调用堆栈是编程过程中非常重要的一个概念,它记录了程序运行时函数的调用顺序。在JavaScript中,每当一个函数被调用,一个新的调用帧(call frame)就会被添加到调用堆栈上,包含了这个函数执行的所有...

    QT和网页中的JavaScript函数进行相互调用的实现

    - 这里的回调函数用于处理JavaScript函数的异步返回结果,如果需要同步获取结果,可以使用`QWebEngineScript`来注册一个全局JavaScript对象,然后通过该对象调用JavaScript函数。 2. **JavaScript调用QT函数**: ...

    javascript实现根据函数名称字符串动态执行函数的方法示例

    接下来,我们来看看实现动态函数调用的几种方式: 1. 使用eval()函数: eval()函数可以执行字符串中的JavaScript代码,如果我们知道要调用的函数名的字符串,可以将其与括号“()”组合起来形成代码字符串,并用eval...

    vbscript和javascript互相调用方法

    例如,如果你想从VBScript调用一个名为`myFunc`的JavaScript函数,你可以这样做: ```vbscript Dim myObj Set myObj = Server.CreateObject("Scripting.Dictionary") myObj.Language = "JScript" myObj.Add "myFunc...

    Javascript调用C#函数示例程序

    一个在HTML中使用Javascript的window.external调用C#内函数的示例程序。该方法可应用于网页程序开发中的网页-程序沟通,例如用C#的IHTMLWindow2.execScript替换HTML默认Javascript方法使其直接与C#传参、通讯。

    javascript_函数大全

    ### JavaScript函数大全解析 在深入探讨JavaScript函数的广泛应用与特性之前,让我们首先明确一点:JavaScript函数不仅是编程语言中的核心组件,更是实现复杂逻辑、封装功能模块的关键所在。不同于许多传统面向对象...

    Babel插件用于带任何函数调用

    标题 "Babel插件用于带任何函数调用" 指的是在JavaScript开发过程中,使用Babel这个转换工具时,特定的插件可以处理带有任意函数调用的代码。Babel是一个广泛使用的JavaScript编译器,它允许开发者使用最新版本的...

    Javascript 设计模式之构造函数模式.zip

    构造函数模式是JavaScript中的一种重要设计模式,用于创建对象。本文将深入探讨构造函数模式及其应用。 构造函数模式的核心在于使用函数来创建具有相似属性和方法的对象。在JavaScript中,函数可以作为构造函数来...

    JavaScript函数式编程.pdf

    柯里化有助于参数复用和延迟计算,使得函数调用更加灵活。 7. 组合(Composition) 函数组合是指将简单的函数组合成复杂函数的过程。在JavaScript函数式编程中,组合函数可以将多个小的、单一功能的函数串联起来,...

    javascript函数式编程

    JavaScript函数式编程是一种编程范式,它强调将计算视为数据处理的过程,并且重视函数作为第一类公民,即函数可以作为变量赋值、作为参数传递、作为返回值返回。这种编程风格在JavaScript中尤其常见,因为它提供了...

    qt 调用javascript函数 带参数

    本篇文章将深入探讨如何在Qt中调用JavaScript函数并传递参数,以实现更丰富的功能。 首先,Qt的Webkit模块是实现这一目标的关键。Qt Webkit是一个基于WebKit引擎的组件,它允许Qt应用渲染网页内容,并与网页进行...

    c#代码与javascript函数的相互调用

    本文将深入探讨C#代码与JavaScript函数的相互调用机制,解析如何在ASP.NET环境中利用这两种语言的优势,构建高效、动态的Web应用。 ### C#调用JavaScript #### 直接插入JavaScript代码 在C#的ASP.NET页面中,可以...

    C#代码与javaScript函数的相互调用

    本文将详细探讨C#与JavaScript之间的相互调用方法,主要涉及四个方面的内容:如何在JavaScript中访问C#函数、如何在JavaScript中访问C#变量、如何在C#中访问JavaScript已有的变量以及如何在C#中访问JavaScript函数。...

    浅析JavaScript函数的调用模式

    JavaScript函数的调用模式是该语言中重要的基础概念之一,理解这些模式可以帮助开发者更有效地编写代码和解决实际问题。本文将详细介绍方法调用模式、构造器调用模式以及apply/call调用模式。 首先,介绍方法调用...

Global site tag (gtag.js) - Google Analytics