原型对象
01 原型对象概念
- 在构造函数创建出来的时候,系统会默认帮构造函数创建一个关联的新对象,就是原型对象,其默认为一个空对象
- 构造函数找到原型对象:prototype
- 原型对象找到构造函数:constructor
注意:原型对象本身也是一个对象,这个对象是Object类型,有一个属性constructor
02 原型对象的作用
- 构造函数的原型对象的属性与方法可以被构造函数创建的对象共享
03 如何访问原型对象
- 构造函数.prototype
- 对象.__ proto__(注意:正常开发中不要使用这个属性,因为ECMA标准中并没有这个属性,是浏览器开发商提供的方便调试,直到E6纳入了标准中)
- Object.getPrototypeOf(对象)
04 如何使用原型对象
-
利用对象的动态特性
实例成员:实例对象的属性与方法 原型成员:原型对象上的属性与方法
代码示例
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.showAge = function () {
console.log(this.age);
};
Person.prototype.des = "描述信息";
var p1 = new Person("张三",20);
console.log(p1);
console.log(Person.prototype);
//删除原型对象上面的属性
//delete Person.prototype.des; //删除成功
console.log(p1.des);
//删除对象中不存在的属性,返回true
console.log(delete p1.des); //不能使用这种方式直接删除原型对象上面的属性
console.log(p1.des);
- 字面量的方式直接替换
代码示例1
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype = {
showName:function () {
console.log(this.name);
},
showAge:function () {
console.log(this.age);
},
des:"描述信息",
friends:["乌拉乌拉","哗啦哗啦","滴答滴答"]
}
var p1 = new Person("张三",20);
var p2 = new Person("张四",20);
p1.showName();
p2.showName();
//原型成员会被所有的对象(构造函数)共享
p1.des = "测试"; //该行代码添加属性在p1上面,并不会改变原型属性
console.log(p2.des); //描述信息
console.log(p1);
console.log(p2);
p1.friends.push("巴拉巴拉");
console.log(p1);
console.log(p2); //会受到影响
//使用对象.这种方式来设置属性的时候,
// 如果这个属性是值类型那么表示添加一个实例属性des,不会修改原型属性
// 如果这个属性是引用类型,那么可以修改到原型属性
Person.prototype.des = "0000";
console.log(p1.des); //测试
console.log(p2.des); //0000
注意:使用字面量方式替换原来的原型对象,需要手动添加构造器属性,因为字面量创建的对象本身没有构造器属性,那么会去他的原型对象上找,而通过字面量创建的对象是由Object创建的,其原型对象的构造器属性为object,所以在没有添加构造器属性之前,Person.prototype.constructor = Object
代码示例2
function Person(name,age) {
this.name = name;
this.age = age;
}
// var o = {};
// var o = new Object();
//字面量创建的对象是Object创建的
//该对象的构造函数是 Object
//该对象的构造函数也有自己的原型对象 Object.prototype
//该对象的构造函数也有自己的原型对象,内部有构造器属性 Object.prototype.constructor =》Object,所以需要手动添加一个构造器属性
//对象本身并没有构造器属性,在访问该属性的时候访问的是其原型对象上面的属性
Person.prototype = {
constructor:Person,
showName:function () {
console.log(this.name);
},
showAge:function () {
console.log(this.age);
}
};
var p1 = new Person("张三",20);
console.log(Person.prototype.constructor == Person); //Person
console.log(p1);
代码示例
function Dog() {
}
//构造函数 Dog
//构造函数的原型对象 Dog.prototype
//原型对象找到构造函数 Dog.prototype.constructor ==>Dog
Dog.prototype.name = "默认的名称";
// Dog.prototype = {
// name:"默认的名称"
// };
console.log(Dog.prototype);
var dog1 = new Dog();
var dog2 = new Dog();
console.log(dog1.name);
console.log(dog2.name);
console.log(dog1.\_\_ proto\_\_== Dog.prototype); //true
console.log(Object.getPrototypeOf(dog2) == Dog.prototype); //true
05 构造函数,原型对象与对象的关系
06 原型对象解决函数共享问题
建议:属性写在构造函数上,方法写在原型对象上
注意:对象访问属性与方法时,会先在自己身上查找,没有再去原型对象上查找。
代码示例
function Person(name) {
this.name = name;
}
//设置构造函数的原型对象
Person.prototype.showName = function () {
console.log(this.name);
}
var p1 = new Person("张三");
var p2 = new Person("张三丰");
p1.showName(); //张三
p2.showName(); //张三丰
console.log(p1.showName == p2.showName); //true
//注意:下面的代码在p1上面添加了一个showName方法并没有修改原型对象。
p1.showName = function () {
console.log("测试");
};
p1.showName(); //测试
p2.showName(); //张三丰
07 原型对象位置设置问题
注意:在设置(替换)原型对象前后创建的对象指向的原型对象不是同一个
代码示例
//01 提供构造函数
function Person(name,age) {
this.name = name;
this.age = age;
}
//03 创建实例对象
var p1 = new Person("张三",20);
//02 设置原型对象
Person.prototype = {
constructor:Person,
showName:function () {
console.log(this.name);
}
}
var p2 = new Person("李四",20);
p2.showName(); //李四
p1.showName(); //报错,因为p1是在替换原型对象之前创建的,其原型对象只有一个constructor属性,没有showName方法,所以报错。
08 hasOwnProperty方法
hasOwnProperty:判断某个对象是否拥有指定的实例属性(不包括原型成员)
in关键字 :检查对象是否拥有指定的成员(实例成员与原型成员)
代码示例
function Person(name) {
this.name = name;
}
Person.prototype.hi = "hi";
Person.prototype.show = function () {
};
var p1 = new Person();
//语法 对象.hasOwnProperty("属性")
console.log(p1.hasOwnProperty("name")); //true
console.log(p1.hasOwnProperty("age")); //false
console.log(p1.hasOwnProperty("hi")); //false
//语法 “属性” in 对象
console.log("name" in p1); //true
console.log("age" in p1); //false
console.log("hi" in p1); //true
console.log("show" in p1); //true
09 isPrototypeOf方法
isPrototypeOf:判断某个对象是否是另一个对象的原型对象
代码示例
function Person(name) {
this.name = name;
}
var obj = {};
var o = {
hi:"hi"
}
Person.prototype = o;
var p1 = new Person("李四");
//Object.prototype Object构造函数的原型对象
console.log(o.isPrototypeOf(p1)); //true 判断o是否是p1的原型对象
console.log(Object.prototype.isPrototypeOf(p1)); //true
实例化与实例
实例化:构造函数创建对象的过程
实例(对象):构造函数创建出来的对象是该构造函数的一个实例对象;在说实例的时候需要指明构造函数。