javascript笔记3:创建对象

创建对象

1.工厂模式 用函数来封装以特定接口创建对象的细节.
function createPerson(name,age,job) {
    let  o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayName=function () {
        console.log(this.name);
    };
    return o;

}

let person1=createPerson('Nicholas',29,'Software Enginner');
let person2=createPerson('Greg',27,'Doctor');
person1.sayName();
person2.sayName();

缺点 没有解决对象识别的问题(即怎么知道一个对象的类型);

2构造函数模式
function Person(name,age,job) {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=function () {
        console.log(this.name);
    }// new Function('console.log(this.name)');
}
let p1=new Person('Nicholas',29,'Software Enginner');
p1.sayName();
let p2=new Person('Greg',27,'Doctor');
p2.sayName();
console.log(typeof p1,p1 instanceof Person,p1 instanceof Object);//ojbct true true
console.log(p1.constructor===Person,p2.constructor===Person);
console.log('name:',p1.sayName===p2.sayName,typeof Person.prototype);//false; object

//当构造函数使用
let person=new Person('fubao',30,'Software Enginner');
person.sayName();
//
//Person('Greg',27,'Doctor');
//window.sayName();
//在另一个对象的作用域中调用
let o=new Object();
Person.call(o,'Kristen',25,'Nurse');
o.sayName();

缺点:每个方法都要在每个实例上重新创建一遍.

3:原型模式

创建的每个函数都一个prototype(原型)属性,它是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的具有实例共享的属性和方法.
优点:可以让所有对象的实例共享它所包含的属性和方法.

function PersonPT() {
    
}
PersonPT.prototype.name='Nicholas';
PersonPT.prototype.age=29;
PersonPT.prototype.job='Software Engineer';
PersonPT.prototype.sayName=function () {
    console.log(this.name);
};
let pson1=new PersonPT();
pson1.sayName();
let pson2=new PersonPT();
pson2.sayName();
console.log('__proto__是原型对象',pson2.__proto__===PersonPT.prototype);//构造函数的原型对象

console.log('sayName',pson1.sayName===pson2.sayName);//true
console.log(PersonPT.prototype.constructor===PersonPT);
console.log(typeof PersonPT.prototype,PersonPT.prototype instanceof Object);
//通过isPrototypeOf方法来确定实例的原型是否一样.
console.log(PersonPT.prototype.isPrototypeOf(pson1));
console.log(PersonPT.prototype.isPrototypeOf(pson2));
//获得[[Prototype]]
console.log(Object.getPrototypeOf(pson1)===PersonPT.prototype);
console.log(Object.getPrototypeOf(pson1).name);
pson1.name='greg';
console.log(pson1.name,pson2.name);
//delete  pson1.name;
//console.log(pson1.name);
//hasOwnProperty()方法可以检测一个属性是存在实例中,还是存在原型中.
console.log(person1.hasOwnProperty('name'));//true;
delete  person1.name;
console.log(person1.hasOwnProperty('name'));//false;
//确定属性来自原型而不是对象中
function hasPrototypeProperty(object, name) {
    return !object.hasOwnProperty(name)&&(name in object);
}
//要取得对象上所有可枚举的实例属性,可使用Object.keys()方法
for(let prop in pson1){
    console.log(prop);
}
var keys=Object.keys(PersonPT.prototype);//所有可枚举的实例属性
console.log(keys);
console.log(Object.keys(pson1));
console.log(Object.getOwnPropertyNames(PersonPT.prototype));//所有实例属性,是否可枚举
//3,更简单的原型语法
function PersonSimple() {

}

PersonSimple.prototype={
    //constructor:PersonSimple,
    name:'Nicholas',
    age:29,
    job:'Software Engineer',
    sayName:function () {
        console.log(this.name);
    }

};//constructor属性不再指向PersonSimple
let friend=new PersonSimple();
console.log(friend instanceof Object);//true;
console.log(friend instanceof PersonSimple);//true
console.log(friend.constructor===PersonSimple);//false;
console.log(friend.constructor===Object);//true;
//原型的动态性
let personSimple=new PersonSimple();
PersonSimple.prototype.sayHI=()=>{
    console.log('hi');
};
personSimple.sayHI();//hi

原型模式的缺点:a.省略了构造函数传递初始化参数.b.共享引用类型会引起问题.

4.组合使用构造函数模式与原型模式. (推荐使用)

构造函数定义实例属性,原型模式用于定义方法与共享的属性.
优点:实例都一份自己实例属性副本.同时共享对方法的引用.节省内存.

function PersonMix(name,age,job){
    this.name=name;
    this.age=age;
    this.job=job;
    this.friends=['Shelby','Court'];
}
PersonMix.prototype={
    constructor:PersonMix,
    sayName:function () {
        console.log(this.name);
    }
};

let pm1=new PersonMix('Nicholas',29,'Software Engineer');
let pm2=new PersonMix('Greg',27,'Doctor');
pm1.friends.push('Van');
console.log(pm1.friends);
console.log(pm2.friends);
console.log(pm1.sayName===pm2.sayName);
5.动态原型模式.
function PersonDynamic(name,age,job){
    this.name=name;
    this.age=age;
    this.job=job;
    if(typeof this.sayName!='function'){//动态体现
        PersonDynamic.prototype.sayName=function () {
            console.log(this.name);
        }
    }
}
6.寄生构造函数模式
function PersonCon(name,age,job) {
    let o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayName=function (){console.log(this.name);};
    return o;
}
let f=new PersonCon('fb',30,'SE');
f.sayName();
console.log(f.constructor===PersonCon);
console.log(f.constructor===PersonCon.prototype);

缺点:返回对象与构造函数或者与构造函数的原型属性之间没有关系.

7.稳妥构造函数模式

稳妥对象 指的是没有公共属性,而且其方法也不引用this的对象.

function PersonWT(name,age,job) {
    let o=new Object();
    o.sayName=function () {
        console.log(name);
    };
    return o;
}

let wt=PersonWT('fb',30,'SE');
wt.sayName();

你可能感兴趣的:(javascript笔记3:创建对象)