zoukankan      html  css  js  c++  java
  • JavaScript学习----初步

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>JavaScript Study 2015.11.9--</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style type="text/css">  
    
        </style>
        
        <script type="text/javascript">
        
         //JavaScript = ECMAScript(function,closure,OO) + DOM + BOM
        
            /*
            var sColor = "red";
            //alert(sColor.length);    //输出 "3"
            
            var bFound = false;
            //alert(bFound.toString());    //输出 "false"
    
            var iNum1 = parseInt("12345red");    //返回 12345
            var iNum1 = parseInt("red12345");  //返回 NaN
            //alert(iNum1);
            //alert(inum1); // error: inum1 is not defined
            var iNum1 = parseInt("0xA");    //返回 10
            var iNum1 = parseInt("56.9");    //返回 56
            var iNum1 = parseInt("red");    //返回 NaN
    
    
            //解析16进制的值, 第二个参数
            var iNum1 = parseInt("AF", 16);    //返回 175
            //alert(iNum1);
            //2进制
            var iNum1 = parseInt("10", 2);    //返回 2
            //8进制
            var iNum2 = parseInt("10", 8);    //返回 8
            //10进制
            var iNum3 = parseInt("10", 10);    //返回 10
            
            //如果10进制数,包含0作前导,最好使用第二个参数为10
            var iNum1 = parseInt("010");    //返回 8
            var iNum2 = parseInt("010", 8);    //返回 8
            var iNum3 = parseInt("010", 10);    //返回 10
    
            
            
            var b1 = Boolean("");        //false - 空字符串
            var b2 = Boolean("hello");        //true - 非空字符串
            var b1 = Boolean(50);        //true - 非零数字
            var b1 = Boolean(null);        //false - null
            var b1 = Boolean(0);        //false - 零
            var b1 = Boolean(new Object());    //true - 对象
    
            
            
            
            ECMAScript 中可用的 3 种强制类型转换如下:
            Boolean(value) - 把给定的值转换成 Boolean 型;
            Number(value) - 把给定的值转换成数字(可以是整数或浮点数);
            String(value) - 把给定的值转换成字符串;
            
            
            
            var b1 = Boolean("");        //false - 空字符串
            var b2 = Boolean("hello");        //true - 非空字符串
            var b3 = Boolean(50);        //true - 非零数字
            var b4 = Boolean(null);        //false - null
            var b5 = Boolean(0);        //false - 零
            var b6 = Boolean(new Object());    //true - 对象
            
            document.write(b1+"<br>");
            document.write(b2+"<br>");
            document.write(b3+"<br>");
            document.write(b4+"<br>");
            document.write(b5+"<br>");
            document.write(b6+"<br>");
            
            //特别注意
            document.write(Number(false)+"<br>");//    0  
            document.write(Number(true)+"<br>");//        1  
            document.write(Number(undefined)+"<br>");//        NaN  
            document.write(Number(null)    +"<br>");//    0
            document.write(Number("1.2")+"<br>");//        1.2
            document.write(Number("12")+"<br>");//        12
            document.write(Number("1.2.3")+"<br>");//        NaN
            document.write(Number(new Object())+"<br>");//        NaN
            document.write(Number(50)    +"<br>");//    50
    
            var s1 = String(null);    //"null"
            var oNull = null;
            var s2 = oNull.toString();    //会引发错误
            
            //两种方式都可以
            var obj = new Object;
            var obj1 = new Object();
            
            
            Object 对象具有下列属性:
            constructor
            对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。
            Prototype
            对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。
            Object 对象还具有几个方法:
            hasOwnProperty(property)
            判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty("name"))
            IsPrototypeOf(object)
            判断该对象是否为另一个对象的原型。
            PropertyIsEnumerable
            判断给定的属性是否可以用 for...in 语句进行枚举。
            ToString()
            返回对象的原始字符串表示。对于 Object 对象,ECMA-262 没有定义这个值,所以不同的 ECMAScript 实现具有不同的值。
            ValueOf()
            返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。
    */
    
    
            
            /*
            
            //函数
            
            function sayHi() {
              if (arguments[0] == "bye") {
                return;
              }
    
              alert(arguments[0]);
            }
    
            //下面的调用方式都不报错
            sayHi();
            sayHi("hehe");
    
            
            function howManyArgs() {
              alert(arguments.length);
            }
    
            howManyArgs("string", 45);
            howManyArgs();
            howManyArgs(12);
    
            
            
            //模拟函数重载
            function doAdd() {
              if(arguments.length == 1) {
                alert(arguments[0] + 5);
              } else if(arguments.length == 2) {
                alert(arguments[0] + arguments[1]);
              }
            }
    
            doAdd(10);    //输出 "15"
            doAdd(40, 20);    //输出 "60"
            
        
            
            function doAdd(){
              var j =0;
               for(var i=0;i<arguments.length;i++){
                j= j+ arguments[i];
               }
               alert(j); 
            }
            
            doAdd(20);
            doAdd(20,40);
    
    
                
                
            
            //函数的覆盖
            function doAdd(iNum) {
              alert(iNum + 20);
            }
    
            function doAdd(iNum) {
              alert(iNum + 10);
            }
    
            doAdd(10);    //输出 "20"
            
            var doAdd = new Function("iNum", "alert(iNum + 20)");
            var doAdd = new Function("iNum", "alert(iNum + 10)");
            doAdd(10);
    
        //画出内存结构
        function fn(){
            return 100;
        }
        //x 指向 fn 所指向的内存区域
        var x = fn;
        
        var y = fn();
        var z = x();
    
    
        //定义对象
      function Person(name,age,address){
           this.name = name;
           this.age = age;
           this.address = address;
           this.say = function(){
                alert(this.name+","+this.age+","+this.address);
           }
      }
      var p1 = new Person("p1",23,"bj");
      var p2 = new Person("p2",24,"nj");
      //存在的问题:
      //每创建一个对象p,都会在内存中有一份Person的say function拷贝,会导致内存空间的浪费。
      //而实际的对象的创建,应该是:每创建一个对象p,只会创建一个变量,指向内存中的say function的同一区域。
      //p1.say();
     // p2.say();
      
      
      
      //定义对象的方式1:
      function Person(name,age){
         this.name = name;
         this.age = age;
      }
      
      Person.prototype.say = function(){
        alert(this.name+","+this.age);
      }
      
      var p1 = new Person("p1",20);
      p1.say();
      var p2 = new Person("p2",21);
      p2.say();
      
     
      
      //定义对象的方式2:
     
     
     
     person = new Object();
     person.name = "li";
     person.age = 34;
     person.say= function(){alert(person.name);}
     
     person.say();
      
     //定义对象的方式3:
     
     person={
         name:"li",
         age:34,
         say:function(){
         alert(this.name);
         }
     }
     person.say();
     
      
      var person ={
        name:"li",
        age:34,
        say:function(){
            alert(this.name);
        }
      }
     
     for(x in person){
        alert(x);  // name,age,say
     }
     */
     
     
     
      
      
      
      
      /*
      //http://www.jb51.net/article/24101.htm
      //闭包
      闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量。
      //作用:
      一个是前面提到的可以读取函数内部的变量,
      另一个就是让这些变量的值始终保持在内存中。
      //什么时候使用:
       1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
       2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
       3、通过保护变量的安全实现JS私有属性和私有方法(不能被外部访问)
        私有属性和方法在Constructor外是无法被访问的
        function Constructor(...) {  
          var that = this;  
          var membername = value; 
          function membername(...) {...}
        }
        以上3点是闭包最基本的应用场景,很多经典案例都源于此。
    
    
     //这是一个最简单的闭包
     
     var sMessage = "hello closure";
     function sayHelloClosure(){
        alert(sMessage);
     }
    sayHelloClosure();
    //在上面这段代码中,脚本被载入内存后,并没有为函数 sayHelloWorld() 计算变量 sMessage 的值。
    //该函数捕获 sMessage 的值只是为了以后的使用,也就是说,解释程序知道在调用该函数时要检查 sMessage 的值。
    //sMessage 将在函数调用 sayHelloWorld() 时(最后一行)被赋值,显示消息 "hello world"。
    
    
    var iBaseNum = 10;
    function addNum(inum1,inum2){
        //定义一个闭包
        function doAdd(){
            return inum1+iNum2+iBaseNum;
        }
        //调用
        return doAdd(); 
    }
    
    //这里,函数 addNum() 包括函数 doAdd() (闭包)。
    //内部函数是一个闭包,因为它将获取外部函数的参数 iNum1 和 iNum2 以及全局变量 iBaseNum 的值。 
    //addNum() 的最后一步调用了 doAdd(),把两个参数和全局变量相加,并返回它们的和。
    //这里要掌握的重要概念是,doAdd() 函数根本不接受参数,它使用的值是从执行环境中获取的。
    //可以看到,闭包是 ECMAScript 中非常强大多用的一部分,可用于执行复杂的计算。
    //提示:就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。
    
      
    //这里很关键,也很难理解,需要画内存图。
      function foo(x){
        var tmp = 3;
        return function(y){
            alert(x + y + (++tmp) );
        }
      }
      //这里才是闭包
      var bar = foo(2); // 相当于 var bar = function(y){alert(2+y+(++tmp));} 但还是有所不同。 
      bar(10);//16
      bar(10);//17  由于tmp仍存在于bar闭包的内部,所以它还是会自加1,而且你每次调用bar时它都会自加1.
      
        //闭包的理解:
        //http://kb.cnblogs.com/page/105708/
        
        //Javascript的垃圾回收机制
       在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。
        如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
        因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
    
    
        var name = "The Window";   
          var object = {   
            name : "My Object",   
            getNameFunc : function(){   
              return function(){   
                return this.name;   
             };   
            }   
        };   
        
        
        var func = object.getNameFunc(); //返回匿名的闭包函数
        var returnName = func();
        //alert(returnName);
        //alert(object.getNameFunc()());  //The Window   为什么不是: My Object
    
    
        function outerFun()
        {
             var a=0;
             function innerFun()
             {
                  a++; //a 的值不会被GC回收。
                  alert(a);
             }
             return innerFun;  //注意这里
        }
        
        var obj = outerFun();
        obj();  //结果为1
        obj();  //结果为2
        obj(); //3  ....
        
        var obj2 = outerFun();
        obj2();  //结果为1
        obj2();  //结果为2
    
        
        function outerFun()
        {
             var a =0;
             alert(a);  
        }
        var a=4;
        outerFun();//0
        alert(a);//40
        
        
        function outerFun()
        {
             //没有var 
             a =0;
             alert(a);  
        }
        var a=4;
        outerFun();//0
        alert(a);//0
    
    //作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行a=0时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var a=4;  并改变其值.
       */ 
       //作用域链
      // http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html
      
      
      //OO面向对象
       /*
      function Cat(name,age){
           this.name = name;
           this.age = age;
           this.type = "动物";
           this.say = function(){
             alert(this.name);
           }
      }
      
      var cat1 = new Cat("haha",3);
      var cat2 = new Cat("wwww",4);
    
      
      上面的定义方式,存在的问题:
      cat1, cat2 ...的
       type, say 都是相同的内容,在new的时候,会给每个cat1,cat2,都创建一块内存,用来存储type,say.
       这就造成了内存空间的浪费。
       可以使用下面的改良的方式定义:
      
      
      function Cat(name,age){
         this.name = name;
         this.age = age;
      }
      
      Cat.prototype.type = "动物";
      Cat.prototype.say = function(){
        alert(this.name);
      }
       */
      /*
      上面的定义方式,存在的问题:
      虽然解决了内存空间浪费的问题,但在形式上看起来,并不像java里的Class的定义方式。
      可以使用下面的改良的方式定义:
    
     function Cat(name,age){
         this.name = name;
         this.age = age;
         if(!this.type)
         Cat.prototype.type = "动物";
         if(!this.say){
             Cat.prototype.say = function(){
                alert(this.name);
            }
        }
      
      }
      
      var cat1 = new Cat("haha",3);
      var cat2 = new Cat("wwww",4);
      
      cat1.say();
      cat2.say();
       */ 
      //继承
      
      //http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
         /* 
     // 一、 构造函数绑定
    //第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:
      //父类
       function Animal(){
        this.species = "动物";
      }
      //子类
        function Cat(name,color){
             Animal.apply(this, arguments);//
            this.name = name;
            this.color = color;
          }
      
       var cat1 = new Cat("大毛","黄色");
       alert(cat1.species); // 动物
      
     
      
     // 二、 prototype模式
    //第二种方法更常见,使用prototype属性。
    //如果"猫"的prototype对象,指向一个Animal的实例,那么所有"猫"的实例,就能继承Animal了。
       //父类
       function Animal(){
        this.species = "动物";
      }
     //子类
        function Cat(name,color){
            this.name = name;
            this.color = color;
          }
      //实现继承
       Cat.prototype = new Animal();//重写了Cat.prototype
       Cat.prototype.constructor = Cat;//将新的Cat.prototype.constructor再指向Cat
    
      var cat1 = new Cat("大毛","黄色");
      alert(cat1.species); // 动物
      
      
     
     
     // 三、 直接继承prototype (有问题)
    //第三种方法是对第二种方法的改进。由于Animal对象中,不变的属性都可以直接写入Animal.prototype。所以,我们也可以让Cat()跳过 Animal(),直接继承Animal.prototype。
    //现在,我们先将Animal对象改写:
    
    
        function Animal(){}
        Animal.prototype.species = "动物";
    
    //然后,将Cat的prototype对象,然后指向Animal的prototype对象,这样就完成了继承。
      
       function Cat(name,color){
            this.name = name;
            this.color = color;
          }
        
        Cat.prototype = Animal.prototype;
        Cat.prototype.constructor = Cat;//这一句实际上把Animal.prototype对象的constructor属性也改掉了!
        
       var cat1 = new Cat("大毛","黄色");
       alert(cat1.species); // 动物
      //与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。
      //所以,上面这一段代码其实是有问题的。
     
      
      
      //四、 利用空对象作为中介
    //由于"直接继承prototype"存在上述的缺点,所以就有第四种方法,利用一个空对象作为中介。
        
        /*
        function Animal(){}
        Animal.prototype.species = "动物";
        
       function Cat(name,color){
            this.name = name;
            this.color = color;
          }
        
        var F = function(){};
       F.prototype = Animal.prototype;
       Cat.prototype = new F();
       Cat.prototype.constructor = Cat;
    
    
       var cat1 = new Cat("大毛","黄色");
       alert(cat1.species); // 动物
    
      
       //F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
    
       //
       function Animal(){}
        Animal.prototype.species = "动物";
        
       function Cat(name,color){
            this.name = name;
            this.color = color;
          }
        
       function extend(Child, Parent) {
        var F = function(){};
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
        Child.uber = Parent.prototype;
      }
    
      extend(Cat,Animal);//YUI提供的实现继承的方式
      var cat1 = new Cat("大毛","黄色");
      alert(cat1.species); // 动物
    
     
    //五、 拷贝继承
    //上面是采用prototype对象,实现继承。我们也可以换一种思路,纯粹采用"拷贝"方法实现继承。简单说,如果把父对象的所有属性和方法,拷贝进子对象,不也能够实现继承吗?这样我们就有了第五种方法。
     
      function Animal(){}
        Animal.prototype.species = "动物";
        
       function Cat(name,color){
            this.name = name;
            this.color = color;
          }
        
         function extend2(Child, Parent) {
        var p = Parent.prototype;
        var c = Child.prototype;
        for (var i in p) {
          c[i] = p[i];
          }
        c.uber = p;
      }
    
     extend2(Cat, Animal);
      var cat1 = new Cat("大毛","黄色");
      alert(cat1.species); // 动物
    */
    /*
    //一、什么是"非构造函数"的继承?
    //比如,现在有一个对象,叫做"中国人"。
        var Chinese = {
            nation:"中国"
        }
        
        var Doctor ={
          career:"医生"
        }
        
        
    //1, object方法
        function object(o) {
            function F() {}  //空对象
            F.prototype = o;  //父对象
            return new F();
        }
    //这个object()函数,其实只做一件事,就是把子对象的prototype属性,指向父对象,从而使得子对象与父对象连在一起。
    
    
    //2, 浅拷贝方法
    //除了使用"prototype链"以外,还有另一种思路:把父对象的属性,全部拷贝给子对象,也能实现继承。
    
        function extendCopy(p){
            var c = {};
            for(var i in p){
                c[i] = p[i];
            }
            return c;
        }
        
        //var Doctor = extendCopy(Chinese);
        //Doctor.career = '医生';
        //alert(Doctor.nation); // 中国
        
    //但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。
    
     Chinese.birthPlaces = ['北京','上海','香港'];
     var Doctor = extendCopy(Chinese);
     Doctor.birthPlaces.push('厦门');
     alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
     alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门
    
    //3, 深拷贝方法 (JQuery使用的实现继承的方式)
    
    function deepCopy(p,c){
        var c = c || {};
        for(var i in p){
            if(typeof p[i] === 'object'){
                c[i] = (p[i].constructor === Array)? []:{};//? 什么意思
                deepCopy(p[i],c[i]);//递归
            }else{
                c[i] = p[i];
            }
        }
        return c;
    }
    
     Chinese.birthPlaces = ['北京','上海','香港'];
     var Doctor = deepCopy(Chinese);
     Doctor.birthPlaces.push('厦门');
     alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
     alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门
    */
    
    
    
    
    
        </script>
      </head>
      <body>
        <div id="wrap">
          
        </div>
      </body>
    </html>
  • 相关阅读:
    安装 Ruby, Rails 运行环境
    saas 系统租户个性化域名&&租户绑定自己域名的解决方案
    caddy server 几个常用插件
    caddy server && caddyfile
    caddy server 默认https && http2的验证
    caddy server 了解
    redis 连接池的一些问题
    Hangfire 任务调度
    Spring Cloud feign 服务超时处理
    windows 2016 容器管理
  • 原文地址:https://www.cnblogs.com/heavyhe/p/4978256.html
Copyright © 2011-2022 走看看