对象的字面量方式创建
- 对象字面量
//(1)new构造函数
var obj = new Object();
obj.name = 'qaq';
console.log(ogj);
//(2)对象自变量(语法糖)
var person = {
name:'qaq',
age:20
}
console.log(person);
Object.creat(对象) 重要方法
//(3)Object.create()
//从一个实例对象生成另一个实例对象
/*vreat()中的额参数a作为返回实例对象b的原型对象
在a中定义的属性方法都能被b实例对象继承下来*/
var a ={
getX:function(){
console.log('X');
}
}
var b = Object.create(a);
//b继承了a的方法 b能调用getX
b.getX();//X
- 工厂模式
//能创建多个类似的对象
//问题:没有解决对象识别的问题
function creatPerson(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function () {
console.log(this.name)
}
return o;
}
var p1 = creatPerson('qaq', 20);
var p2 = creatPerson('yyy', 10);
p1.sayName();//qaq
console.log(p1 instanceof creatPerson);//false
console.log(p1 instanceof Object);//true
- 构造函数模式
//缺点:会浪费系统空间
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function () {
console.log(this.name);
}
}
var man = new Person('qaq', 10);
var woman = new Person('aba', 20);
console.log(man, woman);
console.log(man.sayName === woman.sayName);//false
//具有相同的sayName方法在man和woman实例中占用了不同的内存空间,
3.1构造函数拓展模式
//缺点:会污染全局空间
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = sayName;
}
function sayName(){
console.log(this.name);
}
var man = new Person('qaq', 10);
var woman = new Person('aba', 20);
console.log(man, woman);
console.log(man.sayName === woman.sayName);//true
3.2寄生构造函数模式
//缺点:定义了相同方法,浪费内存;instance和prototype属性都无意义
//结合工厂模式和构造函数模式
function Person(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
console.log(this.name);
}
return o;
}
var man = new Person('qaq', 10);
var woman = new Person('aba', 20);
console.log(man, woman);
console.log(man.sayName === woman.sayName);//false
console.log(man.__proto__ === Person.prototype);//false
console.log(man instanceof Person)//false
3.3稳妥构造函数模式
//稳妥模式:没有公共属性,并且它的方法也不引用this对象
function Person(name) {
var o = new Object();
//name属于私有属性 闭包 闭包里的属性安全性高
o.sayName = function(){
return function(){
console.log(name);
}
}
return o;
}
var p1 = Person('qaq');
p1.sayName();//'qaq'
- 原型模式
//缺点:引用类型值属性会被所有实例对象共享并且会被修改
function Person() { };
// Person.prototype.name = 'qaq';
// Person.prototype.age = 20;
// Person.prototype.sayName = function () {
// console.log(this.name);
// }
Person.prototype = {
constructor:Person,//不写的constructor话指的不是person
name:'qaq',
age:18,
sayName:function(){
console.log(this.name);
}
}
var p1 = new Person();
var p2 = new Person();
console.log(p1.sayName === p2.sayName);//true
- 组合模式
(用的最多)
function Person(name,age){
//定制自己私有属性
this.name = name;
this.age = age;
this.friedns = ['aaa', 'bbb'];
}
//定制各个实例对象的共享属性
Person.prototype = {
//改变原型对象的同时要改变该原型对象的constructor属性,让它指向当前构造函数
constructor:Person,
sayName:function(){
console.log(this.name);
}
}
var p1 = new Person('a', 10);
var p2 = new Person('b', 11);
console.log(p1);
p1.friedns.push('aa');
console.log(p1.friedns);//有aa
console.log(p2.friedns);//无aa
p1.sayName();//a
p2.sayName();//b
5.1动态原型模式
function Person(name,age){
this.name = name;
this.age = age;
this.friedns = ['aaa', 'bbb'];
if(typeof this.sayName != 'function'){
//初始化原型对象上的属性
Person.prototype.sayName = function(){
console.log((this.name));
}
}
}
console.log(Person.prototype);
var p1 = new Person('a', 10);
console.log(Person.prototype);
console.log(p1 instanceof Person);//true
小结
- 字面量方式
问题:创建多个对象会造成代码冗余 - 工厂模式
解决对象字面量法师创建对象的问题 问题:对象识别的问题 - 构造函数模式
解决工厂模式的问题
问题:方法重复被创建
3.1构造函数拓展模式
将方法放置在全局变量里解决资源浪费问题
问题:造成全局变量的污染
3.2寄生构造函数模式
特点:结合工厂模式与构造函数模式(函数中创建空对象返回对象,外部再创建新对象)
缺点:定义了相同方法,浪费内存;instance和prototype属性都无意义
3.3稳妥构造函数模式 特点:使用闭包调用私有属性,安全性高。没有公共属性,并且它的方法也不引用this对象
缺点:对象识别的问题,方法重复被创建 - 原型模式
解决构造函数模式创建对象的问题
特点:在于方法可以被共享
问题:给当前实例定制的引用类型的属性会被所有实例所共享 - 组合模式(构造函数模式和原型模式)
构造函数模式:定义实例属性
原型模式:用于定义方法和共享的属性,还支持向构造函数中传递参数。
该模式应用最广泛