js函数总结
2016-02-22 10:02
591 查看
1.函数声明提升
函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分。<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>函数声明提升</title> </head> <body> <script type="text/javascript"> fn();//我是函数声明 var fn=function(){ console.log("我是函数表达式"); }; function fn(){ console.log("我是函数声明"); } fn();//我是函数表达式 /* 实际执行顺序: var fn; function fn(){ console.log("我是函数声明"); } fn();//我是函数声明 fn=function(){ console.log("我是函数表达式"); }; fn();//我是函数表达式 */ /* 函数表达式最大的问题,在于js会将此代码拆分为两行代码分别执行。 所以函数声明覆盖了变量声明 */ </script> </body> </html> <pre name="code" class="html">//封装函数 //1、传统方式封装 //该方式允许封装的函数"先调用,后声明",该过程称为函数的"预加载" //预加载:程序代码没有执行之前,函数的声明先进入内存 //表面上是函数调用在前、函数声明在后,本质上是函数声明在前、调用在后 //预加载条件:"声明和调用"必须在同一个script标记里面 //原因是每个script标记是独立加载、解释和运行的 //getInfo();//也可以成功调用 function getInfo(){ console.log('beijing'); } getInfo(); //js中一切都是对象 //函数也是对象(数据类型的一种) //2、变量赋值方式声明函数,就是函数表达式(不支持函数预加载) //getWeather();//TypeError: getWeather is not a function var getWeather=function(){ console.log('晴朗'); } getWeather();//晴朗
2.函数-callee
arguments.callee是一个指向正在执行的函数的指针function jisuan(n){ if(n<=1){ return 1; }else{ //return n*jisuan(n-1);//TypeError: jisuan is not a function return n*arguments.callee(n-1); } } var js=jisuan; jisuan=null; console.log(js(5));//120
3.caller属性
caller属性保存着调用当前函数的函数引用<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>caller属性</title> </head> <body> <script type="text/javascript"> function outer(){ inner(); } function inner(){ //inner.caller指向outer console.log(inner.caller);// outer() //alert(inner.caller);//显示outer函数的源代码 //这样写实现了更松散的耦合 alert(arguments.callee.caller);//显示outer函数的源代码 } outer(); </script> </body> </html>
4.匿名函数自执行
//变量赋值声明一个函数 var getInfo=function(){ console.log("Today is sunshine"); } //var getInfo="okok";//使用一个同名的getInfo变量把上面的函数给污染覆盖 getInfo();//Today is sunshine //使得以下匿名函数发生执行 //特点:程序代码没有停顿,立即执行 //好处:可以避免变量污染 (function(){ console.log("I am no name function"); })();//I am no name function
5.arguments
arguments属性是一个类数组对象,保存着传入函数的所有参数,主要用途就是保存函数参数arguments有一个callee属性,该属性是一个指针,指向拥有arguments属性的函数
//arguments关键字 在函数内部可以接受传递进来的实参 //可以通过数字下标形式来访问各个实参信息 //其length属性可以获得实参个数 function getInfo(){ var num=arguments.length; //根据传递参数的个数做灵活处理 if(num==0){ console.log('个人信息'); }else if(num==1){ console.log('名字:'+arguments[0]); }else if(num==2){ console.log('名字:'+arguments[0]+' age:'+arguments[1]); }else if(num==3){ console.log('名字:'+arguments[0]+' age:'+arguments[1]+' job:'+arguments[2]); } //console.log('名字:'+arguments[0]+' age:'+arguments[1]+' job:'+arguments[2]); //console.log(arguments); } //同一个函数调用的时候,由于传递不同个数的实参,最终导致的结果也不一样 //其实是模仿方法重载(定义了许多名称一致的方法,这些方法的参数个数或者参数类型不一样 //这些方法就构成了重载) //在php和js中没有重载 // //重写:子类的同名方法去覆盖父类的同名方法 //重载:一个类里面有许多同名的方法 getInfo(); getInfo('liujie'); getInfo('liujie',23); getInfo('liujie',23,'student');
6.apply和call
apply()和call()方法。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply()方法接收两个参数:一是在其中运行函数的作用域;二是参数数组。第二个参数可以是Array的实例,也可以是arguments对象。
apply()和call()方法的作用相同,它们的区别仅在于接收参数的方式不同。对于call()方法而言,第一个参数this值没有变化,变化的是其余参数都是直接传递给函数,参数必须逐个列举出来。
第一个参数传null或undefined时,将是JS执行环境的全局变量。浏览器中是window,其它环境(如node)则是global。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>apply和call</title> </head> <body> <script type="text/javascript"> /*apply()和call()方法真正强大的地方是能够扩充函数赖以运行的作用域 */ var color="red"; var o={color:"blue"}; function sayColor(){//全局函数 console.log(this.color); } sayColor();//red //这里在全局环境调用,this.color会转化为window.color sayColor.call(this);//red 显示的在全局作用域中调用函数 sayColor.call(window);//red 显示的在全局作用域中调用函数 sayColor.call(o);//blue 使用call()方法将函数内部的this指向了对象o </script> </body> </html>
7.bind方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>bind方法</title> </head> <body> <script type="text/javascript"> /* bind方法的主要作用是将函数绑定至某个对象 */ function f(y){//待绑定的函数 return this.x+y; } var o={x:1};//将要绑定的对象 var g=f.bind(o);//通过调用g(x)来调用o.f(x) console.log(g(2));//3 var color="red"; var o={color:"blue"}; function sayColor(){ console.log(this.color);//blue } var objectSayColor=sayColor.bind(o); //sayColor()调用bind()并传入对象o,创建了objectSayColor()函数 //objectSayColor()函数的this值等于o objectSayColor(); </script> </body> </html>
8.私有变量
/* 任何在函数中定义的变量,都成为私有变量,因为在函数外部无法访问它们 私有变量包括:函数参数、局部变量以及函数内部定义的其他函数 */ function Person(name){ //在构造函数内部定义了两个特权方法:getName()和setName()。这两个方法都可以在构造函数外部使用,而且都有权访问私有变量name this.getName=function(){ return name; }; this.setName=function(value){ name=value; }; } var person1=new Person("liujie"); console.log(person1.getName());//liujie person1.setName("liujiejie"); console.log(person1.getName());//liujiejie
9.块级作用域
function outputNumbers(count){ //由于JS中没有块级作用域,所以这里的i实际是在包含函数outputNumbers创建的,而不是在块语句中创建的 //在java、C++等语言中,变量i只会在for循环的块语句中有定义,循环一旦结束,变量i就会被销毁 //而在js中,变量i是定义在outputNumbers()函数的活动对象中的,因此,从它开始有定义起,就可以在函数内部随处访问它 for(var i=0;i<count;i++){ console.log(i);//0、1、2、3、4 } console.log("块语句外:"+i);//5 } outputNumbers(5);
10.模仿块级作用域
/* 匿名函数可以用来模仿块级作用域 (function(){ //这里是块级作用域,通常称为私有作用域 //将函数声明放在圆括号中表名它是一个表达式 })(); */ function outputNumbers(count){ (function(){ //这里在for循环的外部插入了一个私有作用域,在匿名函数中定义的任何变量,都会在执行结束时被销毁。因此,变量i只能在循环中使用,使用后即被销毁。 for(var i=0;i<count;i++){ console.log(i);//0、1、2、3、4 } })(); console.log(i);//ReferenceError: i is not defined } outputNumbers(5);
11.静态方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>静态方法</title> </head> <body> <script type="text/javascript"> function Person(name){ this.name=name; this.sayName=function(){ console.log(this.name); } } Person.sayAge=function(){//静态方法 console.log(1); }; var person1=new Person('lisi'); person1.sayName();//lisi Person.sayAge();//1 </script> </body> </html>
静态方法可以通过构造函数名来调用
12.用apply改变函数作用域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>用apply改变函数作用域</title> </head> <body> <script type="text/javascript"> /* apply、call、bind都有个作用就是改变作用域,这里用apply将foo函数的作用域指向obj对象,同时传入参数。 再简单分析一下bind函数内部的嵌套,执行bind函数的时候返回的是一个匿名函数,所以执行bar(3)的时候实际上是执行的bind内部的匿名函数,返回的是之前传入的foo函数的执行结果。 函数没有返回值的情况下默认返回undefined。 */ function foo(somthing){ console.log("一:"+this.a, somthing);//一:2 3 } function bind(fn, obj){ return function(){ return fn.apply(obj, arguments); } } var obj = { a:2 } var bar = bind(foo, obj);//foo中的this指向了obj /* bar=function(){ return fn.apply(obj, arguments); } */ var b = bar(3); console.log("二:"+b);//二:undefined </script> </body> </html>
相关文章推荐
- 理解js中的自由变量以及作用域的进阶
- bzoj1013: [JSOI2008]球形空间产生器
- Python和JavaScript间代码转换的4个工具
- Js的Array数组对象详解
- JavaScript兼容问题汇总[实时更新]
- JS将JSON字符串转换为JSON对象
- js 检测输入框变更
- js实现手机号码和身份证号码校验
- JS冒泡和闭包案例分析
- JS字符串的切分用法实例
- JS实现上下左右对称的九九乘法表
- 基于Javascript实现倒计时功能
- MVC Controller return 格式之JsonResult、ContentResult、RedirectResult……
- [Immutable.js] Converting Immutable.js Structures to Javascript and other Immutable Types
- [Immutable.js] Transforming Immutable Data with Reduce
- 【js】页面刷新
- JavaScript多线程
- HTML5-CSS3-JavaScript(1)
- Python和JavaScript间代码互转的4个工具
- 基于Javascript实现倒计时功能