JavaScript基础

JavaScript 是一种脚本语言,可以在浏览器中执行,和 Java 需要先编译成字节码文件然后再运行不同,JavaScript 直接由浏览器解释执行,即解释一句执行一句,不过 JavaScript 一般都是在客户机的浏览器上面运行,相比于需要集中处理众多请求的后台 Java 代码来说,运行效率相对来说就还好,因为毕竟只需要负责客户机这一个终端。

JavaScript是由三部分组成,分别是 ECMAScriptDOMBOMECMAScript的产生是有原因的,因为虽然 JavaScript是由Netscape (网景)公司开发出来,但在浏览器的使用中可不止这一种,还有微软公司的 JScript,当然主要就是用在 IE 浏览器之中了,除此之外,就还有 CEnviScriptEase,这三种不同的实现对于程序员开发可就是麻烦事了,必须要先使用大量的嗅探程序判断出当前运行的是什么浏览器以及使用的是哪一种 JavaScript,其中一个最常见的例子就是获取网页中的一个元素在不同的浏览器中都是不同的实现,为了解决这个问题,欧洲计算机制造商协会(ECMA)就想根据大家的各自情况,提出一种大家都能遵从的标准,该标准主要定义的就是 JavaScript 的核心语法,这样也就能让这种语言更好的发展,不然肯定会被其它优秀的脚本语言所取代,现在网景公司已经不存在了,IE 浏览器的市场份额也下降了很多,不过新出现的浏览器,比如苹果公司的 Safari 浏览器和谷歌公司的 Chrome 浏览器都很好地实现了上面的标准,值得说一下的是网景公司,产生了许多的优秀的产品和想法,其实之前乔布斯的自传中也提到过,他去网景公司参观,有很多优秀的理念,比如图形化界面、面向对象编程,而乔布斯带回苹果公司的就是图形化界面,当然面向对象编程的重要性对于我们程序员来说就不在这里赘述了,大家有兴趣的可以去查一下这家公司。说完了 ECMAScriptJavaScript 的第二部分就是 DOM 了,也就是文档对象模型,就是将一个页面看做是一个文档,而页面中的标签也就看做是文档的元素,当然使用JavaScript 操作起网页中的元素也就十分简单了,最后一部分是 BOM,浏览器对象模型,就是用来和浏览器来打交道的,是一组用来操作浏览器的预定义对象。

JavaScript组成部分:
    ECMAScript:定义了JavaScript中的核心语法
    DOM:文档对象模型
    BOM:浏览器对象模型

1.ECMAScript(核心语法)

1.1 引入JavaScript脚本的方式

要在页面中使用 JavaScript,其实就是将 JavaScript 代码引用到相应的页面中,第一种方式就是直接在页面中写代码,具体方式就是将 JavaScript 代码使用 script 标签括起来,至于应该将代码具体放在什么位置,学习阶段可以直接放在 head 标签之中,开发阶段放在 body 标签结束之前比较好,这么做的原因是因为 JavaScript 代码是由浏览器从上往下依次解释执行的,如果 script 标签中有代码是获取某个页面元素对象的,而这时代码是放在 body 标签之前的,那么获得的只是 null,因为浏览器还没有加载之后的页面,也就当然不可能获得页面之中的元素了,当然注意一下就好,并且以后开发都会将代码组织到函数之中,调用函数就不会出现这个问题了。

第一种方式:
    <script>
        js代码
    </script>

引入 JavaScript 的第二种方式就是外部引用了,就是将 JavaScript 代码抽取为一个独立的文件,而在需要使用的页面进行引用。

第二种方式:
    <script src=”001.js” type=”text/javascript”>
    </script>

    001.js
    alert(“hello”);

需要注意的一点是如果使用外部引用的方式,那么在页面引用外部文件的 script 标签之间是一定不能写代码的,浏览器不会那么聪明地认为我们是想既引用外部文件,也使用页面之中的 JavaScript 代码。

1.2 JavaScript中的注释、变量以及基本数据类型

注释:

每种语言都会有注释,因为使用注释可以极大地提高代码的可阅读性,Java 之中有三种注释,而 JavaScript 与之相比的话则没有文档注释,就只有单行注释和多行注释。

