• JavaScript学习——函数表达式


    function fuctionName(arg0,arg1,arg2){
    //函数体
    }

    不要这样做

    if(condition)
    function sayHi(){
    alert("Hi");
    }
    else{
    function sayHi(){
    alert("Yo");
    }
    }

    ECMAScript中属于无效语句。

    可以这样做

    var sayHi;
    if(condition){
    sayHi=function(){
    alert("Hi");
    };
    }
    else{
    sayHi=function(){
    alert("Yo");
    };
    }

    1.递归

    function factorial(num){
    if(num<=1){
    return 1;
    }
    else{
    return num*arguments.callee(num-1);
    }
    }

    但在严格模式无法使用arguments.callee,可以这样做

    var factorial = (function f(num){
    if(num<=1){
    return 1;
    }else{
    return num*f(num-1);
    }
    });

    这种方式在严格非严格都行得通。

    2.闭包

    闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式就是在一个函数内部创建另一个函数

    function createComparisonFunction(propertyName){
    return function(object1,object2){
    var value1=object1[propertyName];
    var value2=object2[propertyName];
    if(value1<value2)
    {
    return -1;
    }
    else if(value1>value2)
    {
    
    return 1;
    }
    else{
    return 0;
    }
    };
    }

    2.1闭包与变量

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

    每个函数都返回10,因为每个函数的作用域链中都草村这createFunctions()函数的活动对象,所以他们引用的都是同一个变量i。当createFunctions()函数返回后,变量i的值是10,此时每个函数都引用着保存变量i的同一个变量对象,所以都是10。我们可以通过创建另一个匿名函数强制让闭包的行为符合预期

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

     2.this对象

    在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。不过匿名函数的执行具有全局性,因此其this对象通常只想window,但有时由于编写闭包的方式不同,这一点可能不会那么明显。

    var name="The Window";
    var object={
    name:"My Object";
    getNameFunc:function(){
    return fuction(){
    return this.name;
    };
    }
    };
    alert(object.getNameFunc()());//"The Window"

    由于代码创建了一个全局变量name,有创建了一个包含name属性的对象。这个对象还包含一个方法getNameFunc(),它返回一个匿名函数,而匿名函数又返回this.name。由于getNameFunc()返回一个函数,因此调用object.getNameFunc()()就会立即调用它并返回函数。每个函数在被调用时都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。不过,把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问对象。

    var name="The Window";
    var object={
    name:"My Object";
    getNameFunc:function(){
    var that=this;
    return fuction(){
    return that.name;
    };
    }
    };
    alert(object.getNameFunc()());//"My Object"

    2.3内存泄漏

    如果闭包作用域链中保存着一个HTML元素,那么就意味着该元素将无法被销毁。

    function assignHandler(){
    var element=document.getElementById("someElement");
    element.onclick=function(){
    alert(element.id);
    };
    }

    以上代码创建了一个作为element元素事件处理程序的闭包,而这个闭包则又创建了一个循环引用。由于匿名函数保存了一个对assignHandler()的活动对象的引用,因此就会导致无法减少element的引用数。只要匿名函数存在,element的引用数至少也是1,因此占用的内存就永远不会被回收。

    function assignHandler(){
    var element=document.getElementById("someElement");
    var id=elemt.id;
    element.onclick=function(){
    alert(id);
    };
    element=null;
    }

    3.模仿块级作用域

    JavaScript从来不会告诉你是否多次声明了用一个变量,遇到这种情况,它只会对后续的声明视而不见(不过,它会执行后续声明中的变量初始化。)匿名函数可以用来模仿块级作用域并避免这个问题。

    用作块级作用域(私有作用域)的匿名函数的语法如下

    (function()){
    //这里是块级作用域
    })();
    function outputNumbers(count){
    (function(){
    for (var i=0;i<count;i++){
    alert(i);
    }
    })();
    alert(i)//错误!
    }

    因为在匿名函数中定义任何变量,都会在执行结束时被销毁。

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

    这段代码可以确定那一天是1月1日,如果到了这一天,就会向用户祝贺新年的消息。其中now现在是匿名函数中的局部变量,而我们不必在全局作用域中创建它。

    4.私有变量

    严格来讲,JavaScript中没有私有成员的概念;所有对象属性都是公有的。不过,倒是有一个私有变量的概念。任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。私有变量包括函数的参数、局部变量和在函数内定义的其他函数。

    我们把有权访问私有变量和私有函数的公有方法称为特权方法。

    function MyObject(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
    return false;
    }
    //特权方法
    this.publicMethod = function(){
    privateVariable++;
    return privateFunction();
    };
    }

     这个模式在构造函数内部定义了所有私有变量和函数。然后,又继续创建了能够访问这些私有成员的特权方法。

    利用私有和特权成员,可以隐藏那些不应该被直接修改的数据

    function Person(name){
    this.getName=function(){
    return name;
    };
    this.setName = function(value){
    name=value;
    };
    }
    var person = new Person("Nicholas");
    alert(person.getName());//"Nicholas"
    person.setName("Greg");
    alert(person.getName());//"Greg"

    setName和getName都是特权方法,但优缺点,就是必须使用构造函数模式来达到这个目的,构造函数模式的缺点就是针对每个实例都会创建同样一组新方法,而使用静态私有变量来实现特权方法可以解决。

    4.1静态私有变量

    (function(){
    //私有变量和私有函数
    var privateVariable=10;
    function privateFunction(){
    return false;
    }
    //构造函数
    MyObject =function(){
    };
    //公有/特权方法
    MyObject.prototype.publicMethod=function(){
    privateVariable++;
    return privateFunction();
    };
    })();

    这个模式创建了一个私有作用域,并在其中封装了一个构造函数及相应的方法。

    (function(){
    var name="";
    Person=function(value){
    name = value;
    };
    Person.prototype.getName=function(){
    return name;};
    Person.prototype.setName=function(value){
    name=value;
    };
    })();
    var person1=new Person("Nicholas");
    alert(person1.getName());//"Nicholas"
    person1.setName("Greg");
    alert(person1.getName());//"Greg"

    4.2模块方式

    前面的模式是用于为自定义类型创建私有变量和特权方法的。而道格拉斯所说的模块模式则是为单例创建私有变量和特权方法。所谓单例(singleton),指的就是只有一个实例对象。

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

    模块模式通过为单例添加私有变量和特权方法能够使其得到增强

    var singleton=function(){
    //私有变量和私有函数
    var privateVariable=10;
    function privateVariable(){
    return false;
    }
    //特权/公有方法和属性
    return{
    publicProperty:true,
    publicMethod:fucntion(){
    privateVariable++;
    return privateFunction();
    }
    };
    }();

    4.3增强的模块模式

    var singleton=function(){
    //私有变量和私有函数
    var pribateVariable=10;
    function privateFunction(){
    return fasle;
    }
    //创建对象
    var object=new CustomType();
    //添加特权/公有属性和方法
    object.publicProperty=true;
    object.publicMethod=function(){
    privateVariable++;
    return privateFunction();
    };
    //返回对象
    return object;
    }();
  • 相关阅读:
    w10更新
    java.lang.Integer cannot be cast to java.math.BigDecimal
    加法add 乘法multiply
    iterator,hasNext,next
    购物车全部数据,带商品信息
    ERRORinit datasource error, url: jdbc:mysql://localhost:3306/xxxxxx?useUnicode=true&characterEncoding=gbk&serverTimezone=GMT&useSSL=false
    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:
    创建一个场景
    window系统已发布,等待更新
    [转]向量(矩阵)范式理解(0范式,1范式,2范式,无穷范式)
  • 原文地址:https://www.cnblogs.com/pilee/p/3447640.html
Copyright © 2020-2023  润新知