第6章:面向对象的程序设计--创建对象

一.Javascript中的对象

    JavaScript 中的对象分为三类,一类是实例对象,一类是构造函数对象,一类是原型对象。
例如:

function Foo(){}
Foo.prototype.name = 'Bar';
var foo = new Foo();
    在这个例子中,包含了JavaScript的三类对象,对应的如图所示:

    三种对象的关系:

二.创建对象
    1.构造函数模式

    (1)为什么要使用构造函数
    传统的方式:

var foo = {};
    foo.prop1 = 'bar';
    foo.prop2 = false;
    foo.prop3 = function(){
    return 'hello';
}
传统方式创建对象的方法有一个弱点,就是创建对象的代码是一次性的,如果要创建多个对象,则会产生大量的重复代码。

     
    (2)构造函数
function User(name, url){
    this.name = name;
    this.url=url;
    this.display = function(){
        console.log(this.name);
    }
}
    以上是一个简单的构造函数,然后用new语句来创建对象
var user = new User('Tank', 'http://www.99.com/');
    注:构造函数始终以一个大写字母开头,非构造函数以小写字母开头。


    构造函数的优势是没有显式的创建对象,直接将属性和方法赋给了this对象(实例对象),对象的创建可以公用一个构造,并且能够传递对象的各自参数。但是也有问题,就是每个对象的方法都要在每个实例上重新创建一次。例如:

var user1 = new User('Mark', 'http://www.99.com/');
var user2 = new User('James', 'http://www.99.com/');
    以上代码创建了两个User对象,也同时创建了2个display方法。

2.原型模式
    (1)原型模式书写方法
function Person(){}
Person.prototype.name = 'BYVoid';
Person.prototype.showName = function(){
    console.log(this.name);
}
var person = new Person();
person.showName();

原型模式跟构造函数最重要的却别是,构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。而使用原型对象的好处是可以让多有对象实例共享原型所包含的属性和方法。例如:

var person1 = new Person();
person1.showName();  //BYVoid
var person2 = new Person();
person2.showName();  //BYVoid

person1和person2对象共享了Person原型对象的name属性和showName()方法。

原型模式也可以运用字面量来书写,例如:
function Person();
Person.prototype ={
    name: 'BYVoid',
    showName: function(){
        console.log(this.name);
    }
}
    用字面量创建原型模式与默认方式有一个重大的区别。按照字面量的形式书写,等于把Person.prototype重写了,导致constructor属性不再指向Person。弥补的方法是把constructor属性现式的指向Person,例如:
function Person();
Person.prototype ={
    constructor:Person,
    name: 'BYVoid',
    showName: function(){
        console.log(this.name);
    }
}

    原型模式也是有问题的,最大的问题是由其共享的本质所导致的。例如:

function Person(){}
Person.prototype ={
    constructor:Person,
    name: 'BYVoid',
    friends: ['Shelby', 'Court'],
    showName: function(){
        console.log(this.name);
    }
}

var person1 = new Person();
var person2 = new Person();

person1.friends.push('Van');
console.log(person1.friends);  //Shelby,Court,Van
console.log(person2.friends);  //Shelby,Court,Van
只想修改person1对象中的friends属性,但是因为原型模式的共享本质,导致person2对象中的frieds也被修改了。

3.组合使用构造函数和原型模式
    构造函数的优势是可以让实例都有各自的属性,原型模式的优势是可以共享原型对象的方法。结合这两个的方式就可以比较好的定义对象了。例如:
function Person(name,age){
    this.name = name;
    this.age = age;
    this.friends = ['Van','Cat'];
}

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

var person1 = new Person('Shelby', 29);
var person2 = new Person('Court',25);
person1.friends.push('Tank');
console.log(person1.friends);  //Van,Cat,Tank
console.log(person2.friends);  //Van,Cat







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值