单行注释://
多行注释:/*    */

变量:

首先说一下,JavaScript 中的变量使用什么关键字声明,Java 之中可是有很多种关键字可以接受变量声明的,但是在 JavaScript 这里,由于它是一种弱类型语言,不管是基本数据类型还是变量类型,都统一使用 var 关键字进行接受,不过需要注意的一点就是 JavaScript 也是区分大小写的。

var i = 10;
var j = "hello";
var k = true;
var l = 10.34;

上面这几种写法都是正确的,因为 var 关键字可以接受所有的变量类型。至于变量名的取名规则就不在这里说明了,其实和 Java 中是一样的,并且在实际的开发过程中,最好使用见名知意的名字,并且使用驼峰式命名。

基本数据类型:

JavaScript 中的基本数据类型如下:

String        字符串类型。””和’’都是字符串。 JavaScript中没有单个字符
Boolean        布尔类型。  固定值为true和false
Number        数字类型。  任意数字
Null        它只有一个专用值 null,即它的字面量
Undefined    未定义类型,该类型只有一个固定值,即undefined,表示变量声明却未定义具体的值。

主要需要注意的一点就是:由于 undefined 是从 null 中派生出来的,所以 undefined = null

JavaScript 的编程当中,是可以将一个字符串复制给一个引用着数字的变量的,在 JavaScript 中这是合法的,而且为了判断一个变量当前引用的是什么类型的数据,也提供了一个运算符,那就是 typeoftypeof s =="string" 则是判断 s 是否是一个字符串。

1.3 JavaScript中的运算符

JavaScript 中的运算符对比与 Java 中的,大部分运算符的功能都是一样的,需要注意一下的就是比较运算符和逻辑运算符了。

比较运算符:

这里说明的便是 =======运算符比较两个变量是否相等的时候只比较两个变量的值,只要其中的值相等就返回 true ,否则就返回 false;而 === 运算符在进行比较两个变量的时候,不仅会比较两个变量的值是否相等,而且会比较这两个变量的数据类型,只有当值和数据类型都相等的时候才会返回 true,否则就会返回 false.

逻辑运算符:

逻辑运算符主要就是进行与运算和或运算,只不过在 JavaScript 中比较特殊的一点就是,没有 &|,只有 &&||

1.4 JavaScript中的正则表达式对象和数组对象

正则表达式对象:

JavaScript 创建正则表达式的两种方式如下:

第一种(创建对象方式):
    var patt1=new RegExp("正则表达式");
第二种(直接量方式):
    /^正则表达式$/

第一种方式因为要创建对象,所以并不常用,使用的比较多的还是第二种方式,其实也是一个正则对象,不用引号包裹。是用一对 / 包裹,^ 表示字符串开始,$ 表示字符串结束。

使用对象的 test(字符串) 方法,返回 true 就代表字符串符合正则表达式,否则就是不符合。

还有一种情况就是像 /正则表达式/ 这样的正则对象,与之前的差别就是没有开始和结束标记,使用这种正则对象的 test() 方法就表示只要字符串中的其中一个字符符合正则表达式就会返回 true,因此带有开始和结束标记的正则对象适合用于表单验证,而没有开始和结束标记的则适合用于字符串的查找和替换。

数组对象:

声明数组的几种方式:

1.var arr = [“hello”,3,5,true];
2.var arr2 = new Array();
3.var arr3 = new Array(3); //不推荐  数组的长度是3
4.var arr4 = new Array(“hello”,”a”);//不推荐 

使用的最多的还是前两种方式,要么直接给出元素值,要么就只是创建,具体的操作还是看程序的执行。

数组长度:

在开发的过程中,数组的长度是十分有用的,比如遍历数组,其实每个数组都会有一个 length 属性,可以获得数组的元素个数,也就是数组的长度。

不过如果想在 JavaScript 中直接清空数组的话那就要简单的多,直接将数组长度设置为 0 就好了。

数组的相关方法:

join() 方法:将数组之中的元素放入一个字符串当中,并且元素之间使用指定的分隔符进行分隔

reverse() 方法:将数组中的元素进行反转,即第一个元素和最后一个元素位置互换,第二个元素和倒数第二个元素位置互换,依次类推

