WEB_Day06(自定义对象、原型、继承、js多态的体现、DOM)
自定义对象
// 方式一:使用object的来创建一个对象
var p1 = new Object();
p1.name = "admin";
p1.age = 20;
console.log(p1.name + "--" + p1.age);
//方式二:通过对象的声明
var p2 = {
name: "张三",
age: 21,
say: function () {
console.log("Hello");
},
print: function () {
console.log("world");
}
}
console.log(p2.name + "---" + p2.age);
p2.say();
p2.print();
//方式三:工厂函数
function createPerson(name, age, msg) {
return {
name: name,
age: age,
say: function () {
console.log(msg);
}
}
}
//使用工厂函数创建对象
var p3 = createPerson("lisi ", 18, "hello");
var p4 = createPerson("王五", 22, "world");
console.log(p3.name + "---" + p3.age);
p3.say();
console.log(p4.name + "---" + p4.age);
p4.say();
//方式四:使用构造函数
function Person(name, age, msg) {
this.name = name;
this.age = age;
this.say = function () {
console.log(msg);
}
}
// 使用构造函数创建对象
var p5 = new Person("tom", 22, "hello world");
console.log(p5.name + "---" + p5.age);
p5.say();
构造函数的特点:
- 函数名的首字母大写
- 没有return
- 每条语句之后使用分号
- 创建对象使用new 构造函数的名称;
- 在构造函数中 赋值的时候 将参数的值传递给了this
构造函数和实例对象的关系:
使用构造函数的好处不仅仅在于代码的简洁性,更重要的是我们可以识别对象的具体类型了。 在每一个实例对象中同时有一个 constructor 属性,该属性指向创建该实例的构造函数:
console.log(p5.constructor == Person);//p5的构造函数时Person
console.log(p5.constructor == p6.constructor);//p5 和p6为同一个构造函数
对象的 constructor 属性最初是用来标识对象类型的, 但是,如果要检测对象的类型,还是使用 instanceof 操作符更可靠一些:
console.log(p5 instanceof Person);
console.log(p6 instanceof Person);
总结:
- 构造函数是根据具体的事物抽象出来的抽象模板
- 实例对象是根据抽象的构造函数模板得到的具体实例对象
- 每一个实例对象都具有一个 constructor 属性,指向创建该实例的构造函数
- 注意: constructor 是实例的属性的说法不严谨,具体后面的原型会讲到
- 可以通过实例的 constructor 属性判断实例和构造函数之间的关系
- 注意:这种方式不严谨,推荐使用 instanceof 操作符,后面学原型会解释为什么
对象属性的操作:
- javascript为对象提供了一系列内置的方法,方便我们更好的操作对象。
- 【Object.keys()】获取对象所有属性
- 【delete】删除一个属性
- 【in】检查对象是否包含一个属性
- 【for in】遍历对象所有属性
//获取对象的所有属性
var ks = Object.keys(p5);
console.log(ks)
// 删除对象的某一个属性
console.log(delete p5.name);
console.log(Object.keys(p5));
//判断对象是否包含某一个属性
console.log("name" in p5);//false
console.log("age" in p5);//true
//遍历对象的所有属性
for (k in p6) {
console.log(k);
}
原型
js中给函数提供了一个对象类型的属性,叫做prototype(原型)。
原型归函数所有,不用创建,是默认存在的。
function Student() {
// this.school = "中北大学";
}
var stu1 = new Student();
var stu2 = new Student();
//通过原型来为构造函数绑定一个属性
Student.prototype.school = "中北大学";
console.log(stu1.school);
console.log(stu2.school);
function Student1(name, age, ability) {
this.name = name;
this.age = age;
this.ability = function () {
console.log("学习Java知识");
}
}
Student1.prototype.print = function () {
console.log("学习js的原型");
}
var s1 = new Student1("张三", 21);
var s2 = new Student1("李四", 22);
console.log(s1.name + "--" + s1.age);
console.log(s2.name + "--" + s2.age);
s1.print();
s2.print();
概念:
原型是js为所有函数所创建的一个对象类型的属性,原型当中的属性和方法被所有, 通过这个函数所创建的对象共享
结构:原型是一个对象,在原型中通常拥有两个属性:
- 构造器constructor:该属性指向了这个类本身
- 原型指向__proto___:该属性指向原型本身,提供给通过类创建的对象使用。
作用:原型用来创建类的公有属性和公有方法,为创建对象服务
优点:节约内存空间,不必为每一个对象都分配公有属性和公有方法的内存。
缺点:原型中不能保存数组这类引用类型的数据,因为地址传递的问题会导致出现修改的连锁变化
//每一个对象都拥有__proto__ 前后各有两个下划线
console.log(s1.__proto__)
console.log(s1.__proto__ === s1.constructor)//false
原型链:
原型链构成:
由【对象的__proto__属性】和【对象的构造函数的原型的__protp__属性】构成的链式结构称为原型链。
ps:原型链的顶端是Object对象。
pss:Object对象没有__proto__属性,或者说Object对象的__proto__属性指向了自身。
//每一个对象都拥有__proto__ 前后各有两个下划线
console.log(s1.__proto__.print)
console.log(s1.__proto__ === s1.constructor)//false
console.log(s1.__proto__);//构造函数
console.log(Student1.prototype);//Object的一个实例对象
console.log(s1.__proto__.__proto__);//object
console.log(s1.__proto__.__proto__.__proto__);//null
console.log(Object.prototype);
Object构造函数他有prototype属性
s1.__proto__.__proto__.__proto__返回null 说明object对象没有__proto__属性
原型链的作用 : 访问对象的属性或方法的时候,
首先在本身中查找是否拥有这个属性或方法。
如果没有找到那么就沿着原型链向上逐级查找直到Object为止,
在任何一级寻找到这个属性或方法都视为对象拥有这个属性或方法。
原型链的创建 : 上一节中我们说道原型链是依靠__proto__属性将对象和原型连接起来
原型说的是构造函数的prototype所对应的对象的构造函数的constructor属性
原型链说的是对象的__proto__的属性 他获取到的是通过构造函数的prototype绑定的属性和默认的constructor属性
继承
每一个对象都有一个__proto__指向的是它的原型。在这的原型就可以理解为它的父类。在没有指定每一个对象的原型之前,那么该对象的原型默认就是Object的一个实例对象。
<script type="text/javascript">
function F(name) {
this.name = name;
}
F.prototype.school = "中北大学";
function S() { }
var f = new F("Tom");
F.prototype = f.constructor;
S.prototype = f;//指定S的原型为f对象 此时的S的对象就拥有了F的属性和通过prototype绑定的原型属性
var s = new S();
console.log(s.name + "--" + s.school);
//一个构造函数的prototype属性获取到的都是通过prototype属性绑定的对象或属性
console.log(S.prototype);//F的对象
console.log(F.prototype);//本身的prototype绑定的属性和constructor
console.log(s.__proto__);
console.log(s.__proto__.__proto__.__proto__.__proto__);
</script>
创建对象的方式:
//使用原型的方式创建对象
function Student() { };
Student.prototype.name = "张三";
Student.age = 22;
var stu1 = new Student();
var stu2 = new Student();
console.log(stu1.name);
console.log(stu2.name);
//混合方式创建对象:构造方法 + 原型
function Stu(name, age, phone) {
this.name = name;
this.age = age;
this.phone = phone;
}
Stu.prototype.school = "中北大学";
var s1 = new Stu("jack", 21, "1111111111111");
var s2 = new Stu("lucy", 18, "22222222222222");
console.log(s1.name + "--" + s1.age + "--" + s1.school);
console.log(s2.name + "--" + s2.age + "--" + s2.school);
js多态的体现
function show(f) {
console.log(f.name);
}
var son = new S("王五");
show(f);
ECMAScript部分 :js的核心语法部分:基础部分(变量 语句 数据类型 运算符 面向对象 原型 原型链)
DOM
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。
模型:
节点:
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
节点的类型有七种:
- Document:整个文档树的顶层节点
- DocumentType:doctype标签(比如<!DOCTYPE html>)
- Element:网页的各种HTML标签(比如<body>、<a>等)
- Attr:网页元素的属性(比如class=“right”)
- Text:标签之间或标签包含的文本
- Comment:注释
- DocumentFragment:文档的片段
浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。
常用节点分为四类:
- 文档节点(Document):整个HTML文档
- 元素节点(Element): HTML文档中的HTML标签
- 属性节点(Attr):元素的属性
- 文本节点(Text): HTML标签中的文本内容
console.log(document.nodeName);//#document
console.log(document.nodeType);//9
console.log(document.nodeValue);//null
文档节点(document):
文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。
document对象作为window对象的属性存在的,我们不用获取可以直接使用。
通过该对象我们可以在整个文档访问内查找节点对象,并可以通过该对象创建各种节点
元素节点(Element)
HTML中的各种标签都是元素节点,这也是我们最常用的一个节点。
浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。
文本节点(Text)
文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。
它包括可以字面解释的纯文本内容。
文本节点一般是作为元素节点的子节点存在的。
获取文本节点时,一般先要获取元素节点。在通过元素节点获取文本节点。
属性节点(Attr)
属性节点表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
可以通过元素节点来获取指定的属性节点。
例如:元素节点.getAttributeNode(“属性名”);
注意:我们一般不使用属性节点。
<body>
<div id="d">这是div的文本内容</div>
</body>
<script type="text/javascript">
console.log(document.nodeName);//#document
console.log(document.nodeType);//9
console.log(document.nodeValue);//null
//当使用dom操作文档的时候 首先必须保证dom对象已经加载并完成
var d = document.getElementById("d");
console.log(d.firstChild.nodeValue)
console.log(d.getAttributeNode("id"));
</script>
window.onload = function () {
console.log(document.nodeName);//#document
console.log(document.nodeType);//9
console.log(document.nodeValue);//null
//当使用dom操作文档的时候 首先必须保证dom对象已经加载并完成
var d = document.getElementById("d");
console.log(d.firstChild.nodeValue)
console.log(d.getAttributeNode("id"));
}
nodeName属性:
返回节点的名称
console.log(d.nodeName);//返回标签名称并大写
nodeType属性:
返回一个整数值,表示节点的类型。
- 文档节点(document):9,对应常量Node.DOCUMENT_NODE
- 元素节点(element):1,对应常量Node.ELEMENT_NODE
- 属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
- 文本节点(text):3,对应常量Node.TEXT_NODE
- 文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE
- 文档类型节点(DocumentType):10,对应常量Node.DOCUMENT_TYPE_NODE
- 注释节点(Comment):8,对应常量Node.COMMENT_NODE
console.log(d.nodeType);
console.log(d.nodeType == Node.ELEMENT_NODE)//true
nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,其他类型的节点一律返回null。同样的,也只有这三类节点可以设置nodeValue属性的值,其他类型的节点设置无效
d.firstChild.nodeValue = "这是修改之后的文本值";
textContent属性:
返回当前节点和它的所有后代节点的文本内容
var d = document.getElementById("d");
console.log(d.textContent);
textContent属性自动忽略当前节点内部的 HTML 标签,返回所有文本内容。
该属性是可读写的,设置该属性的值,会用一个新的文本节点,替换所有原来的子节点。它还有一个好处,就是自动对 HTML 标签转义。这很适合用于用户提供的内容
var d = document.getElementById("d");
d.textContent = "<s>这是新增内容</s>"
上面代码在插入文本时,会将<s>标签解释为文本,而不会当作标签处理。
事件:
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
JavaScript 与 HTML 之间的交互是通过事件实现的。
对于 Web 应用来说,有下面这些代表性的
事件:点击某个元素、将鼠标移动至某个元素上方、 按下键盘上某个键,等等。