南充城市建设投诉网站,软件发布网,网站建设 站内搜索,世界十大建筑设计事务所定义函数 关键字function用来定义函数。定义函数有两种方法 #xff08;1#xff09;函数定义表达式 1 var f function(x) { return x1; } #xff08;2#xff09;函数声明语句 1 function funcname([arg1 [, arg2 [...,argn]]]) {
2
3 } 函数声明语句通常出现在JavaScr… 定义函数 关键字function用来定义函数。定义函数有两种方法 1函数定义表达式 1 var f function(x) { return x1; } 2函数声明语句 1 function funcname([arg1 [, arg2 [...,argn]]]) {
2
3 } 函数声明语句通常出现在JavaScript代码的最顶层也可以嵌套在其他函数体内。但在嵌套时函数声明只能出现在所嵌套函数的顶部。也就是说函数定义不能出现在if语句、while语句后者其他语句中。 二者异同 1都创建了相同的新函数对象 2函数声明语句中的函数名是一个变量名变量指向函数对象。函数定义表达式并未声明一个变量如果一个函数定义表达式包含名称函数的局部作用域将会包含一个绑定到函数对象的名称。所以名称存在函数体中并指代该函数本身也就是说函数的名称将成为函数内部的一个局部变量。【注】函数定义表达式特别适合用来定义那些只会用到一次的函数 3函数声明语句中的函数被显式地“提前”到了脚本或函数顶部。因此它们在整个脚本和函数内都是可见的。但以函数表达式定义函数则不同想要调用此定义的函数必须要引用它而要使用一个表达式方式定义的函数之前必须要把他赋值给一个变量前面说过变量的声明提前了但给变量赋值是不会提前的所以以表达式方式定义的函数在定义之前无法调用。如下代码 1 person(); /*函数声明语句显式提前至顶部所以能在定义之前调用*/
2 function person() {}
3 person(); /*在函数定义之后调用毋庸置疑正确*/ 1 p();
2
3 var p function(){
4
5 }
6
7 /*
8 打印出undefined is not a function 变量p还未初始化,因此函数定义表达式无法在函数定义之前调用
9 */ 函数调用 1作为函数 1 function person(age,name){
2
3 }
4
5 person(12,嘿嘿); /*函数调用*/ 2作为方法 1 var calculator {2 operator1 : 1,3 operator2 : 2,4 add: function(){5 this.result this.operator1 this.operator2;6 }7 8 };9
10 calculator.add(); //方法调用计算11的结果
11 calculator.result 2
12
13 /*
14 通过对象直接量来创建属性和方法此时calculator作为调用上下文所以this关键字则引用该对象
15 */ 3作为构造函数 1 var o new Object();
2
3 var o new Obejct;
4
5 /*
6 构造函数调用创建一个新的空对象这个对象继承自构造函数的prototype属性。构造函数试图初始化这个新创建的对象并将这个对象用做其调用上下文因此构造函数可以使用this关键字来引用这个新创建的对象
7 */ 【注】如果构造函数没有形参JavaScript构造函数调用的语法是允许省略实参列表和圆括号的。所以凡是没有形参的构造函数调用都可以省略圆括号。 4通过它们的call()和apply方法间接调用 【后面讲】 this关键字 this是 一个关键字不是变量也不是属性名。JavaScript的语法不允许给this赋值。和变量不同关键字this没有作用域的限制嵌套的函数不会从调用它的函数中继承this。对此我们用实例说明 1 var o {2 m: function() {3 var self this;4 console.log(this o); 15 f();6 7 function() {8 console.log(this o); 29 console.log(self o); 3
10 }
11 }
12 }
13
14 /*
15 上述1中打印出true,因为this就指代o。2中输出false,此时this是全局对象或undined。3输出true,self指代外部函数的this值
16 */ 综上所知 1如果嵌套函数作为方法调用其this的值指向调用它的对象。 2如果嵌套函数做为函数调用其this值不是全局对象非严格模式下就是undefined严格模式下。 3如果想访问外部函数的this的值需要将this的值保存在一个变量里这个变量和内部函数都同在一个作用域内。通常使用变量self来保存this。 作为命名空间的函数 引入 当有一段JavaScript模块代码这段代码将要用在不同的JavaScript程序中对于客户端JavaScript来讲通常是用在各种各样的网页中。假如这段代码定义了一个用以存储中间计算结果的变量。如此就出现一个问题当模块代码放在不同的程序中时你无法得知这个变量是否已经建好如果已经存在这个变量那么将会和代码发生冲突。解决办法就是将代码放入一个函数内然后调用这个函数。这样全局变量就变成了函数内的局部变量。用匿名函数来定义用法如下 1 (function(){ //模块代码中所使用的变量都是局部变量
2 console.log(12) 1
3 }()); //结束函数定义并立即调用它
4
5 或者
6
7 (function(){
8 console.log(12); 2
9 })(); 这里有个疑问尚未解决如果有园友知道希望能帮助我解决谢谢不知道大家注意到上述两个匿名函数的不同之处对在1中输出的最后没有加分号若加分号则错误无法输出不加分号则正常输出2中则是好使的希望得到各位园友的帮助在此表示感谢 这种定义匿名函数并立即在单个表达式中调用它的写法很常见如代码检测中是否出现了一个bug如果出现这个bug就返回一个带补丁的函数的版本 函数属性、方法 1length属性 length到没什么可说的最主要是要属函数的arguments的属性了在函数体内arguments.length表示传入函数的实参的 个数以此来模拟函数重载。请看下面代码 1 function person(age, name, gender, addr) {2 this.age age;3 this.name name;4 this.gender gender;5 this.addr addr;6 /*获得传入实参的个数*/ 7 switch(arguments.length)8 {9 case 1: //
10 break;
11 case 2: //
12 break;
13 case 3: //
14 break;
15 case 4: //
16 break;
17 }
18 }
19
20 var p new person(1,嘿嘿);
21 var p1 new person(1,嘿嘿,false);
22 var p2 new person(1,嘿嘿,false,hunan);
23
24 补充arguments的callee属性 引入 1 var factorial function(x) {
2 if (x 1) return 1;
3 return x * factorial(x - 1);
4 }
5 console.log(factorial(5));
6 /*打印出120*/ 上述代码为求一个数的阶乘毫无疑问没有错误。现在进行一点小改动如下 1 var factorial function(x) {
2 if (x 1) return 1;
3 return x * factorial(x - 1);
4 }
5 var fact2 factorial;
6 factorial function() { 7 return 0; 8 } 9 console.log(fact2(5)); 上述很明显fact2变量指向两个函数当要求调用fact2(5)时先执行 第一个 factorial函数当执行到 return x * factorial(x - 1); 时这时执行的就是 第二个 factorial函数所以此时打印出0。很显然这不是我们想要的结果我们需要的是求阶乘即执行的函数接下来还是它本身也就是第一个所以这个时候callee()方法就派上了用场用于调用自身。所以上述代码这样修改即可 1 var factorial function(x) {
2 if (x 1) return 1;
3 return x * arguments.callee(x - 1);
4 }
5 var fact2 factorial;
6 factorial function() { 7 return 0; 8 } 9 console.log(fact2(5)); 【注】arguments还有一个长得相似callee的属性就是caller而在非严格模式下ECMAScript标准规范规定callee属性指代当前正在执行的函数。caller是非标准的但大多数浏览器都 实现了这个属性它指代当前正在执行的函数的函数。通过caller属性可以访问调用栈。而通过callee来进行递归调用自身因为它保存了当前执行方法的地址而不会出差错。 2 prototype属性 每个函数都包含一个prototype属性这个属性指向一个对象的引用这个对象叫做原型对象。每一个函数都包含不同的原型对象。当将函数用做构造函数的时候新创建的对象会从原型对象上继承属性。有关原型对象前面已讲请参考原型、继承这一讲 3call()和apply()方法 这两种方法可以用来间接地调用函数两个方法都允许显式指定调用所需的this的值任何函数可以作为任何对象的方法来调用哪怕这个函数不是那个对象的方法。两个方法都可以指定调用的实参。call()方法使用它自有的实参列表作为函数的实参apply()方法则要求以数组的形式传入参数。在ECMAScript5的严格模式中call()和apply()的第一个实参都会变为this的值哪怕传入的实参是原始值甚至是null或undifined。在ECMAScript3和非严格模式中传入的null和undefined都会被全局对象代替而其他原始值则会被相应的包装对象所替代。 下面用代码来解释上述概念 1call()方法 1 function person(age,name){2 this.ageage;3 this.namename;4 }5 6 var objnew Object();7 person.call(obj,12,小黑);8 console.log(obj.age);9 console.log(obj.name);
10
11 /*
12 创建空对象obj此时调用person类的call()方法并将obj传递进去此时obj成为其调用上下文此时this即obj最终能打印出12和小黑
13 */ 2apply()方法 更多用法请参考:apply()详情 3bind()方法 bind()是在ECMAScript5中新增的方法但在ECMASript3中可以轻易模拟bind()从名字可以看出这个方法的主要作用就是将函数绑定至某个对象上。 1 function f(y){2 return this.x y;3 }4 var o { x : 1 };5 var g f.bind(o);6 console.log(g(2));7 8 function bind(f,o){9 if(f.bind) return f.bind(o);
10 else return function(){
11 return f.apply(o, arguments);
12 };
13 } 上述将函数f绑定至对象o上当在函数f()上调用bind()方法并传入一个对象o作为参数这个方法将返回一个新的函数。调用新的函数将会把原始的函数f()当做o的方法来调用。传入新函数的任何实参都将传入原始函数。上述中 f.bind(o); 则此时函数f()中的this即为o此时this.x1绑定后返回新的函数g再调用函数g(2),此时函数f()即为其参数所以打印出3。 函数传参 1传递原始类型所谓c#中的值类型 1 function person(age){
2 age;
3 }
4 var age 12;
5 person(age);
6 console.log(age); 根据上述代码你觉得会打印出多少呢我们一句一句分析 1var age 12栈上开辟一段空间地址假设为0x1,此时0x1存的是变量age并且其值为12。 2person(age)调用函数person并将实参传进去此时person中的形参相当于是局部变量所以同样在栈上开辟一段空间地址为0x2变量为age,将上述1中的值赋给2中的age所以同样为12然后进入函数体内将age,此时相加的是新创建的局部变量的值并未改变1中的age值。 3综上打印出12。 2传递对象所谓c#中的引用类型 1 function person(p){
2 p.age;
3 }
4 var p { age : 12 };
5 person(p);
6 console.log(p.age); 同理进行分析 1 var p { age : 12 }首先在栈上开辟一段空间地址为0x1值为null然后右边在堆上首先开辟一段空间地址为0x2的空对象然后定义属性age并且其值为12并且此对象指向变量p所以此时变量的值为0x2。 2person(p)同样p此时相当于是person类的局部变量首先在栈上开辟一段空间地址为ox3名字为p的变量此时将(1)中p的存的值0x2赋给0x3中p的值所以此时0x3中的值为0x2也就是此时ox2指向了堆上那个地址为0x2,属性为age值为12的对象。然后进入函数体内部对其年龄进行age此时堆上对象的属性age变为13。 3综上此时打印出的P中的age为13。 总结传参 无论是传递原始类型值类型还是对象引用类型只需要看栈上变量的值是存的值还是地址若存的是值则相当于复制一份即副本不会改变原来的值若是变量的值存的是地址若在函数体内改变值则原来对象中的值也会受影响。 转载于:https://www.cnblogs.com/CreateMyself/p/4692357.html