pop() 方法:将数组中的最后一个元素删除并返回

push() 方法:向数组中添加一个或多个元素并返回数组的长度

1.5 JavaScript中的全局函数和自定义函数

其实很多东西都可以直接在 W3CSchool 的文档中查到,比如之前的数组和现在要说的全局函数,实际编程的时候,也最好像之前写 Java 程序一样,多去查询 API 等文档。

全局函数:

eval() 函数:这个函数需要传入的参数是一个字符串,而这个函数的作用就是将这个字符串转换为一个 JavaScript 表达式或者可执行的语句,可以是 "1+2" 这样的字符串,也可以是像 "var i =10;" 这样的语句,其实在这里举的两个例子都只是为了说明这个函数确实可以做到将字符串转换为像上面这样的 JavaScript 脚本去执行,但是在开发过程中,使用的最多的还是使用这个函数去解析 json 格式的字符串,就是将这一个字符串转换为一个 json 对象,因为前后台的交互使用 json 会十分方便,因此后台传过来的 json 数据就可以像这样直接传给前台的 JavaScript 去解析了,非常方便。

encodeURI()decodeURI() 这两个方法主要是用于对数据的编码和解码,之前已经提到过,我们在用 get 方式提交表单数据的时候,就可以看到诸如 "?username=kobe&password=lakers"这样的数据,也提到过一个问题,那就是如果 username 对应的值如果是 kobe&paul,那是不是在提交到后台的时候就会发生解析错误呢?可是并没有啊,那是为什么呢?就是因为在前台提交的时候经过了 encodeURI() 函数编码,然后在后台的时候经过了 decodeURI() 解码,因此 username 对应的值中即使存在像 & 这样的字符,也会被转换成别的字符序列,因此就不会出现问题了。

parseInt(string)parseFloat(string) 这两个函数一看到就感觉很熟悉,就是因为之前在 Java 中存在类似的方法,也是将字符串转换为对应字面的整形数值或者浮点型数值,那进行转换的过程是怎样的呢?其实是一个字符一个字符进行转换的,直到碰到不能转换的字符为止,就将前面能够转换的字符转换成数值,并作为结果进行返回,那要是一开始就碰到一个不能转换的字符呢?那就会直接返回一个 NaN,意思就是 Not a Nomber,表明不是一个数字。

自定义函数:

自定义函数有两种创建方式,如下可以看出区别:

方式一:
    function 函数名(函数参数列表){
        函数体;
    }
例子:
    function sum(a,b){
        return a+b;
    }

方式二:
    var 函数名 = function(参数列表){
        函数体;
    }
例子:
    var sum = function(a,b){
        return a+b;
    }

关于函数需要注意的几点:

  1. JavaScript 的函数其实都是有返回值的,当函数体中没有写 return 和只写 return; 的时候,其实是默认的返回 undefined

  2. JavaScript 中不存在函数重载,即使有多个函数重名,那也只会发生覆盖,即后面一个函数覆盖前面一个函数,所以只会保留最后一个函数

  3. JavaScript 中的函数被调用的时候不会看参数列表的个数,而只会看函数名,即使参数列表有两个参数,而调用的时候没有传入参数,那也是可以的,只是其中的参数没有值而已

1.6 自定义对象

先看自定义对象的第一种方式吧,格式和自定义函数是一样的

function Animal(){

}

function Person(name,age){
    this.name = name;
    this.age = age;
}

这两种方式都是可以的,与 Java 中的对象不同,Java 中创建对象是以类为模板的,而类定义了哪些成员变量和成员方法,那每一个新建出来的对象就有哪些成员变量和成员方法,但是 JavaScript 中却不一样,像上面的 Animal 对象,里面一个成员变量都没有,但是在接下来的编程中还是可以这样写:

var animal = new Animal();
animal.name = "大熊猫";
animal.age = 3;
alert(animal.name+","+animal.age);

