上次说到了构造函数的注意事项 ! 接下来是构造函数的原型对象
构造函数的原型对象
原型对象是什么?
- 在构造函数创建出来的时候,系统会默认帮构造函数创建并关联的一个新对象
- 自定义构造函数的原型对象默认是一个空对象。
原型对象的作用是什么?
- 构造函数中的原型对象中的属性和方法可以被使用该构造函数创建出来的对象使用。
- 即以自定义构造函数方式创建出来的所有对象,自动拥有和共享该构造函数的原型对象中的所有属性和方法。
如何访问构造函数的原型对象
构造函数.protoType
如何为构造函数的原型对象添加属性和方法
- 利用对象的动态特性来为构造函数的原型对象添加属性和方法
- 通过我们把"构造函数的原型对象"简化为"构造函数的原型"。
- **示例代码 : **
//1. 提供构造函数
function Student(number,name,age) {
//1.1 设置对象的属性
this.number = number;
this.name = name;
this.age = age;
//1.2 设置对象的方法
this.read = function () {
console.log("阅读");
}
}
//2. 使用构造函数来创建对象
var stu1 = new Student("20160201","严雯",18);
var stu2 = new Student("20160202","严二雯",16);
//3. 设置构造函数的原型
//3.1 为构造函数的原型对象添加属性
Student.prototype.className = "神仙特技1班";
//3.2 为构造函数的原型对象添加方法
Student.prototype.description = function () {
console.log("我的名字是" + this.name + "学号是" + this.number + "班级是" + this.className);
};
//4. 尝试访问
console.log(stu1.className);
console.log(stu2.className);
stu1.description();
stu2.description();
/*
原型属性和原型方法|实例属性和实例方法
在构造函数内部设置的属性 => 实例属性
在构造函数内部设置的方法 => 实例方法
在构造函数的原型对象上设置的属性 => 原型属性
在构造函数的原型对象上设置的方法 => 原型方法
如果实例属性(方法)和原型属性(方法)存在同名,那么对象在使用属性(方法)的时候,访问的是
实例属性(方法)还是原型属性(方法)?
说明:使用构造函数创建的对象在访问属性或调用方法的时候:
首先在内部查找有没有对应的实例属性(方法)
如果有,那么就直接使用,如果没有找到,那么就继续去构造函数的原型中查找
原型对象中如果存在该属性或方法,那么就直接使用,如果不存在指定的属性则返回undefined,如果不存在指定的方法则报错
注意点
通常在创建对象之前设置构造函数的原型对象(提供共享的属性|方法)
访问原型对象的正确方法是 构造函数.protoType 而不是 对象.protoType
*/
使用原型解决构造函数创建对象的问题
- 示例代码 :
//1. 提供构造函数
function Student(number,name,age) {
this.number = number;
this.name = name;
this.age = age;
}
//2. 设置构造函数的原型方法
Student.prototype.description = function () {
console.log("我的名字是" + this.name + "学号是" + this.number + "年龄是" + this.age);
};
//3. 使用构造函数来创建对象
var stu1 = new Student("20170201","严雯",18);
var stu2 = new Student("20170202","严二雯",16);
//4. 调用创建该对象的构造函数的原型对象中的方法(检查原型方法)
stu1.description();
stu2.description();
//5. 验证构造函数创建出来的多个对象共享原型对象的属性和方法
console.log(stu1.description == stu2.description);
实例化对象和实例
实例化
通过构造函数创建具体对象的过程实例
通过构造函数实例化出来的对象,我们称之为该构造函数的一个实例**注意点 : **
在说实例的时候,一定要指定是某个具体构造函数的实例
示例代码 :
//1. 提供一个构造函数
function Person() {
}
//2. 根据该构造函数创建对象 == 使用Person构造函数实例化对象
var p1 = new Person();
//p1 是构造函数Person的一个实例
原型的使用方法
- 利用对象的动态特性来设置原型对象
function Person(){
this.name = "默认的名称";
}
//设置原型对象
//成员= 属性|方法
//1. 增加成员
Person.prototype.des = "我是直立行走的人";
Person.prototype.logName = function(){
console.log(this.name);
}
//2. 修改成员
Person.prototype.des = "我是直立行走的人++++";
//console.log(Person.prototype);
var p1 = new Person();
console.log(p1.des);
p1.logName();
//3. 删除成员
//delete关键字
//语法 delete 对象.属性
//不能用这种方式删除原型对象上面的属性(删除的是自己的属性)
//console.log(delete p1.des);
// 只能通过这种方式删除
delete Person.prototype.des ;
console.log(p1.des);
- 实例成员
1.实例属性
2.实例方法
- 原型成员
1.原型属性
2.原型方法
-
替换原型对象(字面量)
注意点:
1.如果是替换了原型对象,那么在替换之前创建的对象和替换之后创建的对象她们指向的原型对象并不是同一个
2.构造器属性
在替换之后创建的对象中,它的构造器属性指向的不是Person构造函数,而是Object的原型对象的构造器属性
-
建议:
在设置完原型对象之后再统一的创建对象。
function Person(){
this.age = 40;
}
var p1 = new Person();
//var obj = new Object();
Person.prototype = {
// 注意:如果替换了原型对象,那么需要在原型对象中修正构造器属性
constructor:Person,
sayHi:function (){
console.log("hi");
}
};
var p2 = new Person();
//p2.constructor = Person; //在p2对象上添加了一个属性(constructor)
//var p3 = new Person();
//构造器属性
console.log(p1.constructor == p2.constructor); //false
// console.log(p1.constructor); //Person
// console.log(p2.constructor); //Object
// console.log(p2.constructor == p2.__proto__.constructor);
// console.log(p2.constructor == Object.prototype.constructor);
console.log(p2);
构造器
- 属性:constructor
- 值:与之关联的构造函数
-
注意点:
constructor是在原型对象身上的,我们通过对象.constructor访问得到的值其实就是原型对象中对应的值
使用原型对象的注意事项
- 如何访问原型对象上面的属性
1.对象.属性
2.构造函数.prototype.属性
- 属性的访问(读取)原则
1.就近原则,在访问属性的时候,先在对象自身查找(实例属性|方法),如果找到那么就直接使用
2.如果没有找到,那么就去它的原型对象身上查找,如果找到那么就使用,找不到则undefined或者是报错
- 设置原型属性
1.如果是左值,那么在设置对象的属性的时候,不会去原型对象上面去找(查找自己是否有,如果有就是修改,没有就是添加)
2.如果是右值,那么在读取值的时候,先查找自己,如果找不到,再去原型身上找
- 设置原型属性的方法:
1.只能通过构造函数.prototype.属性或者是直接替换原型对象的方式来设置
2.如果原型对象的属性是引用类型的,那么可以通过对象的方式来进行设置
- 示例代码1
function Person(){
this.des = "默认的描述信息"
}
Person.prototype = {
constructor:Person,
des :"描述信息",
logDes:function (){
console.log("嘲笑我吧");
}
}
//01 对象.属性
var p1 = new Person();
console.log(p1.des);
//console.log(Person.prototype.des);
p1.logDes();
console.log(p1.age);
- 示例代码2
function Person(){
}
Person.prototype = {
constructor:Person,
des :"描述信息",
}
var p1 = new Person();
var p2 = new Person();
//设置
//左值 --- 右值
//如果是左值,那么在设置对象的属性的时候,不会去原型对象上面去找(查找自己是否有,如果有就是修改,没有就是添加)
//如果是右值,那么在读取值得时候,先查找自己,如果找不到,再去原型身上找
// p1.hello(左值) = "hi"(右值);
Person.prototype.hello = "hello";
p1.hello = "hi";
console.log(p1.hello); //hi
console.log(p2.hello); //hello
- 示例代码3
function Person(){};
Person.prototype.className = "逍遥派修仙技能班01";
Person.prototype.showClassName = function(){console.log(this.className)};
Person.prototype.car = {type:"火车",price:"$ 44444.44"};
var p1 = new Person();
var p2 = new Person();
p1.showClassName();
p1.className = "洗衣服小白";
console.log(p1);
console.log(p2);
//如果原型对象的属性是引用类型的
p1.car.type = "飞船";
console.log(p1.car.type); //飞船
console.log(p2.car.type); //飞船
//补充
p1.car = {type:"火箭"};
console.log(p1.car.type); //火箭
console.log(p2.car.type); //飞船
p1.car = {};
console.log(p1.car.type); //undefined
console.log(p2.car.type); //飞船
指针
如果是使用构造函数创建对象,那么在创建的对象中,有一个<proto>指针指向其构造函数对应的原型对象
访问原型对象的方法
1.构造函数.prototype
2.对象.<proto>
- 注意点:
这个属性不是ECMA标准里的,它是部分浏览器厂商为了方便程序员开发和调试而提供的一个属性,是非标准的。 - **示例代码 : **
function Person(){}
Person.prototype.des = "des";
var p1 = new Person();
console.log(Person.prototype == p1.__proto__); //true
hasOwnProperty
- in 关键字
1.检查对象中是否有指定的属性(实例属性 + 原型属性)
2.遍历对象
3.语法:“属性” in 对象
hasOwnProperty
作用:检查对象中是否存在指定的属性(实例属性)
语法:对象.hasOwnProperty("属性")需求:
1.要求判断某个属性是否是原型属性,而且仅仅只是原型属性
2.该属性存在
3.该属性不是实例属性
- **示例代码 : **
Object.prototype.des = "des";
Object.prototype.age = "des";
var obj = {name:"zs",age:20};
console.log("name" in obj);
console.log(obj.hasOwnProperty("name"));
console.log(obj.des);
//in 和hasOwnProperty
console.log("des" in obj); //true
console.log(obj.hasOwnProperty("des")); //false
function isOnlyPrototypeProperty(propertyName,obj)
{
return (propertyName in obj) && !obj.hasOwnProperty(propertyName);
}
//验证
console.log(isOnlyPrototypeProperty("name", obj));
console.log(isOnlyPrototypeProperty("des", obj));
console.log(isOnlyPrototypeProperty("age", obj)); //false
isPrototype
- isPrototype判断是否是原型对象的
- instanceof 判断某个对象是否是指定构造函数的实例对象
- ** 示例代码 : **
function Person(){};
var demo = {};
var demo1 = {};
Person.prototype = demo;
Person.prototype.constructor = Person;
var p1 = new Person();
//判断某个对象是否是指定对象的原型对象
console.log(demo1.isPrototypeOf(p1));