constructon prototype proto 三者之间的关系
-
prototype
:指原型对象(所有实例的公共祖先) -
__proto__
:原型链 (也就是原型之间的连接点) -
constructon
:构造函数,每个构造函数都有一个原型对象(prototype)原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针.
注:每一个实例都会有一个 constructon 方法和 prototype 方法,如果有构造函数会覆盖 constructon,否则 constructon默认创建```js function teacher(name, age) { this.name = name; this.age = age; } teacher.prototype.getAge = function () { return this.age; }; let teacher1 = new teacher("李四", 33); console.log(teacher1); let teacherAge = teacher1.getAge(); console.log(teacherAge); console.log(teacher.prototype === teacher1.__proto__); //输出 true //通过此处我们可以发现访问原型可以通过两种方式 //1.通过实例来访问 //2.通过构造函数来访问 console.log(Object.prototype === teacher.prototype); //false console.log(Object.prototype === teacher.__proto__.__proto__); ///true //Object.prototype是所有实例的父类 console.log(Object.getPrototypeOf(teacher1) === teacher.prototype); //true //js中不太建议我们使用__proto__的方式去查找或者修改原型,在es6中出现了Object.getPrototypeOf(obj),obj:要返回其原型的对象。) console.log(Object.prototype.__proto__); // 结果 null // 因为原型链的最顶点是 Object.prototype 它的 __proto__ 属性是 null // instanceof:判所以当我们要判断一个对象是否是数组时或者判断某个变量是否是某个对象的实例则要选择使用另一个关键语法instanceof,instanceof返回的是一个布尔值 // 判断数组 let arr = [1, 2]; console.log(arr instanceof Array); //true // instanceof 只能判断数组和某个变量是是否是某个对象的实例 let bb = ""; console.log(bb instanceof String); //false // 判断实例 function Person() {} let person = new Person(); console.log(person instanceof Object); //true ```
确定原型和实例的关系
使用原型链后, 我们怎么去判断原型和实例的这种继承关系呢? 方法一般有两种.
第一种是使用 instanceof 操作符, 只要用这个操作符来测试实例(instance)与原型链中出现过的构造函数,结果就会返回 true. 以下几行代码就说明了这点.
let arr = [1, 2];
console.log(arr instanceof Array); //true
// instanceof 只能判断数组和某个变量是是否是某个对象的实例
let bb = "";
console.log(bb instanceof String); //false
// 判断实例
function Person() {}
let person = new Person();
console.log(person instanceof Object); //true
第二种是使用 isPrototypeOf() 方法, 同样只要是原型链中出现过的原型,isPrototypeOf() 方法就会返回 true, 如下所示.
function Person() {}
function Teacher() {}
Teacher.prototype = new Person();
let teacher = new Teacher();
console.log(Object.prototype.isPrototypeOf(teacher)); //true
console.log(Person.prototype.isPrototypeOf(teacher)); //true
console.log(Teacher.prototype.isPrototypeOf(teacher)); //true
console.log(Teacher.prototype.isPrototypeOf(Person)); //false
继承
- 原型链继承
// 在使用圆形链继承时会出现引用类型值共享的问题
function Person(name, age) {
this.name = name;
this.age = age;
this.height = 1.78;
this.arr = [];
}
Person.prototype.getName = function () {
return "我是父类的方法";
};
function Teacher(banji, sex) {
this.banji = banji;
this.sex = sex;
this.sexual = ["1", "woman"];
this.getClass = function () {
return this.banji;
};
}
//在子类中写方法时不可以这样写,否则会报错
// Teacher.prototype.getClass=function(){
// return this.banji
// }
Teacher.prototype = new Person("张三", 33);
let teacher = new Teacher("6年纪一班", "男");
let teacher2 = new Teacher("6年纪一班", "男");
console.log(teacher.getName());
console.log(teacher.getClass());
console.log(teacher.__proto__ === teacher2.__proto__);
// 修改值
console.log((teacher.height = 1.88));
console.log("teacher", teacher.height); //1.88
console.log("teacher2", teacher2.height); //1.78
//在new person时会自动创建一个对象,然后在new teacher和teacher2时会把对象分别赋值teacher和teacher2,对象和数组时引用类型的数据所以会把teacher和teacher中的值修改掉
console.log(teacher.arr.push(18));
console.log("teacher", teacher.arr); // [18]
console.log("teacher2", teacher2.arr); // [18]
console.log(teacher);
console.log(teacher2);
- 构造函数继承
// 构造函数继承:无法拿到原型上的方法
function Person(name, age) {
this.name = name;
this.age = age;
this.arr = [1, 2, 3, 4];
this.getName = function () {
console.log(this.name);
};
}
Person.prototype.say = function () {
console.log("222");
};
function Teacher(arr, name, age) {
Person.call(this, arr, name, age);
}
let teacher1 = new Teacher();
let teacher2 = new Teacher();
teacher1.arr.push(5);
console.log(teacher1.arr); //输出 [1, 2, 3, 4, 5]
console.log(teacher2.arr); //输出 [1, 2, 3, 4]
teacher1.say(); //输出 "222"
teacher1.getName(); //undefined
- 组合继承
function Person(name, age) {
this.name = name;
this.age = age;
this.arr = [];
this.fzunCon = function () {
console.log(this.name);
};
}
Person.prototype.sayName = function () {
console.log(this.name);
};
function Teacher(arr) {
Person.call(this, arr);
}
Teacher.prototype = new Person();
let teacher1 = new Teacher("张三", 222);
let teacher2 = new Teacher("张三2", 222);
teacher1.arr.push(5);
console.log(teacher1.arr); //[5]
console.log(teacher2.arr); //[]
teacher1.sayName(); //"张三"
teacher2.fzunCon(); //"张三2"