JavaScript学习笔记(一)
1.逻辑And运算符详解
只有true&&obj 返回obj obj&& true 返回true false&&obj 与obj&&false都返回false false&&null 返回false false&&NaN返回false NaN&&null 返回NaN null&&NaN 返回null
2.逻辑Not运算符详解
逻辑 NOT 运算符返回的一定是 Boolean 值。 如果运算数是对象,返回 false 如果运算数是数字 0,返回 true 如果运算数是 0 以外的任何数字,返回 false 如果运算数是 null,返回 true 如果运算数是 NaN,返回 true 如果运算数是 undefined,发生错误
3.JavaScript"=="的作用
当==两边的内容是字符串时,则比较字符串的内容是否相等。
当==两边的内容是数字时,则比较数字的大小是否相等。
当==两边的内容是对象或者是对象的函数属性时,则比较内存地址是否相等。
总结:
==和===的区别:"==" 只要求值相等; "===" 要求值和类型都相等
4.函数的深入使用
4.1 可变参数
函数的参数列表可以是任意多个,并且数据类型可以是任意的类型,JavaScript的函数天然支持可变参数,JavaScript有一个arguments变量可以访问所有传到函数内部的参数。
范例:JavaScript使用arguments创建参数可变的函数
1 <script type="text/javascript"> 2 /*add函数是一个参数可变的函数*/ 3 function add(){ 4 var result=0; 5 for(var i=0;i<arguments.length;i++){ 6 //alert(arguments[i]); 7 result+=arguments[i]; 8 } 9 10 return result; 11 } 12 alert("add(1,2,3)="+add(1,2,3));//调用add函数时传入3个参数 13 alert("add(1,2,3,4,5,6)="+add(1,2,3,4,5,6));//调用add函数时传入6个参数 14 alert("add()="+add());//调用add函数时不传入参数 15 alert("add(1,\"HelloWorld\")="+add(1,"HelloWorld"));//调用add函数时传入不同类型的参数 16 </script>
运行结果:
4.2 创建动态函数
创建动态函数的基本格式:var 变量名 = new Function("参数1","参数2","参数n","执行语句");
Function是javascript中的一个对象,是固定不变的,规定Function对象的"F"必须大写,当是function的时候,我们知道是定义函数的时候所使用的一个关键字
4.3 创建匿名函数
alert(function(i1, i2) { return i1 + i2; }(10,10)); 直接声明一个匿名函数,立即使用。用匿名函数的好处就是省得定义一个用一次就不用的函数,而且免了命名冲突的问题,js中没有命名空间的概念,因此很容易函数名字冲突,一旦命名冲突以最后声明的为准。
PS:不支持函数的重载,JavaScript没有方法重载的说法,如果两个方法名字一样,即使参数个数不一样,那么后面定义的就会覆盖前面定义,调用方法时永远是调用后定义的那个。
JS的函数没有专门的函数默认值的语法,但是可以不给参数传值,不传值的参数值就是undefined。
5.数组
5.1 Array的简化声明
1 <script type="text/javascript"> 2 //JavaScript声明数组的四种方式 3 var arr1 = new Array();//创建一个空数组 4 arr1[0]="xdp"; 5 arr1[1]="gacl"; 6 var arr2 = new Array(2);//创建一个数组并指定长度为2 7 arr2["name0"]="xdp";//arr2第一个元素 8 arr2["name1"]="gacl";//arr2第二个元素 9 arr2["name2"]="xtxd";//arr2第三个元素,arr2虽然在声明时指明了长度为2,但是还是可以添加超过其指明长度的元素 10 var arr3 = new Array("孤傲苍狼","白虎神皇","灭世魔尊");//创建一个数组并初始化数组中的元素 11 var arr4 = [1,true,"String"];//Array的简化声明 12 13 document.write("遍历arr1中的元素:<br/>"); 14 for(var i in arr1) { 15 document.write(arr1[i]+"<br/>"); 16 } 17 document.write("-----------------------------------------------------------------------------<br/>"); 18 document.write("遍历arr2中的元素:<br/>"); 19 for(var i in arr2) { 20 document.write("arr2[\""+i+"\"]="+arr2[i]+"<br/>"); 21 } 22 document.write("-----------------------------------------------------------------------------<br/>"); 23 document.write("遍历arr3中的元素:<br/>"); 24 for(var i in arr3) { 25 document.write(arr3[i]+"<br/>"); 26 } 27 document.write("-----------------------------------------------------------------------------<br/>"); 28 document.write("遍历arr4中的元素:<br/>"); 29 for(var i in arr4) { 30 document.write(arr4[i]+"<br/>"); 31 } 32 </script>
运行结果:
遍历arr1中的元素: xdp gacl ----------------------------------------------------------------------------- 遍历arr2中的元素: arr2["name0"]=xdp arr2["name1"]=gacl arr2["name2"]=xtxd ----------------------------------------------------------------------------- 遍历arr3中的元素: 孤傲苍狼 白虎神皇 灭世魔尊 ----------------------------------------------------------------------------- 遍历arr4中的元素: 1 true String
5.2 各种数组方法的使用
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"><head> 3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4 <title>数组练习:各种数组方法的使用</title> 5 <style> 6 div{color:green;padding:10px 15px;margin:12px 0;background:#f0f0f0;border:1px dotted #333;font:12px/1.5 Courier New;word-wrap:break-word;} 7 </style> 8 <script type="text/javascript"> 9 window.onload = function () 10 { 11 var aDiv = document.getElementsByTagName("div"); 12 var aInput = document.getElementsByTagName("input"); 13 var i = 0; 14 var bS1 = bS2 = true; 15 var aTmp = []; 16 17 //删除/添加第一项 18 aInput[0].onclick = function () 19 { 20 aTmp = getArray(aDiv[0].innerHTML); 21 bS1 ? 22 //删除第一项, shift()方法 23 (aTmp.shift(), this.value = this.value.replace("删除","添加"), bS1 = false) : 24 //添加第一项, unshift()方法 25 (aTmp.unshift("January(1)"), this.value = this.value.replace("添加","删除"), bS1 = true); 26 //输出 27 aDiv[0].innerHTML = aTmp.join() 28 }; 29 30 31 //删除/添加最后一项 32 aInput[1].onclick = function () 33 { 34 aTmp = getArray(aDiv[0].innerHTML); 35 bS2 ? 36 //删除最后一项, pop()方法 37 (aTmp.pop(), this.value = this.value.replace("删除","添加"), bS2 = false) : 38 //添加最后一项, push()方法 39 (aTmp.push("December(12)"), this.value = this.value.replace("添加","删除"), bS2 = true); 40 //输出 41 aDiv[0].innerHTML = aTmp.join() 42 }; 43 44 45 //复制, concat()方法 46 aInput[2].onclick = function () 47 { 48 aTmp = getArray(aDiv[1].innerHTML); 49 //输出 50 aDiv[1].innerHTML = aTmp.concat(aTmp).toString().replace(/\s/g,"") 51 }; 52 53 54 //还原, 利用数组的 length 特点 55 aInput[3].onclick = function () 56 { 57 aTmp = getArray(aDiv[1].innerHTML); 58 //设置数组长度 59 aTmp.length = 10; 60 //输出 61 aDiv[1].innerHTML = aTmp.join() 62 }; 63 64 65 //第三组数据还原 66 aInput[4].onclick = function () 67 { 68 aTmp = ["red","green","blue","white","yellow","black","brown"]; 69 //输出 70 aDiv[2].innerHTML = aTmp.join() 71 }; 72 73 74 //删除前三项 75 aInput[5].onclick = function () 76 { 77 aTmp = getArray(aDiv[2].innerHTML); 78 //删除, 0开始, 删除3个 79 aTmp.splice(0, 3); 80 //输出 81 aDiv[2].innerHTML = aTmp.join() 82 }; 83 84 85 //删除第二至三项 86 aInput[6].onclick = function () 87 { 88 aTmp = getArray(aDiv[2].innerHTML); 89 //删除, 2开始, 删除2个 90 aTmp.splice(1, 2); 91 //输出 92 aDiv[2].innerHTML = aTmp.join() 93 }; 94 95 96 //在第二顶后插入"orange", "purple" 97 aInput[7].onclick = function () 98 { 99 aTmp = getArray(aDiv[2].innerHTML); 100 //插入, 2开始, 插入"orange", "purple" 101 aTmp.splice(1, 0, "orange", "purple"); 102 //输出 103 aDiv[2].innerHTML = aTmp.join() 104 }; 105 106 107 //替换第二项和第三项 108 aInput[8].onclick = function () 109 { 110 aTmp = getArray(aDiv[2].innerHTML); 111 //插入, 2开始替换 112 aTmp.splice(1, 2, "#009900", "#0000ff"); 113 //输出 114 aDiv[2].innerHTML = aTmp.join() 115 }; 116 117 //将div中的内容转为数组 118 //str div对象 119 function getArray(str) 120 { 121 aTmp.length = 0; 122 str = str.split(","); 123 for (var i in str)aTmp.push(str[i]); 124 return aTmp 125 } 126 } 127 </script> 128 </head> 129 <body> 130 <div>January(1),February(2),March(3),April(4),May(5),June(6),July(7),Aguest(8),September(9),October(10),November(11),December(12)</div> 131 <input value="删除January(1)" type="button"> 132 <input value="删除December(12)" type="button"> 133 <div>0,1,2,3,4,5,6,7,8,9</div> 134 <input value="复制" type="button"> 135 <input value="还原" type="button"> 136 <div>red,green,blue,white,yellow,black,brown</div> 137 <input value="还原" type="button"> 138 <input value="删除前三项" type="button"> 139 <input value="删除第二至三项" type="button"> 140 <input value="在第二项后插入(orange, purple)" type="button"> 141 <input value="替换第二项和第三项" type="button"> 142 </body></html>
6.Javascript面向(基于)对象编程
6.1 澄清概念
1.JS中"基于对象=面向对象"
2.JS中没有类(Class),但是它取了一个新的名字叫“原型对象”,因此"类=原型对象"
6.2 类(原型对象)和对象(实例)的区别与联系
1.类(原型对象)是抽象,是概念的,代表一类事物。
2.对象是具体的,实际的,代表一个具体的事物。
3.类(原型对象)是对象实例的模板,对象实例是类的一个个体。
6.3 抽象的定义
在定义一个类时,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型(模板),这种研究问题的方法称为抽象。
6.4封装
封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其它部分只有通过被授权的操作(函数),才能对属性进行操作!
封装的范例:
1 <script type="text/javascript"> 2 /*定义一个Person类*/ 3 function Person(_name,_age,_salary){ 4 //Person类的公开属性,类的公开属性的定义方式是:”this.属性名“ 5 this.Name=_name; 6 //Person类的私有属性,类的私有属性的定义方式是:”var 属性名“ 7 var Age=_age; 8 var Salary=_salary; 9 10 //定义Person类的公开方法(特权方法),类的公开方法的定义方式是:”this.functionName=function(){.....}“ 11 this.Show=function(){ 12 alert("Age="+Age+"\t"+"Salary="+Salary);//在公开方法里面访问类的私有属性是允许的 13 } 14 /* 15 定义Person类的私有方法(内部方法), 16 类的私有方法的定义方式是:”function functionName(){.....}“, 17 或者 var functionName=function(){....} 18 */ 19 function privateFn(){ 20 alert("我是Person类的私有函数privateFn"); 21 } 22 23 var privateFn2=function(){ 24 alert("我是Person类的私有函数privateFn2"); 25 } 26 } 27 /*通过prototype给可以类的所有对象添加公共(public)方法, 28 但是这种方式定义的方法不能去访问类的私有属性和私有方法*/ 29 Person.prototype.Fn=function(){ 30 alert("访问公共属性this.Name="+this.Name);//访问公共属性,OK的 31 //alert("访问私有属性Aag="+Age);//访问私有属性,这里会报错“Age未定义” 32 //privateFn();//调用私有方法,这里会报错“缺少对象” 33 34 } 35 36 var p1 = new Person("孤傲苍狼",24,2300); 37 alert("p1.Name="+p1.Name);//访问公有属性,这是可以正常访问的 38 alert("p1.Age="+p1.Age+"\t"+"p1.Salary="+p1.Salary);//不能使用类的对象去直接访问类私有属性,这是访问不了的,结果都是undefined 39 p1.Show();//调用类的公共函数,这次允许的 40 p1.Fn();//调用类的公共函数,这次允许的 41 //alert("p1.privateFn():"+p1.privateFn()+" p1.privateFn2():"+p1.privateFn2());//不能使用类的对象去调用类的私有方法,这里会报错”对象不支持此属性或者方法“ 42 </script>
6.5 继承
继承范例:
1 <script type="text/javascript"> 2 /*定义Stu类*/ 3 function Stu(name,age){ 4 this.Name=name; 5 this.Age=age; 6 this.Show=function(){ 7 window.alert("我的名字是:"+this.Name+",今年:"+this.Age); 8 } 9 this.SayHello = function(){ 10 window.alert("Hello,"+this.Name); 11 } 12 } 13 14 /*定义MidStu类*/ 15 function MidStu(name,age){ 16 this.stu=Stu;//MidStu类继承Stu类 17 this.stu(name,age);//JS中实际上是通过对象冒充来实现继承的,这句话不能少,因为JS是动态语言,如果不执行,则不能实现继承效果 18 /* 19 从父类继承下来的公共方法,可以根据实际情况选择重写 20 */ 21 //在子类MidStu中重写父类Stu的Show方法 22 /*this.Show=function(){ 23 alert("MidStu.Show()"); 24 }*/ 25 //在子类MidStu中重写父类Stu的SayHello方法 26 this.SayHello=function(){ 27 alert("你好,"+this.Name); 28 } 29 30 } 31 32 var midStu = new MidStu("孤傲苍狼",24);//创建一个MidStu类实例对象 33 alert("访问继承下来的属性Name和Age,midStu.Name="+midStu.Name+",midStu.Name="+midStu.Age);//访问继承下来的属性 34 midStu.Show();//调用从父类Stu继承下来的Show方法 35 midStu.SayHello();//调用从父类Stu继承下来的SayHello方法,SayHello()在子类中进行了重写,这里调用的是重写过后的SayHello()方法 36 </script>
运行结果:
6.6 多态
所谓多态,就是指一个引用在不同情况下的多种状态,在Java中多态是指通过指向父类的引用,来调用不同子类中实现的方法。
JS实际上是无态的,是一种动态语言,一个变量的类型是在运行过程中由JS引擎决定的,所以说,JS天然支持多态。
6.7 工厂方法
——使用new Object创建对象并添加相关属性
1 //通过Object直接创建对象 2 //var p1 = new Object();//创建一个Object对象 3 var p1 = {};//创建一个Object对象,简写 4 //动态增加属性、方法 5 p1.Name = "孤傲苍狼"; 6 p1.Age = 24; 7 p1.SayHello = function() { alert("hello,"+p1.Name); }; 8 p1.SayHello(); 9 for(var propertyName in p1) {//对象的成员都是对象的key 10 alert(propertyName); 11 }
6.8 使用构造函数来定义类
(原型对象)
基本语法:
1 function 类名(){ 2 this.属性名;//公共属性 3 var 属性名;//私有属性 4 /*凡是定义类的公共属性和公共方法都要使用this*/ 5 //定义类的公共函数 6 this.函数名=function(){ 7 8 } 9 //定义类的私有函数 10 function 函数名(){ 11 12 } 13 }
范例:
1 /*定义一个猫类,这种就是使用构造函数来定义类(原型对象)*/ 2 function Cat(){ 3 this.Name="catName";//public属性 4 this.Age;//public属性 5 this.Color;//public属性 6 var weight=2;//private属性,只能在Cat类内部使用,Cat类的对象无法访问这个私有属性 7 //public方法 8 this.publicFunction = function(){ 9 alert(weight); 10 alert("猫叫..."); 11 } 12 //private方法,只能在Cat类内部使用,Cat类的对象无法访问这个私有方法 13 var privateFunction = function(){ 14 alert("私有方法"); 15 } 16 17 18 } 19 //如果这样用,那么就当成函数来使用 20 Cat(); 21 //如果这样用,那么就当成类来使用 22 var cat1 = new Cat(); 23 //cat1就是一个对象(实例) 24 alert(cat1.Name);//访问公共属性,弹出默认值catName 25 cat1.Name="TomCat";//访问公共属性 26 cat1.Age=3;//访问公共属性 27 cat1.Color="白色";//访问公共属性 28 alert(cat1.weight);//访问私有属性,无法访问,弹出undefined 29 alert(cat1.Name+"\t"+cat1.Age+"\t"+cat1.Color);//访问对象的属性方式1:对象名.属性名 30 alert(cat1["Name"]+"\t"+cat1["Age"]+"\t"+cat1["Color"]);//访问对象的属性方式2:对象名["属性名"] 31 cat1.publicFunction();//调用public方法 32 cat1.privateFunction();//调用private方法,报错:对象不支持此属性或方法 33 for(var property in cat1){ 34 document.writeln(property+"\t"); 35 }
JS中一切都是对象,类(原型对象)其实也是对象,它实际上是Function类的一个实例
1 document.write("<pre>"); 2 function Person(){ 3 4 } 5 /*Person.constructor得到的Person类的构造函数如下: 6 function Function() { 7 [native code] 8 } 9 */ 10 document.writeln("Person.constructor:"+Person.constructor);//Person类的构造函数 11 document.writeln("Person:"+Person); 12 var p1 = new Person(); 13 document.writeln("p1.constructor:"+p1.constructor);//”p1.constructor“是得到p1实例的构造函数 14 //如何判断某个对象是不是某个类型,采用如下两种方式 15 if(p1 instanceof Person){ 16 document.writeln("p1 is Person ok1"); 17 } 18 if(p1.constructor==Person){ 19 document.writeln("p1 is Person ok2"); 20 } 21 22 var num1=123; 23 document.writeln("num1.constructor:"+num1.constructor); 24 25 var str1="abc"; 26 document.writeln("str1.constructor:"+str1.constructor); 27 document.write("</pre>")
运行结果:
Person.constructor: function Function() { [native code] } Person:function Person(){ } p1.constructor:function Person(){ } p1 is Person ok1 p1 is Person ok2 num1.constructor: function Number() { [native code] } str1.constructor: function String() { [native code] }