这样写一点问题都没有,而且还可以在浏览器中完美运行,打印出对象的姓名和年龄,有时候感觉 JavaScript 真是太灵活了,不仅在这里可以看出来,其实在之前的数组中也可以看出,JavaScript 中的数组和 Java 中的集合很像,但是关于 JavaScript 的数组,如果最开始声明一个数组只有 3 个元素,当我想直接给这个数组的第 5 个元素赋值的时候,绝不会像 Java 中那样出现数组下标越界异常,它会直接给这个数组的第 5 个元素赋值,而且数组的长度也变成了 5,其中没有赋值的元素仍然默认是 undefined,并且在 JavaScript 的数组取值也是一样的,数组长度是 3,取第 5 个元素,也不会发生异常。

关于第二个对象 Person 的声明,运行下面的程序也没有问题。

var person = new Person("博人",10);
alert(person.name+","+person.age);

关于上面创建自定义对象的方式,理解起来还是和 Java 中的方式有的像的,不过下面创建自定义对象的直接量方式,也就是 json 方式,也是很重要的内容,因为以后开发中 json 会用到很多。

var person = {
    name:"kobe",
    age:40
};

对,就是这一种方式,属性与属性值之间以键值对的方式排列,而且不同的属性之间使用逗号 , 相分割。还可以看一下下面的代码:

person.name = "paul";
person.age = 34;
person.sex = "男";
alert(person.name+","+person.age+","+person.sex);

也是可以完美运行,这样就可以看出 json 这种方式的灵活性。

2.BOM(浏览器对象模型)

这就是想介绍的关于 JavaScript 的第二部分—浏览器对象模型,听名字就可以猜出,这个的主要作用是和浏览器打交道的,之前我们输出自定义对象的各个属性值时,是使用的 alert(person.name+","+person.age+","+person.sex); 这样的方式将值在浏览器中弹出显示的,其实这个 alert() 方法就是 BOM 中的 window 对象的一个方法,作用就是就是在浏览器中弹框显示数据。

上面的 alert() 就是一个警告框,其实 window 对象中还有一个确认框,那就是 confirm() 方法,其中也可以传入一个字符串参数,一般都是一个询问的语句,在浏览器的显示效果就是一个弹框,显示上面的询问语句,语句下面就还有两个按钮,一个确认按钮,一个取消按钮,如果用户选择的是确认按钮,那么 confirm() 方法将会返回 true,而如果用户选择的是取消,则会返回 false

BOMwindow 对象还有两个定时器方法,一个是循环定时器,另一个则是一次性定时器。

循环定时器:
    设置:var id = setInterval("函数名()",时间(以毫秒为单位));
    清除:window.clearInterval(id);
一次性定时器:
    设置:var id = setTimeout("函数名()",时间(以毫秒为单位));
    清除:window.clearTimeout(id);

关于浏览器的话就还有一个很常见的功能,便是页面的前进和后退,这次要使用的便是 window 中的 history 对象,先看下面的代码示例:

window.history.go(-1);         //返回上一页
history.go(1);                //转到下一页
history.back();                //等效于 history.go(-1);
history.forward();            //等效于history.go(1);

当然要使用这个对象来控制浏览器中页面的上一页和下一页,前提肯定是需要浏览器之中已经有了浏览记录,这样才能展示上述的效果。

最后想说的一点是关于在 HTML 页面之间进行跳转,就要使用 window 中的 location 对象,其中的 href 属性便可以设置要跳转到的页面。

location.href = url;

3.DOM(文档对象模型)

在实际的编程开发中,除了 JavaScript 的基础语法之外,DOM 就是运用的最多的了,因为为了展示与用户进行交互的效果,就必然要使用 JavaScript 来操作 HTML 网页之中的标签、文本以及属性,而这上面的三个部分,在 DOM 的概念之中就刚好是相对应的节点(元素节点、文本节点、属性节点),使用 DOM 中的对象来操作它们会变得非常简单。

其实当一张 HTML 网页被加载到内存中时就会被看做是一棵 DOM 树,而页面之中的标签、文本以及属性就会被当做一个一个的节点,它们之间有父子关系,也有兄弟关系。

3.1 获取元素节点对象

在实际编程的过程中,只有先获得网页中的元素,才能对它进行修改,而表示当前文档对象的 document 提供了多种方法用来获取文档之中的元素对象,先列在下面:

1.getElementById()
2.getElementsByName()
3.getElementsByClassName()
4.getElementsByTagName()

