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>
时间: 2024-10-14 05:17:43

JavaScript学习----初步的相关文章

JavaScript学习思维导图路线

一.写在前面的话 转眼又是法定节假日—清明节.怀念过去的亲人,越发感到人生短暂,想做的事,一定要尽早做,想成为牛人, 就要付出比别人更加多的时间去学习,今天是假期的第一天,一大早就醒啦,像我等这种没有女朋友的屌丝, 只有来到公司看看书,看看技术博客,还有差不多两个月,毕业快两年了,来到上海的日子,节奏犹如奔跑的骏马一样,来去匆匆. 工作占据了生活的大部分时间,但是是快乐的,很享受这个过程!享受现在公司的一群人,热情,激情,有理想! javascript学习过,一直没有系统的总结,所以这篇算是ja

mongoDB学习初步总结

What? 最受欢迎的非关系型数据库之一.面向文档的数据库,在存储乎数据方面与关系型数据库有着本质的区别. Why? 简单易用 对多变的业务需求,适应性强于SQL型DB 性能 复制 索引 分片 丰富的查询 灵活的数据模型 毫不逊色的速度 海量数据下表现好 对程序员友好,但是是DBA的噩梦,维护性不佳 构成 相对于SQL数据库 行-> 表 -> 数据库 而言,mongoDB的组织结构是: document -> collection -> DataBase 其中的document ,

javascript学习

javascript 学习 title: Javascripttags: javascript,学习grammar_cjkRuby: true--- 定义变量 三种形式 var name; var name = "zhang san"; var name; name = "zhang san"; Javascript 的数据类型 6种数据类型 字符串单引号或双引号 var name = "zhang san"; var name = 'zhang

Javascript 学习笔记 2: 标识语句

可以在任何语句声明之前使用唯一标识(identifier)和冒号(:)用来标记该语句: identifier: statement 这样,你可以在程序的任何其他地方通过标识来使用这个语句.即使在语句内部也可以使用该语句的标识(例如:循环语句和条件语句).当在一个循环语句前添加一个标识,你可以在语句内部通过break 标识来退出当前循环,也可以通过continue标识来继续执行该语句.例如: mainloop: while(token != null) { // Code omitted... c

JavaScript学习之DIV层与图像

DIV层与图像 一.设计一个可定位的层 1.设置位置(position)和大小 (1)绝对定位(absolute):以页面边框为参照,只要设置好绝对位置,那么元素的位置会始终固定在距离边框某个位置的距离. 绝对定位有两个属性:left和top,分别是距离网页左边和网页顶部的绝对位置,可借助style属性直接设置: style="position:absolute;left:距离左边距离;top:距离顶部距离" (2)相对定位(relative):需要有一个参照元素,设置好相对位置和参照

JavaScript学习05 定时器

JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout(“<表达式>”,毫秒) 功能:执行<表达式>一次. 例子: <!DOCTYPE html> <html> <head> <title>timer1.html</title> <meta http-equiv="keywords" co

Javascript学习--------认识window窗口对象

window对象: Window 对象表示浏览器中打开的窗口. 可以通过window对象设置窗口的大小,位置等. 还可以控制是否加载网页等. window对象集合: 集合 描述 frames[] 返回窗口中所有命名的框架. 该集合是 Window 对象的数组,每个 Window 对象在窗口中含有一个框架或 <iframe>.属性 frames.length 存放数组 frames[] 中含有的元素个数.注意,frames[] 数组中引用的框架可能还包括框架,它们自己也具有 frames[] 数

Javascript学习------FileSystemObjec对象

动态创建FileSystemObject对象: var fso=new FileSystemObject("Scripting.FileSystemObject"); (接下来可以用变量fso对Drive对象.Drives集合.File对象.Files集合.Folder对象.Folders集合以及TextStream对象进行相应的操作.) FileSystemObject对象的方法 ·GetAbsolutePathName()方法:该方法根据提供的路径返回完整的路径. ·GetBase

javascript学习笔记---ECMAScript-判断变量类型

判断类型之前,先要清楚有哪些类型. (理理思路:程序由数据和方法构成,数据由简单数据和复杂数据构成) 即类型有: 数据(简单数据:boolean,string,num,undefined,null.复杂数据:object), 方法(function) 万能的typeof,神一样的方法 typeof(1);// num typeof("hello");// string   typeof(false);// boolean var vFlag; typeof(vFlag);// unde