前言
学习JavaScript(1)关于对象
参考红宝书JavaScript高级程序设计第三版第六章
虽然object构造函数或对象的字面量都可以用来创建单个对象,但这些方法有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码,为解决这个问题,有以下几种常用方式创建对象
一.工厂模式
一种函数,使用它来封装以特定接口创建对象的细节
function cat(name,year,color){
let cat = new Object();
cat.name = name;
cat.year = year;
cat.color = color;
cat.introduction = function(){
return this.name + " is a " + this.year + " years old " + this.color + " cat";
}
return cat;
}
let cat1 = cat("vivi",1,"black");
console.log(cat1.introduction());
//vivi is a 1 years old black cat
let cat2 = cat("cici",12,"white");
console.log(cat2.introduction());
//cici is a 12 years old white cat
可以无数次调用这个函数,而每次它都会返回三个属性和一个方法的对象。
然而就有一个新的问题:
cat1和cat2的对象类型是否相同?
工厂模式无法判断
二.构造函数模式
要创建cat的新实例,必须使用new操作符。以这种方式调用构造函数经历以下四个步骤:
1)创建一个新对象
2)将构造函数的作用域赋给新对象(this指向新对象)
3)执行构造函数中的代码(新对象添加属性)
4)返回新对象
注意!按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头
function Cat(name,year,color){
this.name = name;
this.year = year;
this.color = color;
this.introduction = function(){
return this.name + " is a " + this.year + " years old " + this.color + " cat";
}
}
let cat1 =new Cat("vivi",1,"black");
console.log(cat1.introduction());
let cat2 =new Cat("cici",12,"white");
console.log(cat2.introduction());
之所以称之为构造函数,是因为这创建的对象都有一个constructor(构造函数)属性,在这一点上我们就可以得到对象的类型,从而判断是否为相同对象。
console.log(cat1.constructor)
//这里返回的是整个对象的定义
console.log(cat1.constructor == Cat)
//true
console.log(cat1.constructor == cat2.constructor)
//true
然而我们发现构造函数也有一个缺点,以构造函数方式创建函数,会导致不同的作用域链和标识符解析,但创建Function新实例的机制仍然是相同的。因此,不同实例上的同名函数是不相等的
console.log(cat1.introduction == cat2.introduction)
//false
三.原型模式
我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象。prototype就是通过调用构造函数而创建的哪个对象实例的原型对象
原型对象的好处是,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中
function Cat(){
}
Cat.prototype.name = "kiki";
Cat.prototype.year = 1;
Cat.prototype.color = "black";
Cat.prototype.introduction = function(){
return this.name + " is a " + this.year + " years old " + this.color + " cat";
}
let cat1 = new Cat();
console.log(cat1.introduction());
//kiki is a 1 years old black cat
let cat2 = new Cat();
cat2.name = "cici";
console.log(cat2.introduction());
//cici is a 1 years old black cat
在原型模式创建时,不同实例上的同名函数相等
console.log(cat1.introduction == cat2.introduction);
//true
四.组合使用构造函数模式和原型模式(常用)
创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性
function Cat(name,year,color){
this.name = name;
this.year = year;
this.color = color;
}
Cat.prototype = {
constructor: Cat,
introduction : function(){
return this.name + " is a " + this.year + " years old " + this.color + " cat";
}
}
let cat1 =new Cat("vivi",1,"black");
console.log(cat1.introduction());
//vivi is a 1 years old black cat
let cat2 =new Cat("cici",12,"white");
console.log(cat2.introduction());
//cici is a 12 years old white cat
console.log(cat1.name == cat2.name);
//false
console.log(cat1.introduction == cat2.introduction);
//true
组合使用构造函数模式和原型模式是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法,是定义引用类型的一种默认模式
总结
个人学习笔记总结,每天进步多一点