高程7-函数 表达式

1.定义函数的两种方法:

1.函数声明
function functionName(arg0,arg1){
}
特点:函数预解析,代码执行的时候,可以先调用后执行,因为预解析;

a()

function a() {

console.log("s")

};



2.函数表达式
var functionName=function(arg0,arg1){
}
特点:创建的函数是匿名函数,函数名子是空字符串;与定义变量一样,

a()
var a=function (){
console.log("123");
}           // Uncaught TypeError: a is not a function at



不要在if代码体中定义函数

2. 递归

function factorial(num){
          if(num<=1){
            return 1;
        }else{
           return num*factorial(num-1)       //也可以换成 return num*argument.callee(num-1);
} }

这里argument.callee(num-1)指的是正在执行的函数,使用argument.callee代替函数名,可以确保无论怎么样调用的函数都不会出问题,因此,在编写递归函数时,使用argument.callee比函数名可靠;

严格模式:
var fac=(function f(num){
if (num<=1){
return
}else{
return num* f(num-1)
}
)
严格模式,不能通过脚本访问argument.callee,访问这个属性会导致错误,不过,可以使用命名函数表达式来、

3.闭包

有权访问另一个作用域中变量的函数

1.闭包与变量

 

function createFunction(){
              var result=new Array();
              
               for(var i=0;i<10;i++){
               result[i]=function(){
                   return i;
           }
     }
     return result;
}

var a=createFunction()[0]();
console.log(a);           //10,预想的是0;为什么是10,定义函数其实只是定义了一个,地址,其内容只是字符串,真正调用的时候,i没有在当前作用于找到变量,就会去他的父作用域寻找,等找的时候for()循环已经结束,i=10;所以全都是10;

解决办法:自执行函数

function createFunction(){
      var result=new Array();
      for(var i=0;i<10;i++){
          result[i]=(function(){
                      return i;
                    })();
           }
            return result;
}

var a=createFunction();
console.log(a);          // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 每一次赋值的函数都执行一次;

 4.this

 1.全局函数中,this等于window,

var x=2;
function test(){
     var x=1;
    alert(this.x)
}
test()      //2

2.作为对象调用时,指向上一级对象

var x=2;
function test(){
     var x=1;
    alert(this.x)
}
var o={x:100,f:test};
o.f()         //100

3.构造函数,指向实例

var x=2;
function Test(){
    var obj=new Object;
    obj.name="xiaomi";
    obj.f=function() {
        alert(this.name);
    }
    return obj;
}
var t=new Test;
t.f()     //“xiaomi”

4.appli/call/bind 顶包,指向赋予的新作用域

var x=0;
function test() {
    alert(this.x)
}
var obj={x:100}
test.call(obj);        //100 call()空值,则指向全局window

5.内存泄漏

function test(){
        var element=document.getElementById("box");
        element.onclick=function () {
            alert(element.id);
        }
}
test()    //以上代码创建了一个作为element元素事件处理程序的闭包,而闭包又创建了循环引用,只要点击调用,就会应用element元素,因此他的内存占用永远无法被收回;

改版后

function test(){
        var element=document.getElementById("box");
        var id=element.id;  //需要的数据保存在变量中
        element.onclick=function () {
            alert(id);       //每次调用变量
        }
        element=null;         //变量设置为空,告诉浏览器没事给他收回去
}
test()

6.模仿块级作用域

js没有块级作用域概念

function test(){
   for(var i=0;i<6;i++){
       alert(i)//0,1,2,3,4,5
   }
   alert(i);   //6      如果for是一个块,下面的alert()就访问不到i;
}
test()

js 变量赋值的懒惰

function test(){
   for(var i=0;i<6;i++){
       alert(i)
   }
    var i;
    alert(i); //犹豫他很懒,知道有i变量,没不会重复声明,如果赋值了就不一样了;

  }
test()
(function(){
    //我是块级作用域
})()

var someFunction=function(){
//我也是块级作用域
}

7.私有变量

严格讲,js没有私有成员的概念,所有对象属性都是公有的。不过,倒是有一个私有变量的概念,任何函数中的定义的变量,都可以认为是私有变量,因此不能在函数的外部访问这些变量。

 8.单例模式

var singleton={
    name:value,
    method:function () {
        // 这里是方法
    }
}

模式通过为单例添加私有变量和特权方法能够使其得到增强,其语法形式如下:

原文地址:https://www.cnblogs.com/liangfc/p/7835315.html