二. 原型
- 更好的解决方法: prototype
Js 规定每个函数都有 prototype 属性,指向一个对象;这个对象的所有属性和方法都被函数所拥有,这就意味着我们可以把构造函数对象的属性和方法直接定义在prototype上
构造函数和原型 和实例对象之间的关系
1) Person.prototype.constructor == Person
2)实例对象中有一个指针__proto__ 指向 构造函数 prototype
Instance.__proto__ == Person.prototype
3)实例对象直接或间接继承构造函数的所有属性和方法
- 原型链
当代码读取某个对象的方法时,都会执行一次搜索:
现在自己身上找,找不到就到原型上找
- 原型对象的使用建议
a) 私有成员(一般是非函数成员)放在构造函数中
b) 共有成员(函数成员)放在原型对象对象中
c) 手动重置 constructor 属性
function Person(name ,age){
this.name = name;
this.age = age
}
Person.prototype ={
Constructor: Person,
Type: “human”,
sayHello: function(){
console.log(this.name)
}
}
三.继承
javascript中实现继承的方式: 1) 对象与对象之间的继承-》 对象的拷贝 存在的问题: 对象与对象之间无法实现 数据类型 的继承
var wjl = {
name: '王健林',
money: 10000000,
cars: ['玛莎拉蒂', '特斯拉'],
houses: ['别墅', '大别墅'],
play: function () {
console.log('打高尔夫');
}
}
var wsc = {
name: '王思聪'
}
function extend(parent, child) {
for (var key in parent) {
// 不给wsc复制同名的属性
if (child[key]) {
continue;
}
child[key] = parent[key];
}
}
extend(wjl, wsc);
console.dir(wsc);
wsc.play(); //打高尔夫
2)属性继承:
function student(name,age){
Person.call(this,name,age);
}
存在的问题: 借用构造函数 无法继承父类型构造函数原型中的 方法
3)拷贝继承:
Person.prototype.sayName = function(){
Cnonsole.log(“sayHello”);
}
function Student(name,age){
Person.call(this,name,age);
}
For(var key in Person.prorotype){
Student.prototype[key] = Person.prototype[key];
}
存在的问题:
如果子类型重新对自身的 原型对象进行了修改 会影响 父类型的原型 ,一般情况使用比较少,主要用于对 对象方法的继4) 组合继承(构造函数+原型函数):
function Student(name,age){ Person.call(this,name,age); } //让子类型的原型指向 父类型的实例对象, 继承父类型的方法, 同时不影响父类型的原型对象, 这样有第二个子类型继承父类型的时候, 原型对象不会改变 Student.prototype = new Person(); //如果不修改constructor, 正常情况下,不会影响使用; 只在一种情况下会产生影响: 在不知道 student1 是由哪个函数实例化出来的情况下,想要复制一个:
var student2 = student1.constructor(); Student.prototype.constructor = Student; //exam就是 Student 的独有方法, 不会影响父类型以及其他的子类型 Student.prototype.exam = function() { console.log("考试"); } var nora = new Student('nora', 25); 实例对象nora调用 sayName 方法时, 先在 实例Nora本身上找这个方法; 发现没有,继续在Nora的原型对象上找(由于我们已经把Student 的原型对象改为一个Person实例),发现 Person实例上仍然没有这个方法, 所以继续在 Person实例的 原型对象上找; 找到此方法,调用;
//原型对象和实例对象中的 constructor
//constructor指向的不是实例化实例的构造函数,而是实例化该对象的构造函数的原型的构造函数
console.log(Student.prototype.constructor === nora.constructor) //true
console.log(nora.__proto__.constructor === nora.constructor) //true
nora 可以通过 .__proto__.constructor 获取; 也可以通过 nora.constructor 获取
Student 只能通过 .prototype.constructor 获取;