JavaScript基础
一、JavaScript初识
1.什么是JavaScript?
(1) W3C说明
JavaScript 是世界上最流行的编程语言。这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。
JavaScript 是脚本语言(脚本语言不需要编译,可以直接用,由解释器来负责解释。)
JavaScript 是一种轻量级的编程语言。
JavaScript 是可插入 HTML 页面的编程代码。
JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
JavaScript 很容易学习。
(2) JavaScript核心
1> ECMAScript —— 描述了该语言的语法和基本对象;
2> 浏览器对象模型 (BOM, Browser Object Model) — 可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作
3> 文档对象模型 (DOM, Document Object Model) — DOM 通过创建树来表示文档,从而使开发者对文档的内容和结构具有空前的控制力。用 DOM API 可以轻松地删除、添加和替换节点。

2.JavaScript的作用?
实现动态的网页,前端数据的获取、运算、存储等等。
3.如何在HTML中使用JavaScript?
<script type="text/javascript">
// JS codes...
alert('Hello JS!');
document.write('Hello JS');
console.log('Hello JS');
</script>
(2) 外部引用
<script src="day3-1.js"></script>
二、基本语法
1. 变量类型Undefined Null Boolean Number String Object Function
【typeof】
(1) undefined表示声明了变量并未给赋值 (在编程过程中尽量不要这么做,声明了变量最好就给初始化一个值)
(2) null 如果在声明变量时,还不确定应该给该变量初始化什么值,可以初始化为null,表示该变量为空
(3) boolean
(4) number
常用方法:
toString() //转换成字符串
toFixed(2) // 保留2位小数,并转换成字符串
Math.floor(18.88) // 舍弃小数位 寻找最近的整数 这个整数比参数小
注:<1> alert(0.1 + 0.2); alert((0.1 + 0.2) == 0.3);【在js中不推荐使用带小数的number类型进行比较】
<2> Number.MIN_VALUE Number.MAX_VALUE
<3> a.NaN,Not a Number,这个数值表示本应该返回一个数值的表达式,返回的却不是数值。
b.它本身是一个值 var nan = Number.NaN; 或 var nan = NaN;
c.0/0返回NaN,任何大于0的数值除以0返回无穷大,任何小于0的数值除以0返回无穷小
d.可以通过isNaN()函数来判断一个量是否为NaN。注:任何可以转化为数字的数据都不为NaN,如:true, ‘123’,但‘Abc’不能转为数字,值为NaN
<4>将一个量转化为Number,Number(‘123’), parseFloat(), parseInt()
(5) string
<1> ECMAScript中的字符串全部都是不可变的,操作字符串都是创建新字符串抹除旧字符串的过程
字符串操作:
拼接字符串 - 直接两个字符串相加
concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串。
length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。
charAt() – 返回指定位置的字符。
substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置。传一个值的意义是从某个位置开始取到结尾
substr() – 返回字符串的一个子串。传入参数是起始位置和字串长度。
indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 。
lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1 。
toLowerCase() – 将整个字符串转成小写字母。
toUpperCase() – 将整个字符串转成大写字母。
slice() – 提取字符串的一部分,并返回一个新字符串。 可传两个参数 开始和结束(开去间 不会取到) 结束位置可不传
split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。
stringObject.split(separator,howmany)
separator必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
/b+/
match() – 检查一个字符串是否匹配一个正则表达式。
replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。
search() – 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1 。
<2> toString(); // 不适用于undefined和null,建议,编程时要做好非空判断
String(); //强制类型转换为字符串类型,建议不要用
(6) object
创建对象
var obj = new Object();
添加属性 obj.name = “XXX”;
添加方法 obj.selector = function(){};
var num = new Number(); // 创建Number对象,类型不是Number,而是Object
var str = new String();
… 其他更深层次面向对象的介绍放在之后
2.操作符
(1) 表达式:单一的常量、变量,运算式,函数调用,或它们的组合式都可称为表达式
(2) 一元运算符 ++ –
(3) 二元运算符 + - * / % += -= *= /=
(4) 三元运算符 Boolean ? a : b
(5) 关系运算符 > < == === >= <= !=
(6) 逻辑运算符 && || !
3.控制流语句 if..else.. switch while
【附】语句分类
a.声明语句 b.表达式语句 c.分支语句(if..else..,switch) d.循环语句(for,while,do..while) e.控制结构语句(continue,break,return,throw,try{} catch{} finally{})
【注】不要用for in循环(并不是代表遍历元素 之后讲解)
【注】JavaScript中没有块级作用域 (函数例外)
for (var i = 0; i < 2; i++) {
var forVar = 12;
}
alert(forVar);
【注】try 语句允许我们定义在执行时进行错误测试的代码块。
catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
throw 语句允许我们创建自定义错误。
正确的技术术语是:创建或抛出异常(exception)。
try { //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容 }
catch { //除非try里面执行代码发生了异常,否则这里的代码不会执行 }
finally { //不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally }
<script>
function myFunction()
{
try
{
var x=document.getElementById("demo").value;
if(x=="") throw "empty";
if(isNaN(x)) throw "not a number";
if(x>10) throw "too high";
if(x<5) throw "too low";
}
catch(err)
{
var y=document.getElementById("mess");
y.innerHTML="Error: " + err + ".";
}
}
</script>
<h1>My First JavaScript</h1>
<p>Please input a number between 5 and 10:</p>
<input id="demo" type="text">
<button type="button" onclick="myFunction()">Test Input</button>
<p id="mess"></p>
4.函数
【JS中的函数,可以被看成一个值】
【对于绝大部分计算机语言】 (1)函数的定义 (2)函数中的代码必须被调用才会被执行
【对于JavaScript】
(1) 函数的声明方式 :无返回值说明 形参不需要加类型说明
// 普通函数
function addFunc1(num1, num2) {
return num1 + num2;
}
// 用变量名接收函数
// 类似于 var a = 10; 在js中函数可以被看做一个值
var addFunc2 = function (num1, num2) {
return num1 + num2;
}
var func = new Function(‘a‘,’b‘,’return a+b;’);【不推荐】
alert(func); // 弹出函数本身
alert(func(2,3));//弹出函数的运算值
(2) 函数的实现
function introduce(){ }
a.形参不需要加var进行说明
b.形参和函数体内声明的变量在函数执行结束之后就被销毁了,在外部不能使用
c.调用函数时可以传任意多个参数,可以在函数体内通过arguments数组获取参数个数、值
(3) 嵌套函数与函数的作用域
// 注: 局部变量的作用域为当前函数;函数层级越往内部,访问局部变量的能力越强
var b = 11;
function func2() {
function func3() {
var c = 3;
}
// 注: 函数为提前声明的,函数实现完毕,并未被调用时,其中的变量只开辟了空间并未被赋值
// 所以函数内、外有同名变量时,下面一句代码alert(b); 执行结果b为undefined
//alert(b);
var a = 0;
var b = 1;
//alert(b);
}
func2();
三、引用类型和数组
1.引用类型
基础数据类型,引用类型
int i = 10;
// 自己创建一个对象用指针引用它 指针存的是对象的首地址
Dog * dog = [Dog new];
【注】在JavaScript中,基本数据类型传参,在函数内部对实参的值和类型修改都不生效;引用类型传参,在函数内部可以修改实参的值,但是修改实参的类型不生效。
【注】理解JS对象,对象是一系列无序值的合集。(在JS中函数也可以看成一个值)
// 创建一个引用类型变量 创建一个Object对象 给该对象添加属性
var person = new Object();
person.name = 'Wang';
person.age = 13;
person.say = function () {
document.write('My name is '+ this.name + '. I am '+ this.age +' years old.');
}
person.say();
// 字面量的形式创建引用类型变量
var girlFriend = {
name : 'Hong',
age : 12,
say : function () {
document.write('My name is '+ this.name + '. I am '+ this.age +' years old.');
}
}
// 删除属性或方法
delete girlFriend.name;
girlFriend.say();
【附】一般来讲,访问对象属性时都是用点表示法,但是在JS中也可以用中括号的形式访问
girlFriend['name'];
// 注意一下两种表述的区别
//函数
girlFriend['say'];
// 函数值
girlFriend['say']();
2.数组
var arr1 = new Array();
//20代表arr的长度
var arr2 = new Array(20);
document.write(arr1.length + "---" + arr2.length);
var arr3 = [1, 2, 3, true, "abc"];
// 追加元素, 返回值为数组的长度
arr3.push("hello", "wrold");
// 删除元素, 每次只能删除一个, 返回值为被删除的元素
arr3.pop();
arr3.pop();
// 也可以这样添加元素
arr3[5] = "def";
// 删除首元素
arr3.shift();
// 从首部插入元素
arr3.unshift("new first");
// concat
// concat也表示追加元素,不过不会影响原数组,会产生一个新数组
var arr4 = arr3.concat("ccc");
// 截取数组, 从第0个元素取到第3个元素
// 两个值都是可选的 第一个值闭区间 第二个值开区间
var arr5 = arr4.slice(0, 3);
var arr6 = [1, 2, 3, 4, 5];
// 从下表1开始删除元素,删除0个,并且从下标1处插入元素,返回值为被删除的元素组成的数组
arr6.splice(1, 0, "new", "item");
// 可做成替换元素
arr6.splice(1, 1, "new"); 或者 arr6[2]=‘123’;
// 查找
// 返回查找元素的下标,如果查找不到返回 -1
// 第二个参数是从哪个位置开始查找
var position = arr1.indexOf('push’,5);
nslog('position', position);
// 拼接数组内容,形成一个完整的字符串
var arr1 = [1, 1 + 1, "abc", new Date()];
document.write(arr1.join("--"));
// 数组逆序 可以影响原数组
var arr3 = [1, 2, 5, 4, 0];
document.write("<br/>" + arr3.reverse());
// 数组排序
var arr4 = arr3.sort(
function () {
if(arguments[0] < arguments[1]) {
// return true 表明需要调换顺序
return true;
}
}
);
document.write("<br/>" + arr4);
// 对象排序
var arr5 = new Array(5);
for (var i = 0; i < 5; i++) {
var arrObj = new Object();
// Math.random() 随机[0,1)
arrObj.age = Math.random() * 100 % 20;
arr5[i] = arrObj;
document.write("<br/>" + arr5[i].age);
}
var arr6 = arr5.sort(
function () {
if (arguments[0].age < arguments[1].age) {
return true;
}
}
);
for (var i = 0; i < arr6.length; i++) {
document.write("<br/>" + arr6[i].age);
}
3.//String() / Function()
var str = new String('Nice to meet you.');
alert(str);
var func = new Function('num1', 'num2', 'num1++;return num1 + num2;'); // 效率低下,不推荐
alert(func(13, 12));
四、Date和Math
1.时间与日期
// 时间与日期
var date0 = new Date();
document.write(date0 + "<br/>");
// 获取当前时刻的秒数 可用做精确计时
var seconds = Date.now();
// 传时间日期的字符串 规格月/日/年 时:分:秒
var date1 = Date.parse("4/28/2016 10:04:33");
adwrite("时间日期转秒数", date1);
var date2 = new Date(date1);
adwrite("秒数转时间日期", date2);
var date3 = new Date("4/28/2016 10:14:33");
adwrite("当前时间", date3);
// 年 月 日 时 分 秒
var date4 = new Date(2016, 3, 28, 10, 08, 32);
// 获得的值月份位置应传月份的下标
adwrite("当前时间", date4);
// 年
date4.getYear();
// 获取日期
date4.getDate();
// 获取小时
date4.getHours();
- Math
(1) 常用常量
Math.PI // π
Math.E // 自然对数的底数,e
(2) 常用方法
Math.min(1, 2, 3, 4, 5); // 求最小值
Math.max(1, 2, 3, 4, 5); // 求最小值
Math.ceil(18.1); // 向上求整
Math.floor(18.1); // 向下求整
Math.round(18.1); // 四舍五入
Math.random(); // 随机数,0-1之间
Math.abs(); // 绝对值
Math.exp(); //高等数学里以自然常数e为底的指数函数
Math.pow(); // 求次方
Math.log(); // 以什么为底数
…
五、Global对象 (全局)
【最重要的对象window】
1. URI编码
encodeURI(urlStr); // 只编码中文
encodeURIComponent(urlStr); // 编码中文和特殊字符
decodeURI(xx); // 反编码
decodeURIComponent(xxx);
- eval函数 解析代码片段
字符串解析为代码
eval(“var number = 100;”)
3.定时器 与 延时调用
1)setTimeout();//n毫秒后执行一次
2)setInterval();//每隔n秒执行一次
// 第一个参数传入的是代码块 推荐定时器传入函数 如果传入字符串 最终也是被译成函数
// 第二个参数是定时器执行间隔 毫秒
setInterval(function() {
document.write('一秒写一次');
}, 1000);
setTimeout(function() {
alert('两秒时间到');
}, 2000);
// 开启和关闭
//setTimeout 1000ms后执行1次 var i = setTimeout(function(){ },1000); //setInterval 每隔1000ms执行一次 var j = setInterval(function(){ },1000) //清除Timeout的定时器,传入id(创建定时器时会返回一个id) clearTimeout(i); //清除Interval的定时器,传入id(创建定时器时会返回一个id) clearInterval(j);六、BOM和DOM
1. BOM (Browser Object Model) — 浏览器对象模型 浏览器的属性和行为属于BOM
(1) 核心window对象 —
1> window扮演了全局对象角色,在全局作用域中声明的变量、函数,都是window对象的属性和方法。 在全局作用域下写this 那么它代表的就是window
// 给window对象添加了一个number的属性
var number = 15;
alert(window.number);
function showNumber(number) {
alert(number);
}
window.showNumber(number);
2> 获取浏览器大小
var pageWidth = window.innerWidth;
var pageHeight = window.innerHeight;
document.write('pageWidth == ' + pageWidth);
document.write('pageHeight == ' + pageHeight);
3> 打开一个url
// html准备一个框架
<iframe name="andy">
</iframe>
// JS代码
// _self _blank 自定义名称 - 第二个参数如果有这个名字的窗口或者框架就打开 如果没有就创建一个新的并命名为自定义的名称
window.open('http://baidu.com', 'andy');
(2) location对象
location对象提供了与当前窗口中加载的文档有关的信息
host hostname port href protocol… 注:每次修改以上属性,页面都会重新加载
document.write('host == '+ location.host);// 如果有就返回服务器名称和端口号
document.write('hostname == '+ location.hostname);// 主机地址
document.write('port == '+ location.port); // 端口号
document.write('href == '+ location.href);
document.write('protocol == '+ location.protocol); // 协议
// 重定向
location.href = ‘http://www.baidu.com’;
(3) navigator对象
navigator对象提供了浏览器本地相关信息
appName cookieEnabled cpuClass onLine platform plugins…
document.write('<br>' + navigator.appName);// 浏览器的名称
document.write('<br>' + navigator.cookieEnabled);//表示cookie是否启用
document.write('<br>' + navigator.onLine);// 浏览器是否连接到了因特网
document.write('<br>' + navigator.platform);// 浏览器所在的系统平台
// 检测浏览器已装插件
// 可以使用plugins数组来检测是否安装了某些特定的插件 name代表插件的名字
function myPlugins() {
for (var i = 0; i < navigator.plugins.length; i++) {
document.write('<br>' + navigator.plugins[i].name);
}
}
myPlugins();
(4) screen对象 (用处不大)
width、height (屏幕的像素宽高)
(5) history对象 —保存着用户上网的历史记录,它是浏览器对象的属性
使用go的方法在历史记录中任意跳转
history.go(-1); // 后退
history.go(1); // 前进
history.go(2); // 前进两次
// 后退
history.back();
// 前进
history.forward();
// length保存着历史记录的数量
if(history.length == 1) {
alert('这是第一个页面');
}else {
alert(history.length);
}
- DOM (Document Object Model)
描绘了层次化的节点树,允许开发人员添加、移除和修改页面的某一部分
文档节点—是每个文档的根节点,在html中文档节点只有一个子节点,即元素
文档元素 — 文档的最外层元素,每个文档都只能有一个文档元素,其余元素都被包含在文档元素中
【1】节点
节点包括父(parent)、子(child)和同胞(sibling),
• 在节点树中,顶端节点被称为根(root)
• 每个节点都有父节点、除了根(它没有父节点)
• 一个节点可拥有任意数量的子节点
• 同胞是拥有相同父节点的节点
<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一课</h1>
<p>Hello world!</p>
</body>
</html>
【分析上段代码中节点的关系】
从上面的 HTML 中:
• 节点没有父节点;它是根节点
• 和 的父节点是 节点
• 文本节点 “Hello world!” 的父节点是
节点
并且:
• 节点拥有两个子节点: 和
• 节点拥有一个子节点: 节点
• 节点也拥有一个子节点:文本节点 “DOM 教程”
•
和
节点是同胞节点,同时也是 的子节点
并且:
• 元素是 元素的首个子节点
• 元素是 元素的最后一个子节点
•
元素是 元素的首个子节点
•
元素是 元素的最后一个子节点
【2】 获取节点的方法
1> 根据CSS选择器获取
a. querySelector(); // 返回该选择器匹配到的第一个元素,如果没有返回null
var body = querySelector(‘body’);
b. querySelectorAll(); // 返回该选择器匹配到的所有元素,返回一个NodeList对象,如果没有匹配到返回一个空的NodeList对象
【注】可以调用以上方法的类型是Document、Element、DocumentFragment
// querySelector
var body = document.querySelector('body');
body.style.backgroundColor = 'lightgray';
// querySelectorAll
var list = document.querySelectorAll('.demo');
for(var i = 0; i < list.length; i++) {
document.write('<br>' + list[i].innerHTML);
}
// getElementById
var ele = document.getElementById('xxx');
// getElementsByClassName
var list1 = document.getElementsByClassName('demo');
for(var i = 0; i < list1.length; i++) {
document.write('<br>' + list1[i].innerHTML);
}
// classList操作
document.write('<br>' + document.getElementById('xxx').classList.toString());
document.getElementById('xxx').classList.add('new');
var has = document.getElementById('xxx').classList.contains('new');
document.write('<br>'+has);
document.getElementById('xxx').classList.remove('new');
document.write('<br>' + document.getElementById('xxx').classList.toString());
(2) 修改节点内容
var element = document.getElementById('xxx');
element.innerHTML = 'New innerHTML';
(3) JS动态创建、删除节点
var button = document.createElement('button');
button.innerHTML = 'JS创建的按钮';
document.body.appendChild(button);
// 删除节点
var list=document.getElementById("myList");
list.removeChild(list.childNodes[0]);
// insertBefore() 在某个元素之前添加标签
<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
<script>
var para=document.createElement("p");
var node=document.createTextNode("This is new.");
para.appendChild(node);
var element=document.getElementById("div1");
var child=document.getElementById("p1");
element.insertBefore(para,child);
</script>
// 替换标签元素 replaceChild()
<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
<script>
var para=document.createElement("p");
var node=document.createTextNode("This is new.");
para.appendChild(node);
var parent=document.getElementById("div1");
var child=document.getElementById("p1");
parent.replaceChild(para,child);
</script>
(4) 修改节点属性及CSS样式
var button = document.createElement('button');
button.innerHTML = 'JS创建的按钮';
button.onclick = function () {
alert('JS创建的按钮');
}
button.style.width = 300 + 'px';
button.style.height = 100 + 'px';
document.body.appendChild(button);
(5)节点及属性的个数
document.body.childNodes.length
document.body.attributes.length
(6)父节点
parentNode
(7)节点的名字 节点的值
nodeName和nodeValue
【常用的DOM对象的方法】
方法
描述
getElementById()
返回带有指定 ID 的元素。
getElementsByTagName()
返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByClassName()
返回包含带有指定类名的所有元素的节点列表。
appendChild()
把新的子节点添加到指定节点。
removeChild()
删除子节点。
replaceChild()
替换子节点。
insertBefore()
在指定的子节点前面插入新的子节点。
createAttribute()
创建属性节点。
createElement()
创建元素节点。
createTextNode()
创建文本节点。
getAttribute()
返回指定的属性值。
setAttribute()
把指定属性设置或修改为指定的值。
七、事件
添加事件的三种方式:
1.html标签加属性
请点击这段文本!
2.JS动态绑定事件
请点击这段文本!
3.添加监听
var outer = document.getElementById(‘outer’);
var inner = document.getElementById(‘inner’);
// 监听 第一个参数事件类型 第二个参数执行的函数
// 添加监听,第三个参数,默认为false,表示冒泡传递事件
// 将第三个参数改为true,表示捕获事件,事件由最外层标签最先捕获到
outer.addEventListener('click', function() {
alert('outer');
}, true);
inner.addEventListener('click', function() {
alert('inner');
}, true);
// 移除监听
inner.removeEventListener('click', 函数调用);
【注意】如果添加监听时,传的是匿名函数,该监听就不能被移除了,因为移除时,传的匿名函数和添加时的函数不是同一个函数对象了
冒泡:由最具体的元素接收,逐级向上传播至不具体的节点。也就是 由内向外,符合iOS响应链机制 例如onclick
捕获:由不具体的节点先收,逐级向下传播至具体的元素。也就是由外向内,最外层先捕获到事件,与iOS响应链机制相反
所有的DOM事件:
http://www.runoob.com/jsref/dom-obj-event.html