JavaScript疑难点
阅读原文时间:2023年07月08日阅读:3

什么是闭包

  • 我个人理解闭包就是函数中嵌套函数,但是嵌套的那个函数必须是返回值,才构成闭包;

    //标准的闭包
    function fn(){
           var i=1;
            return  function fnn(){
                    i++;
                    return i;
                }
            }
    $('#btn').click(function(){
            var fun=fn();
            console.log(fun());//2
            console.log(fun());//3
    });

闭包的用途

  • 让外部可以读取到函数内部的变量
  • 让这些变量的值始终保存的内存中(所以要尽量少使用闭包)

思考题:

<script>
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
        alert(object.getNameFunc()());
</script>
<script>
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  }; 
         alert(object.getNameFunc()());
</script>
 //第一题结果是the windos
 //第二题结果是the object

创建对象

    //通过object创建对象
     var person =new Object();
     person.name='wj';
     person.job='c#.net';
     person.fn=function(){
         console.log(this.name+this.job);
     };
    // person.fn();
    //通过字面量创建对象
    var conmpany={
        name:"fanyaunwang",
        salary:"6500",
        fn:function(){
            console.log(this.name+this.salary);
        }
    };
    //conmpany.fn();
    //以上2种方式创建对象,会产生大量的重复代码

    //通过工厂模式创建对象
    // 工厂模式减少了代码重复,但是不能识别对象,所有的实例都是object类型
    function createObject(name,age,job)
    {
        var o = new Object();
        o.name=name;
        o.age=age;
        o.job=job;
        o.fn=function(){
            console.log(this.name+this.job+this.age);
        }
        return o;
    }

    //var wj=createObject('wj','22','c#.net');
    //wj.fn();

    //通过构造函数创建对象
    //构造函数中首字母大写,而非构造函数首字母小写作为区别

    function CreatePerson(name,age,job)
    {
        this.name=name;
        this.age=age;
        this.job=job;
        this.fn=function(){
            console.log(this.name+this.age+this.job);
        }
    }
    //通过new来创建CreatePerson实例,这样创建的实例都有一个constractor
    //属性指向CreatePerson
    //通过工厂模式创建的对象都是object,无法判读对象的类型,
    //但是通过构造函数创建的对象可以,这是构造函数创建对象胜过
    //通过工厂模式创建对象的地方
    var obi=new CreatePerson('wangjun','23','c#.net');
    obi.fn();
    console.log(obi.constructor==CreatePerson);//true

    //通过原型模式来创建对象
    //原型模式就是在构造函数中吧方法拿出来的基础上,在做了一层封装

    function Employee(){
    }
    Employee.prototype.name='wangjun';
    Employee.prototype.age='c#';
    Employee.prototype.fn=function(){
        console.log(this.name+this.age);
    }
    var emp=new Employee();
    var emp1=new Employee();
    emp.fn();
    emp1.fn();
    //这个fn是公共的
    console.log(emp.fn()==emp1.fn());//true
    //在构造函数创建对象的模式中是false

    //构造函数和原型混合模式
    //创建自定义类型的最常见方式
    //构造函数模式用于定义实例属性,
    //原型模式用于定义公共属性

    function Customer(name,address)
    {
        this.name=name;
        this.address=address;
        this.phone=['13946','44848484'];
    }
    Customer.prototype={
        constructor:Customer,
        p:['af','sfasf'],
        fnn:function(){
            console.log(this.name+'prototype');
        }
    }
    var objc= new Customer('fanyuanwang','shenzheng');
    var obje=new Customer('wangjin','changsha');
    console.log(objc.phone==obje.phone);//false
    //上面这个就是构造函数的引用类型的不同
    objc.fnn();
    console.log(objc.fnn==obje.fnn);//true
    objc.fnn();
});

格式化时间

  function getnowtime() {
            var nowtime = new Date();
            var year = nowtime.getFullYear();
            var month = padleft0(nowtime.getMonth() + 1);
            var day = padleft0(nowtime.getDate());
            var hour = padleft0(nowtime.getHours());
            var minute = padleft0(nowtime.getMinutes());
            var second = padleft0(nowtime.getSeconds());
            var millisecond = nowtime.getMilliseconds(); millisecond = millisecond.toString().length == 1 ? "00" + millisecond : millisecond.toString().length == 2 ? "0" + millisecond : millisecond;
            return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second + "." + millisecond;
        }
        //补齐两位数
        function padleft0(obj) {
            return obj.toString().replace(/^[0-9]{1}$/, "0" + obj);
        }