5、函数调用

JS函数调用
Javascript 函数有 4 种调用方式。每种方式的不同在于this的初始化。
this关键字
一般而言,在Javascript中,this指向函数执行时的当前对象。但是this是保留关键字,并不能被修改。

调用函数,函数中的代码在函数被调用后执行。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title></title>
 6         <script>
 7             function myFunction(a, b) {
 8                 return a * b;
 9             }
10             myFunction(10, 2); //myFunction(10, 2) 返回20
11         </script>
12     </head>
13 </html>

以上函数不属于任何对象,但是在JS中它始终默认是全局对象。

在HTML中默认的全局对象是HTML页面本身,所以函数是属于HTML页面的。

在浏览器中的页面对象是浏览器窗口。以上函数会自动变为window对象的函数。

所以myFunction()与window.myFunction()是一样的效果。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title></title>
 6         <script>
 7             function myFunction(a, b) {
 8                 return a * b;
 9             }
10             window.myFunction(10, 2); //返回20
11         </script>
12     </head>
13 </html>

这个是调用JS函数常用的方法,但不是良好的编程习惯。

全局变量、方法和函数容易造成命名冲突的bug。

全局对象:

当函数没有被自身的对象调用时,this的值就会变成全局对象。在浏览器中全局对象是window对象。所以以下代码this值返回window对象。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title></title>
 6         <script>
 7             function myFunction() {
 8                 return this;
 9             }
10             window.myFunction(); //返回windo对象
11         </script>
12     </head>
13 </html>

函数作为全局对象调用,会使this的值变成全局对象。使用window对象作为一个变量容易造成程序崩溃。

函数作为方法进行调用:

在JS中可以将函数定义为对象的方法。

以下一段代码创建了一个对象myObject,对象有两个属性firstName和lastName,以及一个方法fullName:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            function myObject() {
                firstName:‘前端‘;
                lastName:‘技术‘;
                fullName:function() {
                    return this.firstName + " " + this.lastName;
                }
            }
            myObjec.fullName(); //返回前端 技术
        </script>
    </head>
</html>

fullName方法是一个函数。函数属于对象。myObject是函数的所有者。

this对象拥有javascript代码。以上代码中this的值为myObject对象。

以下代码修改了fullName方法并返回this值:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            function myObject() {
                firstName:‘前端‘;
                lastName:‘技术‘;
                fullName:function() {
                    return this;
                }
            }
            myObjec.fullName(); //返回[object object](所有者对象)
        </script>
    </head>
</html>

函数作为对象方法调用,会使得 this 的值成为对象本身。

使用构造函数调用函数:

如果函数调用前使用了new关键字,则调用了构造函数。

看起来就像创建了新的函数,但实际上JS函数是重新创建的对象:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title></title>
 6         <script>
 7             function myFunction(arg1, arg2) {
 8                                               this.firstName = arg1;
 9                                               this.lastName = arg2;
10                                             }
11
12                                             // This creates a new object
13                                             var x = new myFunction("前端","技术");
14                                             x.firstName;               // 返回 "前端"
15         </script>
16     </head>
17 </html>        

构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。

构造函数中this关键字没有任何的值。

this的值在函数调用时实例化对象的时候创建。

作为函数方法调用函数:

在JS中,函数是对象。JS函数有它的属性和方法。

call()和apply()是预定义的函数方法。两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

call方法:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title></title>
 6         <script>
 7             function myFunction(a, b) {
 8                                           return a * b;
 9                                     }
10             myFunction.call(myObject, 10, 2);   // 返回 20
11         </script>
12     </head>
13 </html>

apply方法:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            function myFunction(a, b) {
                                          return a * b;
                                    }
            myArray = [10,2];
            myFunction.apply(myObject, myArray);  // 返回 20
        </script>
    </head>
</html>

两个方法都使用了对象本身作为第一个参数。 两者的区别在于第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
在 JS严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。
在 JS 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。
通过 call() 或 apply() 方法可以设置 this 的值, 且作为已存在对象的新方法调用。

时间: 2024-10-12 15:20:56

5、函数调用的相关文章

C++函数调用时的参数传递-3中传递方式