第一个方法 getElementById() 是通过元素的 id 属性来获取元素对象,因为一般元素的 id 都是唯一标识一个元素的,因此调用该方法获得的是一个对象,而不会像其它方法获得一个对象数组。

第二个方法 getElementsByName() 与第一个方法相类似,这次是通过元素的 name 属性来获得对象,不过由于可以有多个元素的 name 属性取同一个值,因此这个方法返回的会是一个对象数组,想取得其中的某一个元素对象的话就要使用数组获得数组中元素的方法了。

第二种方法是通过元素的 name 属性来回去对象,而这第三种方法则是通过元素的 class 属性来获得元素对象,和第二种方法相类似的是,由于多个元素的 class 属性取值也可以是一样的,因此这个方法返回的也是一个数组。

第四种方法是通过元素的标签名来获得元素对象,比如通过 div 或者 font 标签,一个网页中有多个相同标签是十分常见的事,因此这个方法返回的也是一个数组。

其实解释完上面的四个方法,突然感觉这不是和 CSS 之中的选择器差不多吗,都是为了获得网页之中想要获取的标签,只不过 CSS 是为了美化修饰页面,而 JavaScript 是为了做与用户进行交互的动态效果之类的,不过还是很容易看出相似点的。

获取元素节点对象注意点:

有一个容易犯错的地方就是,放在 head 标签之中的 script 标签,其中也写了 JavaScript 代码,比如说是一个获取网页中某元素标签,比如 var obj = document.getElementById("oid");,而 id 属性的属性值是 oid 的元素标签也确实存在于 body 标签之中,但是在运行的时候,上面获取元素的代码获得的一直是 null,这是怎么回事呢?先说解决方法,将 script 标签封装的代码移到 body 结束标签之前,或者将获取元素对象的代码放在一个函数之中,当想获取那个元素的时候去调用该方法,这样就可以解决问题了。那导致问题出现的原因是什么呢?其实是和浏览器加载页面的顺序相关,浏览器是从上往下依次解析网页,当解析到 head 标签之中的 JavaScript 时,此时在该标签之后的网页内容根本就还没有加载进内存当中,现在运行代码,获得的当然是 null 了,移动 script 标签的位置就是针对的这一点,将代码封装在函数中也可以解决问题,因为只有当页面完全加载完了之后我们才会去调用方法,其实实际开发之中封装函数还是用的比较多的,因为封装函数之后,便于复用,写注释之后,也能对这块代码的作用有很好的理解,要比一大块代码简单得多。

3.2 元素对象的常见属性

元素样式相关属性:

如果想要使用 JavaScript 对某元素的显示样式进行修改,应该怎么做?步骤就是:首先获得要修改的元素对象,上面已经给出了四种方式,第二步就是修改元素样式了,在 JavaScript 中修改元素样式也主要是动态地去修改元素的与样式有关的属性,主要由下面三种:

1.元素对象.className = "ys1";
2.元素对象.style.fontSize = “50px”;
3.元素对象.value

第一种是修改元素中 class 属性的属性值,修改为假设已经定义的样式表 ys1,那这样就可以修改元素的样式了,就是换作用样式表 ys1 中的属性值来修饰被选中的元素;第二种是直接修改元素的具体属性,而 fontSize 属性因为与样式有关,所以也就修改了样式;第三种是修改元素的值,即样式表需要修饰的值。

元素其它相关属性:

这里还有一些常见属性需要说明一下,比如使用 JavaScript 选择单选框中的一个或者复选框之中的多个,首先选中那个想要选择或者取消选择的选项,比如 option,然后每个选项都会有一个 checked 属性,如果想选中就要将该属性赋值 true,取消选择的话就赋值为 false

还有一个很重要的属性就是 innerHTML ,它代表的是选择标签的内容体,不仅可以赋值一些普通文本,而且还可以是 HTML 中的元素标签,比如在选择的 div 标签之中加一个 font 标签和文本,而且赋值成功后,浏览器还会将它们作为 HTML 标签来解析,那这个作用就十分大了,平常开发中也用的比较多。

4.JavaScript事件

