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. 课后练习
posted @ 2019-07-20 18:54  龙龙鄂构  阅读(142)  评论(0编辑  收藏  举报