js中面向对象有三大特性:继承,多态,封装。今天主要学习了对象的原型与继承,以下是自己所做的总结:
1.什么是继承?
继承就是父对象的成员,子对象无需创建,即可直接使用。
2.为什么?
既能够解决代码重用的问题,又可以节约内存
3.何时使用?
只要一个子对象中包含多个相同的成员,就可以将相同成员保存到父对象中一次,所有的子对象共同使用。
4.如何使用?
①原型对象:集中保存所有子对象共有成员的父级对象
②原型对象不用创建,每个构造函数都自带一个原型对象
5.如何获得原型对象?
①构造函数.prototype
因为构造函数自带prototype属性,构造函数.prototype指向父级对象
②子对象._proto_
6.如何向原型对象中添加共有成员?
构造函数.prototype.新成员=xxx
7.如何判断是自有属性还是共享属性?
①自有属性:直接保存在当前对象本地的属性
obj.hasOwnProperty("属性名")
true----是自有属性
false---不是自有属性
(注意:不是自有属性,但是不能确定是共享属性,因为
只要自己没有,无论原型对象中有没有,都会返回false)
②共享属性:保存在原型对象中,多个子对象共享的属性
判断是否是共享属性有两个条件:
a.首先,不是自有属性
b.然后,判断可以访问到这个属性
!obj.hasOwnProperty("属性名") && obj.属性名!=undefined
例:
function Student(name,age){
this.name=name;
this.age=age;
}
Student.prototype.intr=function(){
console.log(
"my name is"+this.name
+",my age is"+this.age
);
}
var tom=new Student("tom",21);
tom.intr();
var mary=new Student("mary",22);
mary.intr();
注意:
①这里首先构造了一个Student对象,包含name,age属性
②因为在构造函数中自带prototype属性,所以在 student.prototype下写了一个intr()方法
③当var tom = new Student(“tom”,21)实例化tom对象的时候new做了四件事:
a.首先,创建了一个tom对象
b.其次,设置tom的 _ proto _属性继承构造函数Student的原型对象
c.然后,用新的对象(tom)去调用构造函数,并且将this替换为tom
d.返回新对象的地址给变量
如图所示:
8.原型链:
①由各级对象的_ proto _属性,逐级继承,形成各自的链式结构
②Object.prototype是所有对象的顶级父对象
③Function.prototyope是所有函数对象的父对象
④原型链控制着对象的成员的使用顺序:
a.优先使用自有属性
b.自己没有,才沿着原型链向对象查找,
除非整个原型链上没有,才 说明不可用。
⑤如图所示:
9.原型链和作作用域链的区别:
①原型链控制着对象的成员的使用顺序:
优先使用自有属性,自己没有,才延着原型链向父对象查找,除非整个原型链上没有,才说明不可用
②作用域链控制着变量的使用顺序:
优先使用函数作用域中的局部变量,如果局部没有,延着作用域链向全局找,除非整个作用域链都没有,才说明不可用
注意:
①this.name加上this是在访问对象的属性,延着原型链进行查找
②name不加this是在访问全局的变量,延着作用域链进行查找
10.如何判断继承关系
①根据原型对象判断:
father.isPrototypeOf(child)
判断father是否是child的父级对象,也就是判断child是否继承自father
强调:不仅检查直接父对象,而且检查整个原型链
②根据构造函数判断:
child instanceof 构造函数
判断child是否是构造函数创建出的实例
强调:不仅检查直接父级,而且检查整个原型链