JavaScript 中的事件是十分常见的,比如单击浏览器之中的一个按钮,然后弹出一个带有提示信息的提示框,这就是一个事件啊,当然具体实现功能的时候不会是做这样的效果啊。

4.1 JavaScript事件驱动机制

解释事件驱动机制就是为了来说明一个事件从发生到完成的过程的,主要分为以下几部分:事件源、事件、监听器和绑定监听器。以鼠标单击事件来说明:

1.事件:点击鼠标
2.事件源:Button
3.监听器:function run() {}
4.注册监听器(绑定监听器)  onclick="run()"

下面介绍一下 JavaScript 已经定义好的常见事件吧。

单击事件:

绑定点击事件需要添加一个 onclick 属性,并且该属性的属性值应该设置为绑定该元素的函数方法。

onclick="run()"

焦点事件:

焦点事件分为获得得焦点和失去焦点两部分,获得焦点就是当鼠标移动到相关元素上面,而失去焦点则是鼠标离开相关元素。

获得焦点事件绑定:onfocus="run()"
失去焦点事件绑定:onblur="run2()"

域内容改变事件:

域内容改变事件就是当我们选中的元素之中的内容发生改变时,就会触发该元素绑定的函数事件,比如可以是一个文本域,每当这个文本域中的值发生改变时,就会调用相应的方法。

onchange="run()";

加载完毕事件:

之前提到过一个问题,就是由于浏览器解析代码的顺序是由上往下的,因此可能某些代码获取网页之中的对象一直为 null,其实也可以将上面获取元素对象的代码放在一个函数之中,然后在 body 标签之中加入加载完毕属性 onload,并将该属性的属性值设置为上面的函数,那这样就可以顺利获得元素对象了,其中的原因就在于 onload 属性的作用就是在页面加载完成之后就去调用它所绑定的函数。

表单提交事件:

表单提交属性是用在表单标签之中的,当用户点击 submit 按钮时,就会触发表单提交属性 onsubmit 中的函数,不过这里有点特殊的地方就是,这里绑定函数的时候不是直接写函数名,而是 return 函数名(),如下面这样:

<form onsubmit="return run()" />

当调用的绑定函数返回的是 false 时,那么这个表单就会取消提交,如果是 true,则可以进行提交,这种方式在验证表单输入的时候很有效,有不合法的输入项便取消输入。

键位事件:

下面要说明的两个事件是关于键盘输入的,我们打字时肯定会有键盘按下和键盘抬起这两个事件,在 JavaScript 中这两个事件对应的就是 onkeydownonkeyup,只要为这两个属性绑定相应的函数,那么当上面的键位事件发生时,就会调用相应的函数。

鼠标事件:

这里还想说明三个关于鼠标的事件,主要是以下这些:

onmousemove:鼠标移动事件
onmouseout:鼠标从某元素之中移开事件
onmouseover:鼠标被移动到某元素之上

4.2 JavaScript事件绑定方式

上面介绍 JavaScript 的事件驱动机制所举的例子,在绑定函数的时候都是使用的 "句柄绑定" 方式,使用句柄绑定有很多优点,第一、传参十分方便,第二、可以绑定多个方法,方法执行的顺序就是绑定时设置的顺序。

<input type="text" onclick="fun1(),fun2('hello'),fun3(this)" />

不过使用句柄绑定方式也有缺点,那就是 JavaScriptHTML 代码耦合度太高,不利于开发。

下面便介绍另一种方式:DOM 绑定方式。举个例子说明吧:

window.onload = function(){
    var text = document.getElementById("text1");
    text.onclick = function(){
        alert("我确实被点击了!!!");
    }
}

这样就能使 JavaScriptHTML实现分离,便于多人进行开发合作。

JavaScript事件绑定方式
    1.句柄绑定
    2.DOM绑定

5.总结

感觉这篇文章写的有点多,不过虽然写的很多,却还是有很多重要的部分还没有涉及到,以后肯定也还是要再写别的文章介绍的,这篇文章还只是一个初级的介绍说明,想要熟练地使用 JavaScript 进行开发,还要敲很多代码去运用,以及看很多书去扩大知识面,现在就当把基础打好吧,以后学别的进阶内容也会快一点。

坚持原创技术分享,您的支持将鼓励我继续创作!