第七章 函数表达式和函数声明,关于this对象 ,私有作用域(function(){})() ,私有变量和特权方法

一:函数表达式和函数声明

1:函数声明和函数表达式的区别

①函数声明不需要分号结尾

②函数声明有函数提升的特点

③函数声明后面不能跟圆括号直接调用,因为javascript将function关键字当作一个函数声明的开始,而函数声明后面不能跟圆括号!

2:匿名函数的作用

①作为值使用

function sum(num1,num2){
      return function(num1,num2){
           return  num1+num2;
    }  
}

3:闭包

概念:是指有权访问另一个函数作用域中的变量的函数。(通过在一个函数内部创建另一个函数得到闭包)

①当一个函数被调用时,会创建一个执行环境和相应的作用域链,使用arguments和其他命名参数的值来初始化函数的活动对象。外部函数的活动对象在作用域链中处于次位。

function compare(value1,value2){
        if(value<value2){
                return -1;  
}  else if(value1>value2){
                return 1;
}  else {
                return 0;
}
}

//调用compare()时,会创建一个包含arguments,value1和value2的活动对象。全局执行环境的变量对象(包括result和compare)在compare()执行环境的作用域链中处于第二位。

③后台的每个执行环境中都有一个变量对象。全局对象一直存在,像compare()函数这样的局部环境的变量对象,则只在函数执行的过程中存在。

作用域链本质上事一个指向变量对象的指针列表,它只引用但不实际包含变量对象。

④而闭包———在create()函数内部定义的匿名函数的作用域链中,实际上将会包含外部函数create()的活动对象。

var create1 = create("name");
var result = carete1({name:"Wang"},{name:"Lee"});

//函数create中有匿名函数

在函数create执行完之后,因为匿名函数的作用域链依旧在引用这个活动对象,所以它的活动对象不会被销毁。(但create()执行完后create()的作用域链被销毁)

通过

create1 = null;

销毁匿名函数的作用域链。


二.关于this对象(易出错)

1:匿名函数的执行环境具有全局性,因此this对象通常指向window。但是由于闭包的写法因此并不明显

        var name = "global";

        var object = {
                name : "part",
                getName : function(){
                return function(){
                        return this.name;
                }
            }
        };

        alert(object.getName()());
//global

2:每个函数在被调用的时候会自动取得两个特殊变量:this和arguements。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不会直接访问外部函数中的这两个变量。

   需要把this保存在变量中才能让闭包访问到。

        var name = "The Window";

        var object = {
            name : "My object",
            getName : function(){
                var that = this;
                return function(){
                    return that.name;
                };
            }
        };
    
     alert(object.getName()());
        
     //My object

三.私有作用域

  用作私有作用域(块级作用域)的语法如下:

  (function(){

        //这里是块级作用域

  })();

  这种技术经常在全局作用域中用在函数外部,从而限制向全局作用域中添加过多的变量和函数。比如

  (function(){

        var now = new Date();
            if(now.getMonth()==0&&now.getDate()==1){
               alert("Happy");
      }    
  })();

//这段代码在1月1日的时候显示祝贺新年的消息

四.私有变量和特权方法 

①私有变量:在函数内部定义的变量

②特权方法:有权访问私有变量和私有函数的公有方法称为特权方法(利用闭包实现)

    function PP(name) {
        this.getName : function(){
            return name;
        }
    }

    var ppp = new PP("hehe");
    alert(ppp.getName());

③通过getName()方法访问私有变量name,但是这种写法有个缺点:必需使用构造函数模式来完成。——其他创建私有变量和特权方法的模式见书,暂时不深入

   

原文地址:https://www.cnblogs.com/cndotabestdota/p/5715426.html