JavaScript高级程序设计-学习笔记4(创建对象)

1.工厂模式
用函数来封装以特定接口创建对象的细节

function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");

2.构造函数模式

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("Nicholas", 29, "Software Engineer");

式调用构造函数会经历以下4个步骤:
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。

对比工厂模式可以知道类型:

alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true

调用方法:

// 当作构造函数使用(new)
var person = new Person("Nicholas", 29, "Software Engineer");
person.sayName(); //"Nicholas"
// 作为普通函数调用(没有new)
Person("Greg", 27, "Doctor"); // 添加到window
window.sayName(); //"Greg"
// 在另一个对象的作用域中调用
//使用call()(或者apply())在某个特殊对象的作用域中
调用Person()函数
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse");
o.sayName(); //"Kristen"

3.原型模式

每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。
这里写图片描述
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象,与构造函数没有直接的关系。只有一个原型,空构造器。

var person1 = new Person();
var person2 = new Person();
alert(person1.name); //"Nicholas"——来自原型
alert(person1.hasOwnProperty("name")); //false 检查name来自实例还是原型
alert("name" in person1); //true无论该属性存在于实例中还是原型中,只要能够访问name
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person1.hasOwnProperty("name")); //true

当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性。

var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"

原型模式缺点:
(1) 省略了为构造函数传递初始化参数这一环节,结果所有实例在
默认情况下都将取得相同的属性值;
(2) 对于包含引用类型值的属性来说,问题比较突出。

function Person(){
}
Person.prototype = {
    …
    friends : ["Shelby", "Court"],
    …
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true

4.组合使用构造函数模式和原型模式
为了解决原型模式在引用类型上的问题。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}
Person.prototype = {
    constructor : Person,
    sayName : function(){
        alert(this.name);
    }
}

5.动态原型

跟4差不多都是混合,但是进行了封装。

function Person(name, age, job){
    //属性
    this.name = name;
    this.age = age;
    this.job = job;
    //方法:当不存在时才创建,这样就只会创建一次了
    if (typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            alert(this.name);
        };
    }
}

6.寄生构造函数模式(最好不要用)
除了使用new 操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。

function Person(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");

7.稳妥构造函数模式(适合在一些安全的环境中)

function Person(name, age, job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里定义私有变量和函数
    //添加方法
    o.sayName = function(){
        alert(name);
    };
    //返回对象
    return o;
}
var friend = Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas",除了使用sayName()方法之外,没有其他办法访问name 的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值