《Head First HTML5 javascript》第10章 自定义对象

本文详细介绍了如何在JavaScript中使用自定义对象实现Blog类,包括类特性、类方法和实例方法,以及如何通过原型链进行继承。通过实例展示了如何创建Blog对象、排序和搜索功能,以及使用HTML构建blog列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2022.11.23 第10章 自定义对象

面向对象OOP(Object Oriented Programming)

对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)对象是存储在单个分组中的相关功能的集合。在 JavaScript 中,大多数事物都是对象,从作为核心功能的字符串和数组,到建立在 JavaScript 之上的浏览器 API

继承与原型链

对于使用过基于类的语言 (如 Java 或 C++) 的开发者们来说,JavaScript 实在是有些令人困惑 —— JavaScript 是动态的,本身不提供一个 class的实现。即便是在 ES2015/ES6 中引入了 class关键字,但那也只是语法糖,JavaScript 仍然是基于原型的。

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为 proto)指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object  的实例。

尽管这种原型继承通常被认为是 JavaScript 的弱点之一,但是原型继承模型本身实际上比经典模型更强大。例如,在原型模型的基础上构建经典模型相当简单。

在 JavaScript 中,函数(function)是允许拥有属性的。所有的函数会有一个特别的属性 —— prototype

 

  1. 创建类特性(class property),使用prototype对象

    1. 存储一次,能被所有实例访问,不必定要初始化

      Blog.prototype.signature = "by Puzzler Ruby";
      
    2. 在实例内访问类特性用关键字this,跟访问实例特性一样

      Blog.prototype.toHTML = function(highlight) {
      				...
      					blogHTML +=  this.signature + "</em></p>";
      			...
      			};
      
  2. 类拥有的实例方法(class-owned instance method),使用prototype对象

    1. 存储一次运行多次,方法只有一份,由所有实例共享
    2. 虽然属于类,但能够访问实例特性
  3. 类方法(class method),不使用prototype对象

    1. 为类所有,不能访问实例特性或方法,但可以被实例调用(透过类名即可)

      Blog.blogSorter = function(blog1, blog2) {
      				return blog2.date - blog1.date;
      			};
      
    2. 只能访问类特性,需要下探至prototype特性内

      function showBlog(num)
      			{
      				blog.sort(Blog.blogSorter);		
      				...
      			}
      

对象实例instance

在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符  来作用这个函数时,它就可以被称为构造方法(构造函数)。

function Graph() {
  this.vertices = [];
  this.edges = [];
}

Graph.prototype = {
  addVertex: function(v){
    this.vertices.push(v);
  }
};

var g = new Graph();
// g 是生成的对象,他的自身属性有 'vertices' 和 'edges'。
// 在 g 被实例化时,g.[[Prototype]] 指向了 Graph.prototype。

其他知识点

  1. <table>元素表示表格数据——即通过二维数据表表示的信息

    内容分类流动内容
    允许的内容按照这个顺序:
    • 一个可选的 <caption>  元素 表格的标题
    • 零个或多个的 <colgroup>  元素 定义表中的一组列表
    • 一个可选的 <thead>  元素 通过二维数据表表示的信息
    • 下列任意一个:
     ◦ 零个或多个 <tbody>  封装了一系列表格的(<tr>)
     ◦ 零个或多个 <tr> 定义表格中的行
    

    • 一个可选的 <tfoot>  元素 定义了一组表格中各列的汇总行 | | 标签省略 | 不允许,开始标签和结束标签都不能省略。 | | 允许的父元素 | 任何支持流内容 (en-US)的元素 | | 允许的 ARIA 角色 | Any | | DOM 接口 | HTMLTableElement |

    <table>
      <caption>Color names and values</caption>
      <tbody>
        <tr>
          <th scope="col">Name</th>
          <th scope="col">HEX</th>
          <th scope="col">HSLa</th>
          <th scope="col">RGBa</th>
        </tr>
        <tr>
          <th scope="row">Teal</th>
          <td><code>#51F6F6</code></td>
          <td><code>hsla(180, 90%, 64%, 1)</code></td>
          <td><code>rgba(81, 246, 246, 1)</code></td>
        </tr>
        <tr>
          <th scope="row">Goldenrod</th>
          <td><code>#F6BC57</code></td>
          <td><code>hsla(38, 90%, 65%, 1)</code></td>
          <td><code>rgba(246, 188, 87, 1)</code></td>
        </tr>
      </tbody>
    </table>
    
  2. <td>定义了一个包含数据的表格单元格。It participates in the table model.

  3. vertical-align 指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。

    /* Keyword values */
    vertical-align: baseline;
    vertical-align: sub;
    vertical-align: super;
    vertical-align: text-top;
    vertical-align: text-bottom;
    vertical-align: middle;
    vertical-align: top;
    vertical-align: bottom;
    
    /* <length> values */
    vertical-align: 10em;
    vertical-align: 4px;
    
    /* <percentage> values */
    vertical-align: 20%;
    
    /* Global values */
    vertical-align: inherit;
    vertical-align: initial;
    vertical-align: unset;
    
  4. <style >元素包含文档的样式信息或者文档的部分内容。默认情况下,该标签的样式信息通常是CSS的格式。

  5. **JavaScript 控制台**是一个非常有用的工具,用于调试没有按预期运行的 JavaScript。它允许您针对浏览器当前加载的页面运行 JavaScript 行,并报告浏览器尝试执行代码时遇到的错误。要在任何浏览器中访问控制台,只需按控制台按钮。 (在 Internet Explorer 中,按 Ctrl + 2.)这将给你一个如下所示的窗口