参数传递即实参向形参传递信息,使形参获得对应的存储空间及初值,C++中函数传递主要有3种方式: 1.按值传递. 以按值传递方式进行参数传递的过程为:首先计算出实参的值,然后给它所对应的形参变量分配存储空间,该空间大小等于该形参类型的长度,然后把实参值存入到为形参分配的存储空间里去,该值即为形参的初值,在函数被调用时使用.而这种方式被调用的函数对实参的值改变不会有任何的影响,也就是说,即使形参的值在函数中被改变,也不会对实参值产生任何影响,实参值仍为被调用之前的值.究其原因还是实参和形参各占独立的

【转】C/C++函数调用过程分析

转自:here 这里以一个简单的C语言代码为例,来分析函数调用过程 代码: #include <stdio.h> int func(int param1 ,int param2,int param3) { int var1 = param1; int var2 = param2; int var3 = param3; printf("var1=%d,var2=%d,var3=%d",var1,var2,var3); return var1; } int main(int a

Crush The Crash--汇编级看函数调用

游戏在后期polish以及上线之后,一个不可避免的部分就是要处理各种bug,包括crash. 汇编?似乎只是学校里学习了一下,在现在都倾向于使用高层语言的时代,还有用么?答案是肯定的. 有大量的crash以及bug都是只发生在retail版中,现场都是优化过的汇编代码,大部分是minidump,里面包含的信息非常有限,你拿到的就是一个优化过的汇编代码,加上少量的stack上的内存信息,这种情况下要处理掉crash,能从这些汇编代码中解析minidump并最终击杀问题是唯一的选择. 本文涉及的知识

Javascript读书笔记:函数定义和函数调用

定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方式: var add = new Function("m", "n", "alert(m+n);"); Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:&

JS函数调用的四种方法

js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方法调用模式 函数调用模式 构造器调用模式 apply调用模式 下面我们来看看一些实例更好理解. 1:方法调用模式. 请注意this此时指向myobject. /*方法调用模式*/    var myobject={            value:0,            inc:functio

C/C++:函数调用规则__stdcall,__cdecl,__pascal,__fastcall

__cdecl __cdecl 是 C Declaration  的缩写,表示 C 语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈.被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误. __stdcall __stdcall 是 Standard Call 的缩写,是 C++ 的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是 this 指针.这些堆栈中的参数由被调用的

js函数调用的方法:

js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方法调用模式 函数调用模式 构造器调用模式 apply调用模式 下面我们来看看一些实例更好理解. 1:方法调用模式. 请注意this此时指向myobject. /*方法调用模式*/    var myobject={            value:0,            inc:functio

在linux代码中打印函数调用的堆栈的方法

之前一直有这样的需求,当时问到,也没搜到方法,现在竟然既问到了,也搜到了,哎,世事真是不能强求啊! 在Linux内核调试中,经常用到的打印函数调用堆栈的方法非常简单,只需在需要查看堆栈的函数中加入: dump_stack();或 __backtrace();即可. dump_stack()在~/kernel/ lib/Dump_stack.c中定义 void dump_stack(void){ printk(KERN_NOTICE  "This architecture does not imp

Swift 函数调用到底写不写参数名

最近真正开始学 Swift,在调用函数的时候遇到一个问题:到底写不写函数名? 我们来看两个个例子: // 1 func test(a: Int, b: Int) ->Int { return a + b } test(a: 1, b: 1) // (A) test(1, b:1) // (B) //2 class Test { var name: String var age: Int init(name: String, age: Int) { self.name = name self.ag

分析函数调用关系图(call graph)的几种方法

分析函数调用关系图(call graph)的几种方法 绘制函数调用关系图对理解大型程序大有帮助.我想大家都有过一边读源码(并在头脑中维护一个调用栈),一边在纸上画函数调用关系,然后整理成图的经历.如果运气好一点,借助调试器的单步跟踪功能和call stack窗口,能节约一些脑力.不过如果要分析的是脚本语言的代码,那多半只好老老实实用第一种方法了.如果在读代码之前,手边就有一份调用图,岂不妙哉?下面举出我知道的几种免费的分析C/C++函数调用关系的工具. 函数调用关系图(call graph)是图