是什么:What
是一种脚本语言,用于执行网页上的动作
(内容由 HTML 语言书写,格式由 CSS 规范,动作由 JS 来执行)
JS 是一种解释性的语言,与 Java 这种强类型的语言无关
特点是什么
- 解释性语言
适用/不适用场合
。。。
如何编写
Hello World
在 <body></body>
中放入如下代码
<!--first JS-->
<script>
document.write("Hello World");
</script>
字符串输出
在 document.write("Here is the string for output.")
中的字符串是 HTML 流,即可包括 <br/>
等 HTML 标签
注意:
- 在
document.write()
中,换行应该通过在字符串中用<br/>
输出;输出转义字符\n
在这里无法起到换行的效果;在- 在
alert()
中,换行字符则使用\n
变量定义
- JS 中使用
var VariableName = Value
来把值 Value 赋予变量 VariableName - 值有类型,变量则不需要事先规定类型
- JS 中,变量作用域只有 2 个空间:函数内部空间,全局空间
<!--variable setting-->
<script>
var HW;
HW = "Hello World";
document.write(HW);
//same effect as 'first JS'
</script>
判断
if-else statement
类似 C/C++
if (expr1){
//do something
}
else if (expr2){
//do something
}
else{
//do something
}
示例如下
<script>
var age = 20;
var ADULT = 18;
var teenage = 12;
document.write("Your age is " + age + ".");
if (age >= ADULT){
alert("Adult.");
}
else if (age >= teenage){
alert("Teenage.");
}
else{
alert("Children.")
}
//page message: "Your age is 20."
//alert message: "Adult."
</script>
关系运算符(三元运算符)
<expr>?<v1>:<v2>
//the same effect as:
//if (<expr>)
//{v1}
//else
//{v2}
例如,这这段代码
max = (a > b)?a:b;
与这段代码效果一致
if (a > b)
{
max = a;
}
else
{
max = b;
}
case-switch statment
类似 C/C++
switch(VariableName){
case value1:
//code block 1
break; //otherwise the code below will run.
case value2:
//code block 2
break; //otherwise the code below will run.
default:
//code block 3
}
逻辑运算符
- and:
&&
- or:
||
- not:
!
循环
while loop
类似 C/C++
while(expr1){
//while expr1 == true, do something
}
do-while loop
类似 C/C++
do{
//do something
//if expr1 == true, loop; else, break
}while(expr1)
for loop
类似 C/C++
for (init; condition; step){
//do something
}
例如
for (i = 0; i < 5; i++){
document.write(i);
}
//print 01234
break
控制效果与 C/C++ 一致
contuine
控制效果与 C/C++ 一致
函数
定义方式
function fun_para_0(){
document.write('function without any parameters.');
}
function fun_para_1(a){
return (a + 10);
}
function fun_para_2(n1, n2){
document.write(n1 + n2);
}
fun_para_0();//function without any parameters.
document.write(fun_para_1(15));//25
fun_para_2(1, 2);//3
函数变量
var f = Function("x", "y", "return x*y");
//seems same effect as
//
//function f(x, y){return x*y;}
//
//may be useful in advanced applications one day, use function as variable
重复定义与调用
后面的函数定义将覆盖之前的函数定义:意思是无论你定义+调用多少次函数 myf1
,总之所有对 myf1
的调用都将以最后一次对该函数的定义为准。例如如下的 HTML 代码配合如下的 JS 代码,输出的效果如图所示:
HTML 代码:
<html>
<head>
<title>js03</title>
</head>
<body>
<p> hello js03 </p>
<script src="run.js"></script>
<script>
function my_func(){
document.write(1);
}
my_func()
document.write("<br>");
function my_func(){
document.write(2);
}
my_func()
</script>
</body>
</html>
JS 代码:
function myf1()
{
var i = 7;
while (i >= 0)
{
document.write("This is number " + i + ".<br/>");
i--;
}
}
myf1();
document.write("------when overridden------<br/>");
function myf1()
{
document.write("Hello world! This is js03.");
}
myf1();
document.write("<br/><br/>THE END.");
效果图:
数组
定义方式
var a = new Array();// way 1
var b = new Array(size);// way 2
var c = new Array(digit_1, digit_2, ..., digit_n);// way 3; if only one parameter, the sentence will be treated as way 2
var d = [digit_1, digit_2, ..., digit_n]; // way 4
数组长度
var ar = new Array(100);
document.write(ar.length); // print 100
尾部添加元素
var ar = new Array(size);
ar[ar.length] = Elem0;
``
> 以字符串形式输出数组的 4 种方式
```JS
var ar = ['W', 'H', 'O'];
alert(ar); //way 0
alert(ar.toString());//way 1. same effect as way 0
alert(ar.valueOf());//way 2. same effect as way 0
alert(ar.join(char));//use char to connect each element of the array
堆栈操作
var ar = new Array();
var count = ar.push(item0, item1, item2); //item0 is on the bottom; count == 3
var topItem = ar.pop(); //topItem == item2
队列操作
var ar = new Array();
var count = ar.push(item0, item1, item2); //item0 is on the bottom; count == 3
var topItem = ar.shift(); //topItem == item0
排序
按字符串顺序,从小到大排序
var values = ['hello', 'gello', 'hellp'];
values.sort();
alert(values); // gello, hello ,hellp; if values == [0,1, 5, 10, 15], here is: 0, 1, 10, 15, 5
按输入顺序反向输出
var values = ['hello', 'gello', 'hellp'];
values.reverse();
alert(values); // hellp, gello ,hello
连接数组
var values = ['k','i','s','s'];
var obj = ['y', 'o', 'u'];
var hello = values.concat(obj);
alert(hello);//k,i,s,s,y,o,u
数组切片
左闭右开
var values = ['k','i','s','s'];
var hello = values.slice(1, 4);
alert(hello);//i, s, s
splice(开始位置, 删除个数, 插入元素0, 插入元素1, ...)
删除
var values = ['k','i','s','s'];
values.splice(0, 2);
alert(values);//s, s
插入
var values = ['k','i','s','s'];
values.splice(values.length, 'you');
alert(values);//k,i,s,s,you
替换
var values = ['k','i','s','s'];
values.splice(1, 2, 'a', 'i');
alert(values);//k,a,i,s
对象
定义对象
var obj1 = new Object();//way1
var obj2 = {x:1, y:2, z:3}//way2
删除对象属性
delete obj2.x;
document.write(obj2.x)//undefined
或者
obj2.x = null;
document.write(obj2.x)//null
遍历对象属性
obj = {name:"Potter", age: 14, gender: "male"};
for (var x in obj){
document(obj[x] + "<br>");//random access in object
}
//print:
//Potter
//14
//male
构造函数
- 不直接制造对象
- 用 this 来指代构造出的对象,用于定义成员
- 没有 return
function ClassName(para_1, para_2, ...){
this.attrib_1 = para_1;
this.attrib_2 = para_2;
//...
this.attrib_n = function(){
//use this.attrib_1, ..., this.attrib_i, otherwise this.atrrib_n returns a value which doesn't change when this.attrib_1, ..., this.attrib_i change.
//For example, it will keep the value counted using para_1, ..., para_i.
};
//etc.
}
var obj = new ClassName(p1, p2, ...);
注意构造函数内部的方法应使用函数属性,而非参数。否则内部方法导出的值不随着属性的改变而改变。考虑如下两段代码的输出差异:
如下代码输出 50, 100:
function Rect(w, h){
this.width = w;
this.height = h;
this.area = function(){
return this.width * this.height;
};
}
var r0 = new Rect(5, 10);
alert(r0.area());
r0.width = 10;
alert(r0.area());
如下代码输出 50, 50:
function Rect(w, h){
this.width = w;
this.height = h;
this.area = function(){
return w * h;
};
}
var r0 = new Rect(5, 10);
alert(r0.area());
r0.width = 10;
alert(r0.area());
原型对象
使用 prototype
可为对象原型(而非实例 instance)增加属性,例如
function Person(){} //构造了一个空对象
Person.prototype.name = "Default Name" //此后,所有 Person 对象均有 1 个新属性,属性名 name,初始值 "Default Name"
Person.prototype.gender = "Female" //此后,所有 Person 对象均有 1 个新属性,属性名 gender,初始值 "Female"
var person1 = new Person();//person1.name == "Default Name", person1.gender = "Female"
var person2 = new Person();//person2.name == "Default Name", person2.gender = "Female"
person1.name = "Harry Potter"; // person1.name == "Harry Potter"; 不影响 person2
Person.prototype.gender = "Male";//此后,person1.gender == "Male",person2.gender == "Male"
Person.prototype.age = 14; //此后,person1 增加了 1 个属性 age,值为 14;person2 也有同样的效果
注意一个问题:使用原型后,在实例为原型设定的属性赋值之前,所有实例的属性是指向同一原型的。例如
function Person(){}
Person.prototype = {
name = "Default Name";
fruit = ["apple", "pear", "peach"];
}
var p1 = new Person();//p1.fruit == ["apple", "pear", "peach"]; p1.fruit 指向 Person.prototype.fruit
var p2 = new Person();//p2.fruit == ["apple", "pear", "peach"]; p2.fruit 指向 Person.prototype.fruit
p1.fruit.push("banana"); //此后, p1.fruit 与 p2.fruit 内容一致,均为 ["apple", "pear", "peach", "banana"];
结合原型与构造函数,我们可以既有共享部分(使用 prototype
),又有单独部分(使用关键字 this
):
function Person(){
this.name = "Default Name";
this.fruit = ["apple", "pear", "peach"];
}
Person.prototype = {
gender = "Male";
age = 14;
sayName = function(){
alert(this.name);
}
}
所有对象都是全局对象 window 的成员
- 浏览器的全局对象是 window,所有的「全局变量」都是 window 的成员
-
document
是全局对象 window 的成员,表示浏览器窗口的 HTML 页面,页面上的元素都是document
的成员
JS 加载方式
- 在
<script></script>
中嵌入代码 - 在
<script>
标签的src
属性中指明 JS 对应 URL - 某个 HTML 标签的事件处理器中指明
- 一些特殊的事件处理器如
- 普通标签:onMouseOver, onMouseOut, onMouseClick, onMouseDoubleClick
- body:onLoad, onUnload
- 对话框:alert(), prompt(), confirm()
-
alert()
:单一提示对话框 -
prompt()
:对话框提示输入 1 个值- 例如:
var name = prompt("Input your name: ");
- 例如:
-
confirm()
:对话框提示「是/否」,返回 1 或 0- 例如:
if (confirm("Are you kidding?")) { alert("Ouch!");} else {alert("Thank you.");}
- 例如:
-
- 一些特殊的事件处理器如