1、对象的创建模式有哪些?
1、Object构造函数模式
2、对象字面量模式
3、工厂模式
4、自定义构造函数模式
5、构造函数和原型的组合模式
1.1 Object构造函数模式
*套路:先创建空Object对象,再动态添加属性/方法
*适用场景:起始时不确定对象内部数据
缺点:语句太多
<script type="text/javascript">
var p = new Object();
p.name = 'Tom';
p.age = 13;
p.setName = function (name) {
this.name = name;
}
//测试
p.setName('Jak');
console.log(p.name);//Jak
</script>
1.2 对象字面量模式
*套路:使用{}创建对象,同时指定属性和方法‘
*使用场景:起始时对象 内部数据是确定的
缺点:
*问题:如果创建多个对象,有重复代 码
<script type="text/javascript">
var p= {
name : 'Tom',
age : 13,
setName:function (name) {
this.name = name;
}
};
//测试
p.setName('Jak');
console.log(p.name);//Jak
</script>
1.3工厂模式
1.3.1 什么是工厂函数?
工厂函数:返回一个对象的函数都可以称为工厂函数。
工厂模式:
*套路:通过工厂函数动态创建对象并返回
*使用场景:需要创建多个对象
缺点
*问题:**对象没有一个具体的类型,都是Object类型**
<script type="text/javascript">
function createPerson(name,age){//工厂函数
var obj={//创建对象
name:name,
age:age,
setName:function (name) {
this.name = name;
}
}
return obj;//返回对象
}
var p1=createPerson('Yom',19);//调用函数
var p2=createPerson('Tom',12);
console.log(p1,p2);//返回对象Object,在隐式原型__proto__下的setName不相等
</script>
1.4 自定义构造函数模式(平常使用的多,推荐)
*套路:自定义构造函数,通过new创建对象
*使用场景:需要创建多个类型确定的对象
缺点
*问题:每个对象都有相同的数据,浪费内存
<script type="text/javascript">
//定义类型
function Person(name,age) {
this.name = name,
this.age = age,
this.setName = function (name) {
this.name = name;
}
}
function Student(name,age) {
this.name = name,
this.age = age,
this.setName = function (name) {
this.name = name;
}
}
//用new创建实例
var p1=new Person('Yom',19);
var p2=new Student('Tom',12);
p1.name='Jvk';
console.log(p1 instanceof Person);//true,即对象不再是单一的Object,
console.log(p1.name,p2.name);//Jvk Tom
</script>
1.5构造函数和原型的组合模式
*套路:自定义构造函数,属性在函数中初始化,方法添加到原型上
*使用场景:需要创建多个类型确定的对象
<script type="text/javascript">
function Person(name,age) {
this.name = name;
this.age = age
}
Person.prototype.setName=function (name) {//将方法绑定在构造函数的原型上
this.name=name;//this
}
var p1=new Person('Tom',12);
var p2=new Person('Jav',22);
console.log(p1,p2);////返回对象,隐式原型上的构造器一样,说明p1和p2是在同一个对象上
console.log(p1.name);//Tom
</script>
2、继承模式
2.1 继承模式有哪些?
1、原型继承
2、借用构造函数继承
3、原型和借用构造函数的组合继承
2.1原型继承
1、套路:
*1.1、定义父类型构造函数
*1.2.、给父类型的原型添加方法
*1.3、定义子类型的构造函数
*1.4、创建父类型的对象赋值给子类型的原型
*1.5、将子类型原型的构造属性设置为子类型
*.1.6、给子类型原型添加方法
*1.7、创建子类型的对象,可调用父类型的方法
2、关键
*子类型的原型为父类型的一个实例对象
<script type="text/javascript">
//父类型
function Supper() {
this.supProp = 'supProp';
}
Supper.prototype.showSupper = function () {//将父类型的方法绑定到原型上
console.log(this.supProp);
}
//子类型
function SubPper() {
this.subProp = 'subProp';
}
//实现原型继承的核心代码如下:
//1.实现继承的方法:子类型的原型为父类型的一个实例对象
SubPper.prototype = new Supper();
//2.将SubPper原型的constructor指向SubPper
SubPper.prototype.constructor=SubPper;
//给子类型添加方法
SubPper.prototype.showSubPper = function () {
console.log(this.subProp);
}
//3.创建子类型的实例
var sub = new SubPper();
sub.showSupper();
sub.toString();
console.log(sub.constructor);
</script>
2.2借用构造函数继承
1、套路
*1、定义父类型的构造函数
*2、定义子类型的构造函数
*3、在子类型构造函数中调用父类型的构造函数
2、关键
*在子类型构造函数中通过call()调用父类型构造函数。使用call()借用Person的属性执行
<script type="text/javascript">
function Person(name,age){
this.name=name;
this.age=age;
}
function Student(name,age,price) {
Person.call(this,age,name);//this是子类型的实例。call是借用执行,相当于this.Person(name,age)
// this.name=name;
// this.age=age;
this.price=price;
}
var s=new Student('Tom',12,100)
console.log(s.name,s.age,s.price);
</script>
2.3原型和借用构造函数的组合继承
- 1、利用原型链实现对父类型对象的方法继承
- 2、利用call()借用父类型构造函数初始化相同属性
<script type="text/javascript">
function Person(name,age){//创建父类型的构造函数
this.name=name;
this.age=age;
}
Person.prototype.setName=function (name) {
this.name=name;
}
//重点一:
function Student(name,age,price) {
Person.call(this,age,name);//call是借用执行,相当于this.Person(name,age)
// this.name=name;
// this.age=age;
this.price=price;
}
//重点二:
//子类型的原型等于父类型的实例,为了看到父类型的方法和属性
Student.prototype=new Person();
//修正原型上的constructor
Student.prototype.constructor=Student;
Student.prototype.setPrice=function (price) {
this.price=price;
}
var s=new Student('Tom',12,2222);
s.setName('Emoo');
s.setPrice(10000);
console.log(s.name,s.age,s.price);
</script>