1. js代码,网页代码是从上到下依次执行的。
为了避免网页的延迟,一般JS代码放在页面中后面,因为,若js代码放在中,意味着必须等到所有的JS代码被下载、解析、执行完之后,才开始呈现页面中的内容,如果JS代码量很大的话,会导致浏览器在呈现页面内容时出现明显的延迟。
也可以在<script>
标签定义defer属性。这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完成之后再运行。相当于告诉浏览器,立即下载,但是延迟执行。
2. 如果一个< script>块中有语法错误,则整个该script块中的代码都不执行了,但是不会影响其他块。
3. 基本语法介绍:
- 大小写敏感
- 一般字符串推荐用单引号引来。
- 声明变量的时候不需要写数据类型,统一使用var声明。因为js数据类型是弱类型的语言。
- 每条语句都应该以 “;” 结尾。
- JS代码注释和C#相同。
- JS智能提示仅仅作为参考。
4. JS数据类型:
JS中共有六种数据类型。
- Boolean(布尔) :true 或false;
- Number(数字): 包含所有数字,范围相当于double;
- string (字符串): 所有字符串;
- Undefined(未定义): 取值:只有一个值undefined,在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined.
- Null(空对象), 取值:只有一种取值,null。
- Object(对象类型) : 取值:任和对象、Array、function等等。
typeof 操作符可以用来检测给定变量的数据类型。
5. 在JS中if-else、while、do-while、for 、switch、continue、break语句几乎与C#语句一致。
for 循环演示:
<script type="text/javascript">
var sum=0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
alert(sum);
</script>
if语句:
<script type="text/javascript">
function check()
{
var name = form1.tbname.value;
var pwd = form1.tbPassWord;
if((name=="")||pwd==null)
{
alert("请输入用户名!");
form1.tbname.focus();
return;
}
else if((pwd=="")||(pwd==null))
{
alert("请输入密码!");
form1.tbPassWord.focus();
return;
}
else
{
form1.submit();
}
}
</script>
continue跳转语句:
continue语句与break语句类似,不同之处是,break语句退出循环,continue语句用于终止本次循环并开始下一次循环。
6.JS中的== 与 ===
- 相等运算符: == 、(!=)
- 完全相等运算符: === 、(!==)
===运算符 判断前不进行类型转换,并且 ===两边必须类型相同,值也相同的情况下才返回true。
switch(s) 内部使用的是 ===严格等于来判断是否相等。
7. JS中变量作用域
JS中不存在块级作用域范围。在页面中声明的变量,在整个页面中任何一个地方都可以访问。
function f1(){
//在JS中不存在块级作用域范围,所以在方法内部任何一个地方声明的变量,都在整个方法内部有效,
var x=10;
if(x>5){
var y=100;
alter(y) //100
}
alter(y) //100 因为JS中不存在块级作用域,因此此处可以打印出100
}
f1();
alter(y) ; //未定义,此处已经在函数之外,超出作用域范围。
声明变量的时候如果不写var关键字,表示该变量是一个整个页面都能访问的变量。
因此,声明变量的时候一定要加上var,避免使用“全局变量”。
8 JS中的函数
8.1 函数的定义
- 函数定义时必须写function关键字。
- 无返回值类型
- 无参数的类型
- JS中函数永远有返回值,如果没有执行return语句,则返回值为Undefined.
//定义函数
function getMessage(id) {
return id+':hello';
}
//调用函数。
var msg = getMessage('0001');
8.2 函数和变量的预解析功能
JS中没有函数重载的概念。
1.函数的预解析功能:
arguments
<script type="text/javascript">
function f1(){
alert('first f1') ;
}
function f1(name){
alert(name) ;
}
f1(); //此处调用函数f1()方法的输出结果是 undefined
//因为JS中没有函数重载的概念,所以遇到同名的函数,会用最后一次函数定义覆盖掉前面的函数定义。
//所以调用f1()函数其实是调用最后一次函数定义,但是最后一个函数定义需要传递一个参数给name,调用时没有传递参数,所以name变量没有赋值,所以就是undefined;
//如果不确定函数中将要传递的参数的个数,那么可以使用类似于C#中可变参数的解决办法。在JS中叫做arguments对象。
//其实所有的方法都无需定义形参,定义形参的目的仅仅是为了使用方便。
//无论是否定义了“形参”,在实际调用该函数的时候,所有的参数都包含在了arguments对象中。
function add(){
var sum = 0;
//循环遍历累加的每个参数的值。
for(var i = 0; i<arguments.Length; i++){
sum+=arguments[i];
}
return sum;
}
var result = add(11); //结果为11
</script>
因为函数有“预解析(在一个标签之内)”功能,所以在执行之前会将所有的函数进行预解析。与预解析的时候,同名的函数,则最后定义的函数会覆盖前面定义的函数。
前面标签块中写的函数,后面标签块都能调到,但是后面块中写的函数,前面的标签块是不能调用的。
2 .参数的预解析功能:
由于下面的原因,在函数的一开始,就应该把所有的要使用的变量都声明好
var user_name = 'wang' ;
function f(){
alter(user_name); // 打印结果为: undefined;
// 因为:
// 1. 在函数内部声明的变量整个函数中都可以使用。
// 2. 如果遇到"局部变量"与"全局变量"冲突的情况下,优先使用"局部变量"。
// 3. “变量” 与“函数” 具有同样的预解析功能,在函数的代码执行之前,先会解析函数中声明的所有变量。然后在执行该函数。也就是说在执行第一句代码: alter(user_name); 的时候,局部变量 user_name 已经声明了。但是没有赋值(因为预解析只解析声明,不包含赋值语句。)
var user_name = 'yzk';
alter(user_name); // 结果为: yzk
}
f1();
alter(user_name); // 结果为 wang
9. 匿名函数
<script type="text/javascript">
//在JS中声明匿名函数
//一、第一种匿名函数的写法
// 把一个匿名函数赋值给了一个变量f1,此时的f1是变量名,不是函数名。
// 因为下面的语句是赋值语句,所以需要在最后加上一个“分号”;
// 定义函数的时候是不需要加“分号”的;
var f1= function () {alert('这就是匿名函数')};
f1();
// 二、匿名函数的第二种用法: 定义匿名函数的时候直接调用该函数。
(function (x, y) { alert(x + y);})(10,50);
// 三、第三种匿名函数的写法:
var f1 = new Function('x', 'y', 'z', 'alert(x+y+z)'); //最后一个参数是方法体。
f1(10, 20, 30);
</script>
9 数组
9.1 数组的声明:
一、声明数组并初始化:
<script type="text/javascript">
var numbers = [1, 2, 3, 4, 5]; //声明数组
alert('数组长度为:'+numbers.length); //数组长度
//循环遍历输出每个数组元素
for (var i=0;i<numbers.length;i++){
alert(numbers[i]);
}
//当调用数组对象的tostring()方法时,会返回一个字符串,该字符串是以“逗号”隔开的每个数组元素组成的;
alert(numbers.toString());
</script>
二、声明空数组
<script type="text/javascript">
var data = []; //声明一个空数组。
data[0] = 12;
data[1] = 120;
data[20] = 11; //设置完这句话后,数组长度即变为21;
data[data.length] = 'a';
data[data.length] = 'b';
alert(data.length); //数组长度。
//将1~50之间的偶数存放到data数组中。
for (var i = 1; i <= 50; i++) {
if(i%2==0)
{
data[data.length] = i;
}
}
alert(data.toString());
</script>
三、其他声明方式
<script type="text/javascript">
var arr = new Array(5);
alert(arr.length); //声明了一个长度为5的数组。
</script>
例1. 使用函数对数组进行升序排序
例一、冒泡法进行排序。
<script type="text/javascript">
//对数组进行升序排序;
var arrInt = [5, 6, 43, 2, 45, 6, 34];
fnSortAsc(arrInt);
alert(arrInt);
function fnSortAsc(arrayObject) {
var temp;
for (var i = 0; i < arrayObject.length - 1; i++) {
for (var j = arrayObject.length - 1; j >i; j--) {
if (arrayObject[j] < arrayObject[j - 1]) {
temp = arrayObject[j];
arrayObject[j] = arrayObject[j - 1];
arrayObject[j - 1] = temp;
}
}
}
}
</script>
例二、 求数组元素的平均值
<script type="text/javascript">
//计算数组中元素的平均值
var arrInt = [5, 8, 1, 4, 9, 3, 7, 2, 6];
var avg = fnAverage(arrInt);
alert(avg);
function fnAverage(arrayObject) {
var sum = 0, i;
for (i=0;i<arrayObject.length;i++) {
sum += arrayObject[i];
}
return sum / arrayObject.length;
}
</script>
例三 求数组中的最大值
<script type="text/javascript">
//求数组中的最大值
var arrInt = [5, 8, 1, 4, 9, 3, 7, 2, 6];
var max1 = fnMAX(arrInt);
alert(max1);
function fnMAX(arrayObject) {
var max=arrayObject[0], i;
for (i=1;i<arrayObject.length;i++) {
if (arrayObject[i] > max) {
max = arrayObject[i];
}
}
return max;
}
</script>
例四 将数组元素用‘|’分隔开
<script type="text/javascript">
//将数组元素竖线分割
var arr = ['乔丹', '科比', '姚明'];
var result = fnJoin(arr,'|'); //调用内置函数;
alert(result);
function fnJoin(arr,separator) {
var str='', i;
//1.遍历数组中的每个元素;
for (i = 0; i < arr.length - 1; i++) {
//2.使用指定的分隔符拼接字符串;
str = str + arr[i] + '|';
}
str = str + arr[arr.length - 1];
//3.返回
return str;
}
</script>
9.2 数组,键值对集合
<script>
var dict = new Array();
dict['jk'] = '运费';
dict['王云飞'] = 'www';
dict['xl'] = 'xl';
dict[0]='张三';//普通的数组也可以看作是一个特殊的键值对。
//根据键查找值
alert(dict['jk']);
//遍历键值对数组
//输出dict的长度
alert(dict.length); //如果只是键值对数组,那么length的值为0,所以无法通过for循环遍历,
所以这时遍历键值对数组要使用for-in循环。(类似于foreach循环)
//for-in循环
for (var key in dict) {
//遍历dict中的每一个键
alert('键:' + key + ' 值是' + dict[key]);
}
</script>
//----------------键值对集合的一个简单方式:对象字面量----------------
var dict = { 'jk': '姜昆', 'wyf': '王云飞', 'xjj': '徐佳佳' };
for (var key in dict) {
alert(key + " " + dict[key]);
}
JS中面向对象编程
通过函数function来实现,不存在类这个概念。
<script>
//这是一个函数。也可以叫做“函数对象”
function Person(name,age,emile) {
this.user_name = name;
this.user_age = age;
this.user_emile = emile;
this.sayHellow = function () {
alert(this.user_name+' '+this.user_age+' '+this.user_emile)
}
}
//对Person函数可以直接调用,直接调用就是把Person()当做一个函数来使用
//例如:
Person(); //把Person当做一个普通的函数来调用
//第二种方法:把Person函数当做“类”来使用,通过Persion函数创建一个Person类型的对象。
//当调用Person函数前加new关键字,表示要通过Person()函数创建一个对象。此时,一般把Person()函数叫做“构造函数”。
//也就是说,当我们直接调用一个函数的时候,那么就叫函数,当通过new关键字调用一个函数的时候,这个函数就叫构造函数,(不叫“类”)。
var p = new Person('王云飞',26,'123456'); //这样就创建了一个Person类型的对象P
//当定义一个函数的时候,如果要将该函数作为“构造函数”来使用,那么函数的命名就应该采用“帕斯卡”命名法(每个单词的首字母都大写)。如果定义函数的时候就确定,将来该函数只会作为一个普通函数来调用,那么就采用“驼峰命名法”。
p.sayHellow();
</script>
9.5 原型对象prototype
正常的情况如下所示:
每次通过Person创建的对象,都是一个完全独立的对象,对象和对象之间是没有关系的。其中的方法、属性都是独立的。
<script>
function Person(name, age, email) {
this.user_name = name;
this.user_age = age;
this.user_email = email;
this.sayHi = function () {
alert('hi!我是:' + this.user_name + ' , ' + this.user_age + ' , '+this.user_email);
};
this.sayHellow = function () {
alert('Hellow');
};
}
//每次通过Person创建的对象,都是一个完全独立的对象,对象和对象之间是没有关系的。其中的方法和属性都是独立的。
var p1 = new Person('gyt', 18, '1234@.com');
p1.sayHi();
var p2 = new Person('whs', 19, '4321@.com');
p2.sayHi();
</script>
存储空间的占用如下图所示:
使用prototype之后:
<script>
function Person(name, age, email) {
this.user_name = name;
this.user_age = age;
this.user_email = email;
}
//将方法存储到prototype原型对象。
//函数对象本身具有一个属性,prototype,
Person.prototype.sayHi = function () { //匿名函数。
alert(this.user_name + ' , ' + this.user_age + ' , ' + this.user_email);
}
var p1 = new Person('aaaa', 18, "123@.com");
p1.sayHi();
var p2 = new Person('bbbb', 19, "bbb@.com");
p2.sayHi();
</script>
原型对象prototype是只读的,不能改。
9.4 JS中的继承
在JS中没有类的概念,继承是通过对象和对象来实现的
<script>
//1.在JS中没有类的概念,继承是通过对象和对象来实现的
function Person(name, age, email) {
this.user_name = name;
this.user_age = age;
this.user_email = email;
}
Person.prototype.sayHi=function(){
alert(this.user_name + ' , ' + this.user_age + ' , ' + this.user_email);
}
function Student() {
this.student_id = sid;
}
var p1 = new Person('张三', 12, '1111111');
//继承(继承是通过对象与对象之间实现的)
//继承的关键性语法。
Student.prototype = p1;
//创建student对象。
var s1=new Student('10001');
s1.user_name='wangyunfeu';
s1.user_age=27;
</script>
9.5JS中的事件
JS中也有事件的概念,触发什么事件,执行什么代码。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script>
</script>
</head>
<body>
<span>为按钮添加单击事件</apan>
<input onclick="alert(new Date().toLocaleTimeString());" type="button" name="name" value="显示当前时间"/>
</body>
</html>
9.6 JS中的“this”:
当一个函数注册给不同对象的时候,在调用时,函数中使用的this表示的是不同的对象。
<script type="text/javascript">
function f1() {
alert(this);
}
//f1();
//因为直接在页面上定义的函数其实默认就是注册给了window对象
//所以直接f1()调用函数和通过window.fa()来调用函数是完全一样的。
//正因为f1()函数是window对象函数,所以在f1()函数内部this就是表示的window对象。
//也就是说:在一个函数内部,this表示的是哪个对象,取决于当前函数是哪个对象的函数。
window.f1();
function Person() {
this.toString = function () {
return 'Person类型';
};
}
var p1 = new Person();
alert( p1.toString());
p1.fn = f1; //将f1函数赋值给p1新加的属性fn
p1.fn();
</script>