• JavaScript学习一


    1.   JavaScript介绍

    • 1.  代码位置(掌握)
    • 2.  函数(掌握)
    • 3.  函数中特殊对象;(掌握)
    • 4.  面向对象;(掌握)
    • 5.  原型对象;(掌握)
    1. 代码位置(回顾)

    JS代码可以写在三个位置

    2.1.  <script>标签中

     

    2.2.  引入一个外部的js

    新建一个文本文件,文件后缀为js,在这个文本文件中写代码,然后在需要使用这些代码的网页中使用<script></script>(必须是完整标签引入,不能写成自结束<script src=””/>)标签指定src引入。

     

    2.3.  JS代码作为特殊属性的值

    <!-- 1.<script>标签中 -->

    <!-- <script type="text/javascript"> -->

    <!--  alert(0); -->

    <!-- </script> -->

    <!-- 2.引入一个外部的js -->

    <!-- <script type="text/javascript" src="index.js"></script> -->

    </head>

    <body>

             <!--3.JS代码作为特殊属性的值 -->

             <!-- 建议a标签的href少用# -->

             <a href="#" onclick="javascript:alert(1);">a1</a>

             <!-- 必须记住的:不使用瞄点的方式 -->

             <a href="javascript:;" onclick="javascript:alert(2);">a2</a>

             <a href="javascript:void(0);" onclick="javascript:alert(3);">a3</a>

            

    <!-- 如果url地址后面有#,表示执行了一个瞄点 -->

    <div id="top">top</div><a href="#footer">footer</a>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

    <p>0<p>

     

    <div id="footer">footer</div><a href="#top">top</a>

    </body>

    2.4.  注意点

    1. <script>标签设置src属性后,就不能在这个<script>标签中写js代码,无论你写的是什么,最终都会被src对应的文件内容替换。
    2. <script src=””></script>外链方式,加载JS需要时间,我们可以把<script>标签放在<body>内容的末尾,这样可以保证浏览器先加载显示的内容,然后再加载JS文件内容。(访问的第一次的时候有性能优化,通过tomcat访问的时候,响应码200,第2次访问302(被浏览器缓存了))
    3. JS代码作为特殊标签的特殊属性值时,如果执行某个函数,那么必须要加“()”,这代表执行该函数。 <a onclick=”clickMe()”>点击我</a>
    4. 函数

    3.1.  为什么需要函数

    JS代码可以直接编写在<script>标签之间或者一个单独JS文件中,这些代码在页面被解析的时候就进行执行。

    实际开发中,有的时候我们需要多次执行相同代码,或者在特定的时机执行某段代码,那么函数就可以解决这些问题。

     

    函数可以包装一段代码,并且可以为这段代码取名,名字即为函数名,通过这个函数名可以达到多次调用效果。

    3.2.  函数的定义及调用

    3.2.1.   如何定义一个函数:

    函数默认是添加到window对象里面,

    如果同一段script,先调用函数,在定义函数,不会出错

    函数如果加了()就是调用

       函数是由这样的方式进行声明的:关键字 function、函数名、若干参数[可选]、返回值[可选],以及置于括号中的待执行代码。

    function 函数名(参数1,参数2){

          //代码

          return 返回值;

    }

    3.2.2.   函数的调用(只要看到函数后面有()就是立即调用)

    函数名(参数1,参数2);

    <script type="text/javascript">

             //函数可以包装一段代码,并且可以为这段代码取名,名字即为函数名,通过这个函数名可以达到多次调用效果。     

             //声明一个函数

             function sayMsg(){

                      console.debug("你好");

             }

             //调用函数

             sayMsg();  

    <script/>

    3.2.3.   函数参数细节

     如果被调用的函数,需要我们传入参数,比如求两数和的函数,调用时我们就需要传入两个数。

     

    其实函数调用时,形参和实参的个数可以不一致,如果没有传入实参,那么值为undefined,如果实参个数大于形参个数,也可以正常执行。

     

             //函数参数细节==================================================

             function getSum(num1,num2){

                      return num1+num2;

             }

    //传入实参与形参对应.结果是:15

             console.debug(getSum(5,10));

    //传入实参个数大于形参个数.结果是:15

             console.debug(getSum(5,10,25));

    //传入实参个数小于形参个数.结果是:NaN

             console.debug(getSum(5));  

    //分析 , num1=5,num2=undefined  由于我们进行的是加法运算,js会自动把非数字的值转换为数字,

    //undefined就会转换为数字,所以undefined为NaN,NaN与任何数字做运算都为NaN;

    //1.js运算时如果字符串与任何值做加法都是连接字符串; 2.js运算时如果非数字,那么会先把非数字转化为数字.

    3.2.4.   函数返回值

    返回值:函数代码执行完毕,把运算的结果数据返回,返回的数据就叫返回值。

    如果一函数有返回值,无需特殊声明,只需要使用 return 运算符后跟要返回的值即可,如果没有返回值,函数的默认返回值为undefined。

    //如果一个函数有返回值,那么就直接在函数体中使用return 返回值.如果没有返回值,不写.

             function getAddress(){

                      //return "武汉某个乡卡卡";

             }

             console.debug(getAddress()); //如果没有返回值,返回值就是undefined.

     

    1. JavaScript引擎执行过程:

    4.1.  预编译:

    (代码的首行到末尾扫描),如果发现某行代码中声明函数变量,会声明放到最最最最最前面(代码首行);[变量提升]

    4.2.  执行:执行的时候才会逐行执行.  (赋值在执行期)

             //alert(username);//undefined

             var username = "张三疯";

            

             //alert(fn);//undefined

             var fn = function(){};  //函数表达式

            

             sayHello();

             /**

                      javascript引擎执行过程:

                               1.预编译:(代码的首行到末尾扫描),如果发现某行代码中声明函数,会声明函数放到最最最最最前面(代码首行);

                               2.执行:执行的时候才会逐行执行.  (赋值在执行期)

             **/

             //声明函数

             function sayHello(){

                      console.debug("hello");

             }

     

    1. 函数中特殊对象

    函数运行过程中,JavaScript会自动产生一些特殊对象相当于js的内置对象,不需要我们创建,我们可以使用这些对象干一些有意思的事情。

    5.1.  思考

        1.JavaScript中函数调用时实参的个数可以与形参的个数不一致,如果少传入参数可能会导致计算结果不正确。

        2.目标1:现在需要编写一个函数,该函数接受任意个数的参数(类似于java的可变参数),对传入的参数进行求和。

     3.目标2:方法的重载:方法名相同,参数的类型或者参数的个数不一样。

    5.2.  对比Java(但是js里面默认没有重载和重写)

    【Java里面的内容,比较一下

    Override是重写(覆写):方法名称、参数个数,类型,顺序,返回值类型都是必须和父类方法一致的。它的关系是父子关系

    Overload是重载:方法名称不变,其余的都是可以变更的。它的关系是同一个类,同一个方法名,不同的方法参数或返回值。

        备注:它们都是是Java多态性的不同表现

    以上场景中问题,都与函数被执行时传入的参数有关,其实在函数被执行的时候会自动创建一个用于描述“参数列表值”的对象。

    5.3.  arguments

    函数中获取参数值,可以通过参数名获取,也可以通过arguments对象来获取;

    arguments产生:该对象不是由程序员创建的,而是在javascript执行函数的时候,就会为这个函数创建一个arguments对象,我们可以在函数内部使用这个对象;

    arguments对象:包含了本次调用函数时传入的所有参数。该对象为一个“伪”数组。

    arguments伪数组:和普通对象一样,只是对象具有通过索引([index])访问成员的功能和访问个数(arguments.length)功能。

    arguments对象属性:   

        length:传入参数的个数。

        callee:当前函数对象:返回正被执行的function对象。(已过时)

          语法:arguments.callee。

    5.3.1.   JavaScript中函数调用时实参的个数可以与形参的个数不一致,如果少传入参数可能会导致计算结果不正确。

             function sayMsg(name,msg){

    //arguments : 函数的参数列表.

    //arguments创建 : 该对象不是由程序员创建的,而是在javascript执行函数的时候,

    //就会为这个函数创建一个arguments对象,我们可以在函数内部使用这个对象;

                      if(arguments.length>=2){

                               console.debug(name+" : "+msg);

                      }

             }

             sayMsg("王大锤");

             sayMsg("王大锤","呵呵");  

    5.3.2.         现在需要编写一个函数,该函数接受"任意个数的参数"对传入的参数进行求和。

             function getSum(){

                      //arguments 是一个数组.

                      var sum;

                      for (var i = 0; i < arguments.length; i++) {

                               sum += arguments[i];

                      }

                      return sum;

             }

             console.debug(getSum(1,5,6,7,8,9));

    5.4.  方法的重载:方法名相同,参数的类型或者参数的个数不一样。

    5.4.1.   实现类似jQuery的get方法

             /**

                      url,[data],[callback],[type]

                               url:待载入页面的URL地址

                               data:待发送 Key/value 参数。

                               callback:载入成功时回调函数。

                               type:返回内容格式,xml, html, script, json, text, _default。

     

             **/

             function get(url,data,callback,type){

                      //如果第二参数是一个函数,那么就可以确定传入第二个参数其实应该在第三个位置.

                      if(typeof data == "function"){

                               type = callback;

                               callback  = data;

                               data  = undefined;

                      }

                      console.debug("url : "+url);

                      console.debug("data : "+data);

                      console.debug("callback : "+callback);

                      console.debug("type : "+type);

             }

                     

             get("xxx.action",function(){

                      console.debug("响应函数");

             },"json");

    5.4.2.   jQuery.js:jquery-2.1.1.js p8289

     

    1. JavaScript面向对象

    6.1.  一切皆对象

     JavaScript中一切皆对象,在JavaScript中我们可以把任何(基本数据)类型当成对象来使用。

        比如var num = 3.14159;我们可以调用Number对象上面的toFixed(2)方法来进行小数位的截取。这点于Java中既然不同,Java中的基本数据类型是不能调用方法,只能通过包装类型。

    //JavaScript中一切皆对象,在JavaScript中我们可以把任何(基本数据)类型当成对象来使用。

             //基本数据类型:number/boolean/string/null(值:null)/undefined(undefined)

             //引用数据类型:Object/Array/Regexp/Date/Number/Boolean/String...

            

             //基本数据类型中number.

             var num1 = 3.14159;

             console.debug(num1.toFixed(2)); //一切皆对象

             console.debug(typeof num1);//number

            

             //引用数据类型Number

             var num2 = new Number(3.14159);

             console.debug(num2.toFixed(2));

             console.debug(typeof num2);//object

     

             var b1 = false;

             if(b1){

                      console.debug("能输出我就吃下去");

             }

            

             //js 中所有值的真假性:  0,"",undefined,NaN,null,false(基本数据类型的false)为false,其他值都为true.

             var b2 = new Boolean(false);

             if(b2){

                      console.debug("会输出.....,坑");

             }

    6.2.  简单操作

    6.2.1.   创建对象

        var obj = new 类();

    6.2.2.   添加属性/方法

        obj.name = "张三";

        obj["age"] = 18;

        obj.say = function(){

              alert(this.name);

        }

    6.2.3.   删除属性

        delete obj.name;

        delete obj["age"];

    6.2.4.   遍历对象成员

        for(var p in obj){

             console.debug(p);//p(string)为对象的属性成员名。

        }

    6.3.  JSON对象和JSON字符串

        {key1:value,key2:value....};

        var obj = {name:"张三",age:18};

    <script type="text/javascript">

             //创建json对象

             var jsonObject1 = {

                      name : "xxx",

                      age : 20

             };

     

             //创建json字符串,后台action向前台传递的字符串参数

             //标准json字符串:key必须写"",不是'',如果值不是为布尔,数值,也必须写""

             var jsonString = '{"name":"xxx","age":20}';

             //     var jsonString = "{'name':'xxx','age':20}";JSON.parse报错

             //     怎样把json字符串转化为json对象

             var jsonObject2 = eval("(" + jsonString + ")");//可以转换不标准的json字符串

             var jsonObject3 = JSON.parse(jsonString);//只能转换标准的json字符串

     

             console.debug(jsonObject1);

             console.debug(jsonObject2);

             console.debug(jsonObject3);

    </script>

    6.4.  迭代对象成员(属性+方法)

             /**

               for(var p in obj){

                        p:代表属性名

                        obj:代表被迭代的对象

               }

             **/

             for(var p in obj){

                      console.debug(obj[p]);  // -> obj["name"]   p = name;

                                                                            // -> obj["address"]  p = address;

                                                                            //....

                                                                            //....

             }                

    6.5.  对象属性拷贝

    var obj1 = {

                               name : "gg",

                               address : "yyy",

                               age :  "18",

                               sex : "man"

             };

            

             var obj2 = {

                      name : "mm",

                      sex : "woman"

             };

            

             //拷贝属性 - > 逗逼方式

             /* obj2.address = obj1.address;

             obj2.age = obj1.age;

             obj2.sex = obj1.sex; */

            

             //拷贝属性

             for(var p in obj1){

                      //判断obj2中是否存储这个属性.

                      if(!obj2.hasOwnProperty(p)){

                               obj2[p] = obj1[p];  //obj2["address"] = obj1["address"];   p = "address"

                      }

             }

    1. 函数也是对象

     引用JavaScript中最经典的一句话,一切皆对象,函数其实也是一个对象,这点让很多学习JavaScript的人感到无比的困惑,但是JavaScript的确如此。

    7.1.  函数定义方式:这种定义方式非常的常见。

         function my(){

         }  

    7.2.  函数对象形式:创建函数对象方式,很诡异,但是的确可行。

    var add2 = new Function("a", "b","return a + b");

    7.3.  代码

    <script type="text/javascript">

             //函数有2种定义方式

             //第一种:常用

             function add(a, b) {

                      return a + b;

             }

             console.debug(add(1, 2));//3

            

             //第二种:不常用

             var add2 = new Function("a", "b","return a + b");

             console.debug(add2(1, 2));//3

            

             //既然函数也是对象,添加属性

             add.age=20;

             console.debug(add.age);//20

             add.name="张久万";

             console.debug(add.name);//add,函数的name属性是一个只读的属性,值为函数本身名称

            

             name="xxx";

             console.debug(window);

             console.debug(name);//默认值是(空字符串) ,打印name属性本身是打印window.name,而window.name默认值是(空字符串)

    </script>

    7.4.  jQuery

    <script type="text/javascript" src="jquery-1.11.1.js"></script>

     

    <script type="text/javascript">

             $(function(){

                      //console.debug( $.trim("   a  ") );//看成对象来使用

                      //console.debug( $("#myh1") );//看成函数来使用

             });     

    </script>

    </head>

    <body>

             <h1 id="myh1">全连不休</h1>

    </body>

    1. this

    8.1.  this使用场景:对函数或方法所在的那个对象进行操作;

    this指向的是谁?”谁调用该函数,this就代表谁”

    <script type="text/javascript">

             var obj = {

                      name : "王二花"

             };

     

             //showName默认是属于window对象

             function showName() {

                      console.debug(this.name);

             }

     

             //     this指向的是谁?”谁调用该函数,this就代表谁” :window

             window.showName();//默认是空字符串

     

             //把window对象的showName函数赋值给obj的getName函数

             obj.getName = window.showName;//一定不能写()

             //调用obj的getName函数

             //     this指向的是谁?”谁调用该函数,this就代表谁” :obj

             obj.getName();//王二花

    </script>

    8.2.  修改函数中this

    一般后面写代码很少修改函数中this,面试可能被问到,看jQuery源码。

    函数也是对象,函数对象中存在两个特别有趣的方法,可以修改this。

      call(thisObject,args1,args2...)第2-n个参数一个一个的写

      apply(thisObject,[args1,args2])第2个参数是数组

    call,apply方法都是调用函数,于函数名()直接调用不同,这个两个方法可以修改函数运行时中的this.

      call,apply区别:第一个参数总是指函数运行时的this,call从第二参数开始都为调用函数的参数,而apply,第二个参数为一个数组,该数组就是调用函数的所有参数。

    window.msg = "你牛逼";

             var obj = {

                      msg : "我也不赖..."

             };     

            

             function sayMsg(a,b){

                      console.debug(this.msg+" 参数:"+a+","+b);  

    }

     

             //函数也是一个对象,既然是对象,那么这个对象上面就可以有一些方法.

                      /**

                               函数对象的方法:

                                        call(thisObject,arg1,arg2..argN)

                                                 thisObject:函数执行时,this指向谁.如果不写默认为window.

                                                 arg1,arg2...argN代表调用函数时传入参数.

                                                

                                        apply(thisObject,[arg1,arg2..argN])

                                                 thisObject:函数执行时,this指向谁.如果不写默认为window.

                                                 [arg1,arg2..argN] : 函数执行时,传入参数列表,注意是一个数组.

                                       

                                                

                                       

                               call和apply作用都是让我们的函数执行,其实就等同与  " 函数() "

                               call和apply主要用于执行一个函数时修改函数中的this.

                      **/

             sayMsg.call(window,"www","ttt");

             sayMsg.apply(obj,["www","ttt"]);

            

             //call ,apply的使用

             var n1 = new Number(123);

             var n2 = 123;

             var n3 = new Date();

            

             //jquery可以获取变量的类型.

             console.debug($.type(n1));

             console.debug($.type(n2));

             console.debug($.type(n3));

            

             var obj = {};

             alert(obj.toString.call(n1)); 

                      //n1是一个Number对象,由于Number的toString被复写过,

                      //toString的结果是Number的值,如果我想知道类型,我们可以使用object对象的toString.

    JavaScript中没有为我们提供像Java中定义类的关键字class。JS中定义类只需要定义这个类的构造函数即可;

    JavaScript中没有为我们提供像Java中定义类的关键字class。

    JS中定义类只需要定义这个类的"构造函数"即可; 构造函数与普通函数没区别.

    只要是类,类名就是首字母大写。

             //定义了一个类的构造函数

             function User(name,age){

                      //构造函数中this,就是实例对象         

                      //如果要为对象添加属性,那么需要使用 "this.属性名 = 值;"

                      this.name = name;

                      this.age = age;

                     

                      this.getName = function(){

                               return this.name;

                      };

             }

            

             //通过new创建 实例对象.

             var u1 = new User("大明",50);

             console.debug(u1.getName());

            

             var u2 = new User("小明",30);

             console.debug(u2.getName());

    1. prototype

    10.1.         对象u内部结构

     

     

    10.2.         对象实例u是由两部分组成

    10.2.1.        对象自定义属性部分

    10.2.2.        对象原型部分,对象的原型也是一个对象,同类型原型部分一样

    验证对象的原型也是一个对象

        alert(u.__proto__);  //[object Object]

    验证同类型原型部分一样:实例了2个User对象

    u.__proto__===u2.__proto__     true

    u.__proto__===User.prototype   true

    /**

                      对象实例是由两部分组成:

                               1.对象自定义属性部分

                               2.对象原型部分,alert(u.__proto__);对象的原型也是一个对象. (同类型原型部分一样)

              **/

     

             function User(name, age, address) {

                      this.name = name;

                      this.age = age;

                      this.address = address;

             }

             var u = new User("城灌溪", 28, "cd");

     

             /*

                      对象属性访问过程:

                               1.对象访问属性时首先会在对象自定义属性部分查找,如果自定义属性部分存在那么就使用;

                               2.如果访问的属性在自定义部分没有找到,那么就会到对象 的"原型对象(__proto__)"上面查找,有就使用.

                               3.如果 "原型对象"没有,那么会在"原型对象"的"原型对象"上面 查找对应属性,如果有就使用.

              */

             console.debug(u.name); // 自定义属性. (程序员自己添加的属性)

             console.debug(u.constructor);// 原型对象属性属性.

             console.debug(u.hasOwnProperty);// 原型对象属性属性.

             console.dir(u);

     

    10.3.         对象属性访问过程

    对象访问属性时首先会在对象自定义属性部分查找,如果自定义属性部分存在那么就使用;如果没有找到,那么就会到这个对象的原型部分(__proto__对象)查找,如果能找到就使用,如果没有找到,那么就会在这个对象的原型部分的原型部分查找对应的属性;

    总结:对象访问属性,先在自定义部分查找,如果没有找到,就会去在原型上面查找;如果还没有原型对象的原型上面找,一直找到Object对象为止

    10.4.         原型共享

     

    同一类型的对象实例(构造函数相同),共享同一个原型对象。

    10.5.         原型使用

     JS对象属性访问过程为:先从对象自定义区域查找属性,如果有就使用,如果没有就到对象的原型区域中进行查找,并且原型区域可被多个对象共享使用,所以我们可以往原型对象上面添加属性或方法, 就相当于往对象上面添加了属性或方法。

     

    /*

            相同类型的对象,共享一个原型,我们往这个原型上面添加成员,相当于同类型对象添加成员.

        */

       

        function User(name){

            this.name = name;

        }

       

        //获取原型对象:"构造函数.prototype"

        //原型对象只适合放公共的属性,如果每一个对象中属性值都不一样,那么没必要使用原型.

        User.prototype.aaa  = "呵呵";

        User.prototype.getName = function(){

            return this.name;

        }

       

        var u1 = new User("张三");

        u1.aaa="哈哈";  //添加到u1自定义属性区域,并没有修改原型对象中aaa.

        console.debug(u1.aaa);

       

        var u2 = new User("李四");

        console.debug(u2.aaa);

       

       

    10.5.1.        笔试题:

             /**

                 var a = 5;

                 var b = a.add(2);

                 console.debug(b);// b = 7

             **/

            

             //a 是 number类型,但是我们使用的时候可以把当成Number.

             Number.prototype.add = function(num){

                 return num + this;

             };

             var a = 5;

        var b = a.add(2);

        console.debug(b);// b = 7

    1. 课程总结

    11.1.         重点

    1. 标准json字符串格式&怎样解析json字符串
    2. 原型prototype

    11.2.         难点

    1. 变量提升:JavaScript引擎执行过程
    2. 实现js的方法重载
    3. 常见异常
    4. 课后练习
  • 相关阅读:
    UOS、鸿蒙、麒麟全面出击,国产系统能否干掉Windows?
    黑客给疫情添乱
    人工智能与信息安全
    作为一个程序员,告诉你一些编码知识
    Linus Torvalds 宣布新版Linux系统内核发布
    linux系统root密码忘记了怎么办
    DevOps与NoOps现状分析
    Nginx服务详细介绍
    博客园“可运行"代码
    让setTimeout支持链式
  • 原文地址:https://www.cnblogs.com/Src-z/p/11218801.html
Copyright © 2020-2023  润新知