案例:使用自定义对象实现blog目录

<html>
	<head>
		<title>YouCube - The Blog for Cube Puzzlers</title>
		<script>

			function Blog(body, date, image){
				this.body = body;
				this.date = date;
				this.image = image;
			}

			Blog.prototype.toString = function(){
					return "[" + this.date.shortFormat() + "]" + this.body;
				};

			Blog.prototype.toHTML = function(highlight){
				var blogHTML = "";
				blogHTML += highlight ? "<p style='background-color:#eeeeee'>" : "<p>";

				if (this.image){
					
					blogHTML += "<strong>" + this.date.shortFormat() + "</strong><br /><table><tr><td>" + "<img src='" + this.image +"'/> </td><td style='vertical-align:top'>" + "</br>" + this.body + "</td></tr></table><br /><em>" + this.signature + "</em></p>" ;

				}
				else
					blogHTML += "<strong>" + this.date.shortFormat() + "</strong>" + "</br>" + this.body + "<br /><em>" + this.signature + "</em></p>" ;
				return blogHTML;
			};

			Blog.prototype.containsText = function(text){
				return(this.body.toLowerCase().indexOf(text.toLowerCase()) != -1);
			};

			Blog.prototype.signature = "pizzler ruby";

			Date.prototype.shortFormat = function(){
				return this.getFullYear()  + "/" + (this.getMonth() + 1) + "/" + this.getDate();
			};

			Blog.blogSorter = function(blog1, blog2){
				return blog2.date-blog1.date;
			};

			var blog = [new Blog("Got the new cube I ordered. It's a real pearl.", new Date("08/14/2008")),
						new Blog("second line.", new Date("08/19/2008")),
						new Blog("third line.", new Date("08/16/2008")),
						new Blog("the fourth line.", new Date("08/21/2008"), "cube77.png"),
						new Blog("Got the new cube I ordered. It's a real pearl.", new Date("08/14/2008")),
						new Blog("second line.", new Date("08/19/2008")),
						new Blog("third line.", new Date("08/16/2008")),
						new Blog("the fourth line.", new Date("08/21/2008"))];

			function showBlog(numEn){
				//如果没有传入显示个数,则显示所有日志
				if (!numEn)
					numEn = blog.length;

				//显示日志
				var blogText = "";
				for (var i=0; i<numEn; i++){
					blogText += blog[i].toHTML(0 == i%2);
				}
				document.getElementById("blog").innerHTML = blogText;
			}

			//倒序排列
			blog.sort(Blog.blogSorter);

			function searchBlog(){
				var searchText = document.getElementById("searchtext").value;
				for (var i = 0; i<blog.length; i++){
					if (blog[i].containsText(searchText)){
						alert(blog[i]);
						break;
					}
				}
				if (blog.length == i)
				alert("sorry,there are no blog entries containing the search text.");
			}
			
			function randomBlog(){
				var i = Math.floor(Math.random() * blog.length);
				alert(blog[i]);
			}

		</script>
	
	</head>

	<body onload = "showBlog(5);">
		<h3>YouCube - The Blog for Cube Puzzlers</h3>
		<img src="cube.png" alt="YouCube" />
		<input type="button" id="search" value="search the blog" onclick="searchBlog();" />
		<input type="text" id="searchtext"  value="" />

		<div id="blog"></div>
		<input type="button" id="showall" value="show all blog" onclick="showBlog();" />
		<input type="button" id="random" value="random the blog" onclick="randomBlog();" />
		
	</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值