目录
HTML HyperText Markup Language
【DHTML+DOM+BOM】网页编程——掌握基本编程思想进阶
HTML HyperText Markup Language
- HTML 就是超文本标记语言的简写,是最基础的网页语言。
- HTML 是通过标签来定义的语言,代码都是由标签所组成。
- HTML 代码不区分大小写。
- HTML 代码由 <html> 开始 </html> 结束。里面由头部分 <head></head> 和体部分 <body></body> 两部分组成。
- 头部分是给 HTML 增加一些辅助或者属性信息,它里面的内容会最先加载。
- 体部分是真正存放页面数据的地方。
<html>
<head>
<title>网页标题</title>
</head>
<body>
<h1>测试内容</h1>
</body>
</html>
界面:
1. 标签的表现形式&操作思想
标签分两种:
- 有开始,有结束,用于封装数据。<labelname></labelname>
- 有开始,直接内部结束,是功能标签</labelname>。如换行标签<br/>,分割线标签<hr/>。
HTML操作:就是用标签中的属性对数据进行操作,标签相当于容器。
<html>
<head>
<title>我是网页标题</title>
</head>
<body>
这个文字没有进行标签封装,后面br标签换行<br/>
<font color="#FF0000" size="20px">用font标签封装的文字+属性</font>
<hr/>
水平线标签:默认前后都回进行换行
<!-- 我是注释,注释内容不会被执行 -->
<h1><!-- 标签是可以被嵌套的 -->
<font color="#0000FF">
我是被h1标签封装和font标签封装的文字,有h1~h6级的标签,有默认的字体大小
</font>
</h1>
</body>
</html>
标签是可以被嵌套的,一定要记住。
界面:
2. 特殊字符
< | < | > | > | & | & |
" | " | ® | ® | © | © |
™ | ™ | | 空格 |
特殊字符和标签不用刻意的去记,常用的特殊字符就几个如空格 ,常用标签必须掌握记住的。
<html>
<head>
<title>网页标题</title>
</head>
<body>
<h1><font color="#0000FF" size="20px">测试内容</font></h1>
<hr/>
<p><</p>
<p>></p>
<p>空 格</p>
<p>空 格</p>
<p>&</p>
<p>™</p>
<p>©</p>
</body>
</html>
界面:
直接敲空格无论敲多少个都是直接一个空格。换行也是一样的
3. HTML 的严谨性&现代浏览器自动安全解析
<html>
<head>
</head>
<body>
<h1><font color="#0000FF" size="20px">测试内容</font></h1>
<hr/>
</body>
</haha>
<title>网页标题</title>
如上面,我把</html>结束标签换成</haha>标签,同时把<title>标签写到<html>外面,看看会发生什么?
改了</html>结束标签没有影响到整个界面,并且没有影响到<title>标签的解析。
我们来看看代码审查:
没错,浏览器自动的把错误代码改正了过来。
CSS 与 HTML
CSS 即 层叠样式表 (Cascading Style Sheets)用来定义网页的显示效果。
CSS是HTML中标签的样式属性,早期并没有CSS,HTML把标签中的样式属性抽取出来后,就用CSS语言样式表代替了。
加大了HTML对代码样式的复用率,提高了代码的可维护性,增强了网页的显示效果功能。也就是 HTML 中的标签和属性,进行分开封装,提高了代码的显示效果。
HTML 提供了两个标签,仅用于封装数据,没有特殊含义,常用属性style用于封装CSS样式属性代码:
标签 | 封装区域 | 结尾换行 |
div | 块级标签:整行(如要修改此封装数据的背景颜色,会直接修改整行的背景) | 是 |
span | 行内标签:数据范围(如要修改此封装数据的背景颜色,只有数据范围背景被更改) | 否 |
一些块级与行内标签:
块级标签 | 行内标签 |
dl | a |
table | img |
tr | input |
td | |
p |
例子:
<html>
<head>
<title>我是网页标题</title>
</head>
<body>
<div>DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
界面:
1. CSS 与 HTML 结合一(style属性)
使用了 HTML 的一个 style 属性
<html>
<head>
<title>我是网页标题</title>
</head>
<body>
<div style="color: red; font-size: 24px; background-color: orange;">DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
界面:
style 属性的值,封装的都是 CSS 的属性和值代码,格式(属性名 冒号 值 分号)
2. CSS 与 HTML 结合二 (style标签)
观察以下代码,多个标签属性重复了,我们必须想办法向上抽取出来:
<html>
<head>
<title>我是网页标题</title>
</head>
<body>
<div style="color: red; font-size: 24px; background-color: orange;">DIV区域一</div>
<div style="color: red; font-size: 24px; background-color: orange;">DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
使用 HTML 提供的 style 标签:
<html>
<head>
<title>我是网页标题</title>
<!-- style 标签 CSS 代码一般放在 head 标签中先加载 -->
<style type="text/css">
div {
color: red;
font-size: 24px;
background-color: orange;
}
</style>
</head>
<body>
<div>DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
style 标签的 type 属性只有一个值 text/css
界面:
3. CSS 与 HTML 结合三 (CSS文件)
如果多个 HTML 页面的属性样式重复了,我们就用 CSS 文件的方式复用重复样式。
div.css :
div {
color: red;
font-size: 24px;
background-color: orange;
}
span.css :
span {
color: green;
font-size: 20px;
background-color: red;
}
index.html:
在style标签中 用 @impor url(css文件); 导入相应的css文件
<html>
<head>
<title>我是网页标题</title>
<!-- style 标签 CSS 代码一般放在 head 标签中先加载 -->
<style type="text/css">
@import url(div.css);
@import url(span.css);
</style>
</head>
<body>
<div>DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
界面:
3.1 CSS文件中导入CSS文件
theme.css:
@import url(div.css);
@import url(span.css);
index.html:
<html>
<head>
<title>我是网页标题</title>
<!-- style 标签 CSS 代码一般放在 head 标签中先加载 -->
<style type="text/css">
@import url(theme.css);
</style>
</head>
<body>
<div>DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
也是同样的效果
3.2 link 标签导入css文件
<html>
<head>
<title>我是网页标题</title>
<!-- link 标签 CSS 代码一般放在 head 标签中先加载 -->
<link rel="stylesheet" href="theme.css" type="text/css"/>
</head>
<body>
<div>DIV区域一</div>
<div>DIV区域二</div>
<span>SPAN区域一</span>
<span>SPAN区域二</span>
</body>
</html>
4. 复用属性样式代码场景总结
- 只在一个几个标签或者单独不同类别对象定义使用样式,选择 style 属性。
- 多个标签的类别相同使用重复样式,选择 style 标签。
- 多个页面用样式,选择 css 文件。
5. 三种基本选择器
选择器:就是指 CSS 样式代码要作用(设置)到哪个标签,寓意:选择一个标签(容器)来设置 CSS 样式代码。
CSS 样式代码格式:选择器名称 { 属性名 : 属性值 ; 属性名 : 属性值 ; . . . N ~ }
三种选择器:
- HTML 标签名选择器,使用的就是 HTML 标签名。
- class 类选择器,(选择器名前 “.” 点号开头)使用的是 HTML 标签中的 class 属性值的类名(专门给 CSS 使用的)。
- id 选择器,(选择器名前 “#” 点号开头)使用的是 HTML 标签中的 id 属性值的唯一名称(保证 ID 的唯一性,可以给 CSS 使用,和 JavaScript 使用)。
<html>
<head>
<title>我是网页标题</title>
<style type="text/css">
/* class 选择器 */
.haha {
color: red;
font-size: 24px;
background-color: orange;
}
/* id 选择器 */
#xixi {
color: blue;
font-size: 20px;
background-color: yellow;
}
/* 标签名 选择器 */
p {
color: green;
font-size: 25px;
background-color: red;
}
</style>
</head>
<body>
<div class="haha">DIV演示区域一</div>
<div class="haha">DIV演示区域二</div>
<span id="xixi">SPAN演示区域一</span>
<span id="xixi">SPAN演示区域二</span>
<p>段落演示区域一</p>
<p>段落演示区域二</p>
</body>
</html>
界面:
css代码中的注释是(/* */)
根据上述代码,我们发现 class 类选择器和 id 选择器的功能感觉没什么两样,那不是重复了吗?是的,class 和 id 属性值重复了,上面是个演示例子,真实开发中我们需要把 id 属性值设置成唯一的。
5.1 选择器的优先级
优先级 | 1 < | 2 < | 3 < | 4 |
选择器 | 标签名 | class | id | style 属性 |
例子:
<html>
<head>
<title>我是网页标题</title>
<style type="text/css">
/* class 选择器 */
.haha {
color: red;
font-size: 24px;
background-color: orange;
}
/* id 选择器 */
#xixi {
color: blue;
font-size: 20px;
background-color: yellow;
}
/* 标签名 选择器 */
p {
color: green;
font-size: 25px;
background-color: red;
}
</style>
</head>
<body>
<div class="haha" id="xixi" style="color: white; font-size: 30px; background-color: black;">DIV演示区域一</div>
</body>
</html>
界面(直接作用于 style 属性的 css 样式):
6. 关联&组合选择器
- 关联选择器:标签是可以嵌套的,要让相同选择器中的不同选择器显示不同样式,就可以用关联选择器。
- 组合选择器:多个不同的选择器,进行同样的样式设置,就可以使用组合选择器。
关联选择器例子:
选择器 与 选择器之间 空格 隔开
<html>
<head>
<title>我是网页标题</title>
<style type="text/css">
div span {
color: red;
background-color: orange;
}
.haha span {
color: blue;
background-color: yellow;
}
#xixi span {
color: green;
background-color: red;
}
</style>
</head>
<body>
<div><span>DIV</span>演示区域一</div>
<div class="haha">DIV<span>演示</span>区域二</div>
<div id="xixi">DIV演示<span>区域</span>三</div>
</body>
</html>
界面:
组合选择器例子:
每组选择器之间用 “,” 逗号隔开
<html>
<head>
<title>我是网页标题</title>
<style type="text/css">
div span, .haha span, #xixi span {
color: red;
background-color: orange;
}
</style>
</head>
<body>
<div><span>DIV</span>演示区域一</div>
<div class="haha">DIV<span>演示</span>区域二</div>
<div id="xixi">DIV演示<span>区域</span>三</div>
</body>
</html>
界面:
很简单,技术含量 0.
7. 伪元素选择器
何为伪元素选择器?其实就是 HTML 中预定义的某种状态的选择器,如我们可以在一个选择器的某个状态更换一种样式。
有四种常见的伪元素选择器:
未点击(初始) | 被访问后 | 悬停状态(光标移动到标签上) | 点击状态(未松手) |
link | visited | hover | active |
必须按照使用顺序来写代码:L ——> V ——> H ——> A
语法(选择器 : 伪元素)
使用例子:
<html>
<head>
<title>伪元素选择器</title>
<style type="text/css">
/* 未访问 */
a:link {
color: blue;
font-size: 20px;
text-decoration: none;
background-color: red;
}
/* 访问后 */
a:visited {
color: gray;
font-size: 20px;
background-color: white;
}
/* 悬停 */
a:hover {
color: red;
font-size: 24px;
background-color: blue;
}
/* 点击 */
a:active {
color: white;
font-size: 30px;
background-color: black;
}
</style>
</head>
<body>
<a href="#">我是超链接-伪元素选择器演示</a>
</body>
</html>
界面(下面是鼠标放上去变成了悬停状态):
JavaScript 语法快速入门(针对有高级语言基础的)
注意:这里只针对有高级语言基础的,因为 JavaScript 语法和如 Java 有点像,而又是不同的语言。if、for、while、这些语句基本相同。所以这些语句用法不讲。
JavaScript 是基于对象和事件驱动的脚本语言,主要应用在客户端。
特点:
- 交互性(它可以做的就是信息的动态交互,如点击网页上的一个按钮改变它的样式效果)
- 安全性(不允许直接访问本地硬盘)
- 跨平台性(只要是可以解释 JS 的浏览器都可以执行,和平台无关)
JavaScript 与 Java 不同
- JS 是 Netscape 公司的产品,前身是 LiveScript,Java 是 Sun 公司的产品,现在是Oracle 公司的产品。
- JS 是基于对象,Java 是面向对象。
- JS 只需要解释就可以执行,Java 需要先编译成字节码文件,再由JVM虚拟机解释执行。
- JS 是弱类型,Java 是强类型。
JS 的语法(程序设计语言基本都具备以下语法,只是表现形式不同):
- 注释
- 标识符
- 常量变量
- 运算符
- 语句
- 函数
- 数组
1. JavaScript 和 HTML 代码结合
JavaScript 代码 用 HTML 标签 <script> 进行封装,要在 <body> 标签中:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<!-- JavaScript 和 HTML 结合一 -->
<script type="text/JavaScript">
// 弹窗
alert("我是弹窗内容");
</script>
<!-- JavaScript 和 HTML 结合二 -->
<script type="text/JavaScript" src="hello.js">/* 注意使用属性 src 引入 JS 文件后,不能再在此处写 JS 脚本代码 */</script>
</body>
</html>
使用第二种方式注意:使用属性 src 引入 JS 文件后,不能再在此处写 JS 脚本代码,如果写了当废话。
hello.js 文件:
alert("Hello JavaScript");
界面:
2. 变量的定义 & 语法非严谨 & 默认值
变量的定义用关键字 var 完成,没有明显类型:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
/*
var 类型:啥数据都能装,不用明显的数据类型
*/
var x = 123;
alert(x);
alert(x = 12.3);
alert(x = "abc");
alert(x = true);
</script>
</body>
</html>
界面:
2.1 语法非严谨
不但可以把分号去掉,更恐怖的还可以把 var 变量声明去掉
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
/*
var 类型:啥数据都能装,不用明显的数据类型
*/
x = 123
alert(x)
alert(x = 12.3)
alert(x = "abc")
alert(x = true)
</script>
</body>
</html>
效果是一样的,不会报错。真实开发中一定要规范。
2.2 变量默认值
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
var x;
alert(x); // undefined
</script>
</body>
</html>
显示:
3. 运算符 - 一些注意
和其它程序设计语言不同的是逻辑与位运算符:
逻辑运算符 | && | || |
位运算符 | & | | |
3.1 字符串转数字 & 非法转换错误
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
/*
字符串除了用 + 号链接符外,用标准数学运算符计算会自动转换成数字
*/
alert("13" - 1); // 12
alert("12" / 3); // 4
alert("10" * 2); // 20
alert("a" - 1); // NaN:非法的转换,只能是数字
</script>
</body>
</html>
3.2 自动类型转换
5 + null // 返回 5 null 转换为 0
"5" + null // 返回"5null" null 转换为 "null"
"5" + 1 // 返回 "51" 1 转换为 "1"
"5" - 1 // 返回 4 "5" 转换为 5
"a" - 1 // NaN 非法 "a" 转换失败,程序报错
3.3 typeof() 判断数据类型
JavaScript 数据类型
在 JavaScript 中有 6 种不同的数据类型:
- string
- number
- boolean
- object
- function
- symbol
3 种对象类型:
- Object
- Date
- Array
2 个不包含任何值的数据类型:
- null
- undefined
typeof "John" // 返回 string
typeof 3.14 // 返回 number
typeof NaN // 返回 number
typeof false // 返回 boolean
typeof [1,2,3,4] // 返回 object
typeof {name:'John', age:34} // 返回 object
typeof new Date() // 返回 object
typeof function () {} // 返回 function
typeof myCar // 返回 undefined (如果 myCar 没有声明)
typeof null // 返回 object
3.4 boolean 布尔类型的数值
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
alert(true + 1); // 2,true 就是非 0 或非 null。
alert(false + 1); // 1,false 就是 0 或者 null。
if (true + 10) {
alert("if is true");
}
</script>
</body>
</html>
界面:
4. 函数的定义和细节
- 函数的定义用关键字 function 定义
- 函数参数的定义不需要用 var 声明
- 函数没有重载的概念
- 函数内部内置了一个参数数组,用来存储传递进来的实参,数组名:arguments,并且这个数组是可变的,没有下标越界。
- 定义函数就会在内存中创建一个对象,函数名即保存了内存中 Function 类型的对象的引用地址。
4.1 函数内部数组可变 & 函数参数传递问题
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
// 定义函数和参数
function show(x, y) {
alert(x + y);
}
// 无参函数
function showParam() {
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
}
}
// 带返回值的函数
function getValue(x, y) {
return x + y;
}
/*
函数必须调用才执行,虽然没有在函数方法定义参数,但是乃然可以传递参数
如果有参数的函数,不传递任何一个参数也是可以的
*/
show(); // 不传递参数
showParam(1, 2, 3, 4, 5); // 调用无参函数,并传递参数
var num = getValue(10, 20); // 正常使用
alert(num);
</script>
</body>
</html>
界面:
show()方法:undefined + undefined 非法错误
showParam()方法,显示1~5:
getValue()方法:
所以,真实开发中,有几个参数就传几个参数
4.2 函数对象引用传递
定义函数就会在内存中创建一个对象,函数名即保存了内存中 Function 类型的对象的引用地址。
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
// 无参函数
function showParam(str) {
alert(str);
}
var sum = showParam; // 用函数名的引用地址赋值给 sum 变量
alert(sum); // 将 sum 指向的函数对象转换成字符串,(其实就是调用了对象的toString()方法,函数的字符串表现形式就是定义函数时的表现形式)
sum("OK"); // 调用 sum 变量指向的函数对象
</script>
</body>
</html>
界面:
4.3 动态函数 & 匿名函数
- 动态函数,其实是使用了 JS 中内置的 Function 对象。
- 匿名函数,就是没有方法名的函数,一般用于给事件定义功能,便于简化。
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
// 动态函数
var func = new Function("x, y", "var sum = x + y; return sum;");
var sum = func(5, 5);
alert(sum);
// 匿名函数,没有名字无法调用,需要一个变量进行引用
var funcs = function(str) {
alert(str);
}
funcs("Yes");
</script>
</body>
</html>
界面:
func() 方法
funcs 变量引用
5. 全局和局部变量的作用域
- 全局变量:只要在 script 标签中定义的变量都是全局变量,可以在页面上的任何脚本中使用。
- 局部变量:只要在 function 函数中定义的变量都是局部变量,只有在函数内部有效。
- 全局变量2:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
全局变量演示:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<!-- script 标签一 -->
<script type="text/JavaScript">
var a = "OK";
// 同样的直接写在语句里面的变量也是全局的
for (var n = 0; n < 1; n++) {
// null
}
</script>
<!-- script 标签二 -->
<script type="text/JavaScript">
alert("a = " + a);
alert("n = " + n);
</script>
</body>
</html>
界面:
局部变量演示:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
function showVar() {
var k = "null";
}
alert("k = " + k); // 无效,变量 k 只在函数内部有效,说白了就是对象里面的变量
</script>
</body>
</html>
在浏览器开发者工具里报的错误:
全局变量 2 演示:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
<!DOCTYPE html>
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
function show() {
a = "我是全局变量";
}
show(); // 先调用初始化一下
alert(a); // 弹出窗口:我是全局变量
</script>
</body>
</html>
5.1 全局和局部变量注意事项
而且,全局变量和局部变量重名重复var声明还是会使用相同的内存进行赋值,不会产生新的内存:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
var a = 10;
var a = 20;
alert(a); // 全局变量
function showVar() {
var a = 30;
var a = 40;
alert(a); // 局部变量
}
showVar();
</script>
</body>
</html>
显示:
所有的全局变量都会成为 window 窗口下的成员:
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
var a = "我是全局变量"; // 全局变量
function showVar() { // 函数对象
return "我是函数";
}
document.write(window.a + "<br/>");
document.write(window.showVar());
</script>
</body>
</html>
输出:
我是全局变量
我是函数
6. 数组的语法细节
- 数组的长度是可变的
- 元素类型是任意的(由程序员主观决定存储的元素类型,因为灵活)
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
// 数组的两种声明方式
var arr1 = [0,1,2,3,4]; // 直接明确元素和数组长度
var arr2 = []; // 定义空数组,存储不确定的数据
// 定义一个打印数组的方法
function printArr(arr) {
document.write("[");
for (var index = 0; index < arr.length; index++) {
var str = arr[index];
if (index != arr.length - 1) {
//document.write(arr[index] + ",");
str += ",";
} else {
//document.write(arr[index] + "]<br/>");
str += "]<br/>";
}
document.write(str);
}
}
printArr(arr1);
arr1[9] = 10; // arr1 数组的预定义长度为5,而我直接在下标9的位置进行赋值是允许的,因为数组长度是可变的
document.write("数组长度是可变的:");printArr(arr1);
document.write("<br/>");
// 元素类型是任意的,由程序员主观决定元素类型
arr2[0] = "10";
arr2[1] = "12.3";
arr2[2] = "abc";
arr2[3] = 'q';
arr2[4] = "true";
arr2[5] = null;
arr2[6] = undefined;
document.write("元素类型是任意的:");printArr(arr2);
// 要获取数组的字符串形式:可以直接使用数组对象的 toString() 方法
document.write("使用数组对象的 toString() 方法:" + arr2.toString());
</script>
</body>
</html>
输出界面显示:
7. JavaScript 面向对象编程
- 封装:JavaScript 脚步语言,是基于对象的,没有像如Java、C++等提供描述对象的方式,但是 JavaScript 的设计允许我们模拟面向对象的方式去描述对象。使用 function 方法去描述对象。(私有变量和函数、公开变量和函数,以及静态变量和函数)
- 继承:JavaScript 没有继承的方式,但是 JavaScript 可以实现继承。原型概念:对象调用原型属性 prototype,可实现为类中所有的实例添加新成员,相当于父类。
多态:声明变量用 var 关键字。
7.1 对象封装演示一
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
// 打印方法
function println(date){document.write(date + "<br/>");}
function Person(n){ // 相当于构造器
// 声明私有变量
var name;
// 声明私有方法
function init(){
name = n;
println(name + " : new Person count = " + ++Person.count); // 用于测试静态变量是否是共享于对象的
};
init();
// 公开方法
this.getName = function(){return name;};
this.setName = function(value){name = value;};
this.getN = function(){return n;}; //用于测试传进来的参数是否还可用
}
// 声明静态变量
Person.count = 0;
// 声明静态函数
Person.rest = function() {Person.count = 0;};
var p1 = new Person("斌哥");
var p2 = new Person("雨烟");
println("n = " + p1.getN());
println("n = " + p2.getN());
Person.rest(); // 重置计数器
println("Person.count = " + Person.count);
</script>
</body>
</html>
真正开发的时候,我们需要把 JavaScript 中描述的对象单独封装成一个 .JS 文件
输出界面:
- 构造器:方法参数个数相当于构造器,每 new 一次对象都会执行一次方法。
- 私有变量和方法:私有变量也就是局部变量,用 var 关键字声明。私有方法直接 function 关键字声明。
- 公有变量和方法:用 this. 点的方式声明变量名,然后对变量进行赋值。
- 静态变量和方法:要在对象方法{}外部,用 方法名. 点的方式声明变量名,然后对变量进行赋值。
注意:
大家可以看 Person( n ) 中的参数,在后期乃可用,因为 Function 对象内部本身封装有一个 arguments 数组,用于存储传递过来的参数,arguments[0] 赋值给了变量 n ,这个变量 n 为局部变量也就是对象的私有变量。
所以,为了简化书写,连声明私有变量的步骤都可以省略了。
对象成员的调用有两种方式:
- 对象. 点 的方式
- 对象["变量名"]
7.2 对象封装演示二
<!DOCTYPE html>
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript">
var obj = {
name : "哈哈",
age : 1,
show : function(){
alert("name = " + this.name + ", age = " + this.age);
}
};
obj.show();
</script>
</body>
</html>
定义变量即方法,要用英文 “,” 号隔开。
这种方式定义的属性和方法,都是公共的。
7.3 三种继承演变演示
下面我用动物类进行扩展继承:
Animal.js 文件
// 定义动物 Animal 类
function Animal(name) {
var a = 88; // 私有变量
this.name = name;
this.arr = ["遗传基因"];
this.sleep = function() {
println(this.name + ": 正在睡觉...");
};
this.setA = function(x) {
a = x;
};
this.getA = function() {
return this.name + " : a = " + a;
};
}
// 为原型添加新方法
Animal.prototype.eat = function(food) {
println(this.name + " : 正在吃 --> " + food);
}
// 定义遍历对象成员的打印方法
function printObjectln(obj) {
for (var x in obj) {
println(" " + x + ": " + obj[x]);
}
document.write("<br/>");
}
// 定义打印方法
function println(data) {
document.write(data + "<br/>");
}
原型链式继承
prototype 继承
所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:
所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。
JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
- 核心:将父类的实例作为子类的原型。
- 特点:单继承,函数复用。
- 缺点:1.父类是共享于每个子类实例。2.创建子类实例时无法向父类构造传递参数。
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript" src="Animal.js"></script>
<script type="text/JavaScript">
// 定义猫 Cat 类
function Cat() {
var b = 10; // 私有变量
this.setName = function(name) {
this.name = name;
};
this.setB = function(x) {
b = x;
};
this.getB = function() {
return this.name + " : b = " + b;
};
}
Cat.prototype = new Animal(); // 原型链式继承
// 创建 Cat 实例
var cat1 = new Cat();
var cat2 = new Cat();
cat1.arr[1] = "血色遗传"; // 为 cat1 的 arr 数组下标 1 添加新元素
cat1.setA(99);
cat1.setB(100);
cat1.setName("雨烟");
cat2.setName("斌斌");
// 对比
println("cat1 :");
printObjectln(cat1); // 打印成员
println("cat2 :");
printObjectln(cat2); // 打印成员
println("cat1 instanceof Animal : " + (cat1 instanceof Animal));
println("setName() 子类公有方法引用共享 :" + (cat1.setName == cat2.setName));
println("sleep() 父类公有方法引用共享 :" + (cat1.sleep == cat2.sleep));
println("eat() 父原型公有方法引用共享 :" + (cat1.eat == cat2.eat));
println("cat1-getA() : " + (cat1.getA()));
println("cat2-getA() : " + (cat2.getA()));
println("cat1-getB() : " + (cat1.getB()));
println("cat2-getB() : " + (cat2.getB()));
</script>
</body>
</html>
输出显示:
构造式继承
call() 方法继承是将类中的属性和方法复制到实例中,第一个参数为对象引用,之后的参数列表为需要传递的参数。(复制的变量和值都会创建新内存)。
其实 call() 方法就是用传进去的 this 引用进行添加新成员,并为要赋给变量的值创建新的内存空间,所以父类中的成员都不共享于每个子类实例了。
- 核心:使用 Funciton 原型的 call() 方法,作用是复制父类成员到子类实例(复制的变量和值都会创建新内存)。
- 特点:1.创建实例时可以向父类传递参数。2.可实现多继承。
- 解决:解决原型链式继承每个子类实例共享父类的成员。
- 缺点:1.无法继承父类 prototype 原型成员。2.无法函数复用,子类每个实例都有函数副本。
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript" src="Animal.js"></script>
<script type="text/JavaScript">
// 定义猫 Cat 类
function Cat(name) {
Animal.call(this, name); // 构造式继承
var b = 10; // 私有变量
this.setName = function(name) {
this.name = name;
};
this.setB = function(x) {
b = x;
};
this.getB = function() {
return this.name + " : b = " + b;
};
}
// 创建 Cat 实例
var cat1 = new Cat("123");
var cat2 = new Cat("456");
cat1.arr[1] = "血色遗传"; // 为 cat1 的 arr 数组下标 1 添加新元素
cat1.setA(99);
cat1.setB(100);
cat1.setName("雨烟");
cat2.setName("斌斌");
// 对比
println("cat1 :");
printObjectln(cat1); // 打印成员
println("cat2 :");
printObjectln(cat2); // 打印成员
println("cat1 instanceof Animal : " + (cat1 instanceof Animal));
println("setName() 子类公有方法引用共享 :" + (cat1.setName == cat2.setName));
println("sleep() 父类公有方法引用共享 :" + (cat1.sleep == cat2.sleep));
println("eat() 父原型公有方法引用共享 :" + (cat1.eat == cat2.eat));
println("cat1-getA() : " + (cat1.getA()));
println("cat2-getA() : " + (cat2.getA()));
println("cat1-getB() : " + (cat1.getB()));
println("cat2-getB() : " + (cat2.getB()));
</script>
</body>
</html>
界面输出:
组合式继承
- 核心:原型链式 + 构造式继承。
- 特点:比较理想。
- 解决:利用两者的特点,避免缺点。
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<script type="text/JavaScript" src="Animal.js"></script>
<script type="text/JavaScript">
// 定义猫 Cat 类
function Cat(name) {
Animal.call(this, name); // 调用父类构造复制成员
var b = 10; // 私有变量
this.setName = function(name) {
this.name = name;
};
this.setB = function(x) {
b = x;
};
this.getB = function() {
return this.name + " : b = " + b;
};
}
Cat.prototype = Animal.prototype; // 继承原型链
// 创建 Cat 实例
var cat1 = new Cat("123");
var cat2 = new Cat("456");
cat1.arr[1] = "血色遗传"; // 为 cat1 的 arr 数组下标 1 添加新元素
cat1.setA(99);
cat1.setB(100);
cat1.setName("雨烟");
cat2.setName("斌斌");
// 对比
println("cat1 :");
printObjectln(cat1); // 打印成员
println("cat2 :");
printObjectln(cat2); // 打印成员
println("cat1 instanceof Animal : " + (cat1 instanceof Animal));
println("setName() 子类公有方法引用共享 :" + (cat1.setName == cat2.setName));
println("sleep() 父类公有方法引用共享 :" + (cat1.sleep == cat2.sleep));
println("eat() 父原型公有方法引用共享 :" + (cat1.eat == cat2.eat));
println("cat1-getA() : " + (cat1.getA()));
println("cat2-getA() : " + (cat2.getA()));
println("cat1-getB() : " + (cat1.getB()));
println("cat2-getB() : " + (cat2.getB()));
</script>
</body>
</html>
输出界面:
【DHTML+DOM+BOM】网页编程——掌握基本编程思想进阶