javascript高级程序设计读书笔记———创建对象

2. 创建对象的几种方式

2.1 工厂模式

function createPeople(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        console.log(this.name);
    }
    return o;
}

var p1 = createPeople("landy", "20", "fe");

2.2 构造函数模式

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        console.log(this.name);
    };
}

var p1 = new Person("landy", "20", "fe");

    注意: 与工厂模式不同的地方主要有:
    
    1. 没有显示创建对象。
    2. 直接将属性和方法赋给this对象
    3. 没有return语句

 
    构造函数的缺点:方法无法复用。例如以上例子中的sayName函数。 我们可以将方法移到外部来实现复用。

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}

function sayName(){
        console.log(this.name);
 };

var p1 = new Person("landy", "20", "fe");

但是如果很多方法的话,就需要定义很多全局函数,而且这些函数只能被某个对象调用。这种情况下,已经破坏了该引用类型的封装性。

2.3 原型模式

function Person() {
}

Person.prototype.name = "landy";
Person.prototype.age = "20";
Person.prototype.job = "fe";
Person.prototype.sayName = function(){
    console.log(this.name);
};

var p1 = new Person();
var p2 = new Person();

p1.sayName();  // landy
console.log(p1.sayName == p2.sayName) // true

 
     

方法说明
isPrototypeOf()确定对象是否存在原型关系
hasOwnProperty()确定是实例拥有某一属性还是原型拥有该属性
in判断是否对象拥有某一属性。但不能准确判断出是实例属性还是原型的属性
function Person() {
}
var p = new Person();
Person.prototype.sayHi = function() {
    console.log("hi");
}
p.sayHi();  // no error


function Person() {
}
var p = new Person();
Person.prototype = {
    constructor: Person;
    sayHi: function() {
        console.log("hi");
    }
}
p.sayHi(); // error

// 第二种情况对原型进行了重写,p的原型是之前的person.prototype.而不是重写后的。所以会报错。

注意:原型模式的问题: 数据共享。

2.4 组合使用构造函数模式和原型模式
    
    集合两者之长,构造函数定义实例属性,原型定义方法和constructor属性。

function Person(name, age, job){
    this.name = name;
    this,age = age;
    this.job = job;
}
Person.prototype = {
    constructor: Person,
    sayName: function() {
        console.log(this.name);
    }
}

注意:目前使用最广泛,认同度最高的方式。

2.5 动态原型模式
 
     将所有信息封装在构造函数中,通过构造函数初始化原型

function Person(name, age, job) {
    // 属性
    this.name = name;
    this.age = age;
    this.job = job;

    if(typeof this.sayName !== "function") {
        Person.prototype.sayName = function() {
            console.log(this.name);
        }
    }
    //  在动态原型模式中,不能进行原型重写,否则会切断现有实例与新原型之间的联系
}

2.6 寄生构造函数模式

//  注意比较代码和工厂模式以及构造函数模式的区别

function Person(name, age, job) {
    var o = new Obect();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        console.log(this.name);
    }
    return o;
}

var p1 = new Person('landy', '20', 'fe');
// 构造函数在无返回值的时候,会默认返回新对象实例。可以使用return重写构造函数返回的值。

注意:该种情况下,p1和构造函数Person以及Person的原型属性没有任何关系。所以不能使用instanceof来确定对象类型。

2.7 稳妥构造函数模式
 
    稳妥对象是指没有公共属性,而且方法也不引用this对象。适合在安全环境中引用(这些环境会禁止使用 this 和 new)

funtion Person(name, age, job) {
    var o = new Object();
    // 在这里定义私有变量,eg  name = name;
    // 有点类似C++类中的 private name = ?;

    o.sayName = function(){
        console.log(name);
    }

    return o;
}

// 以上处理通过sayName,没有其他办法访问内部成员。稳妥构造函数提供了较高的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值