资讯专栏INFORMATION COLUMN

面向对象的程序设计之创建对象

acrazing / 689人阅读

摘要:对象的定义无序属性的集合属性的值可以是基本值对象或者函数每个对象都是基于一个应用类型创建的这个引用类型可以是内置的例如也可以是用户自定义的基于创建对象所有的对象都是继承自的因此我们可以从着手创建对象通过关键字创建对象通过对象字面量创建对象基

对象的定义:无序属性的集合,属性的值可以是基本值、对象或者函数.
每个对象都是基于一个应用类型创建的,这个引用类型可以是内置的(例如Object Array Math),也可以是用户自定义的.

基于Object创建对象

所有的对象都是继承自Object的,因此我们可以从Object着手创建对象.

//通过new 关键字创建对象
var person = new Ojbect();
person.name = "yuhualinfeng";
person.age = 30;
person.job = "web developer";

//通过对象字面量创建对象
var person = {};
person.name = "yuhualinfeng";
person.age = 30;
person.job = "web developer";

基于Object创建对象有两种形式,一种是使用new关键字,另一种是使用对象字面量.
使用这种方式创建对象的缺点是:当创建多个相同类型的对象时,会产生许多重复的代码,假如我要三个person对象,我就需要写三相同结构的代码,为了解决这个问题,我们引入了工厂模式创建对象.

使用工厂模式创建对象

工厂模式是软件工厂领域一种广为认知的设计模式,这种模式抽象了创建具体对象的过程.

function createPerson(name,age,job){

var obj = new Object();
obj.name = name;
obj.age = age;
obj.job = job;

return obj;

}

var person1 = createPerson("yuhualingfeng",30,"web developer");
var person2 = createPerson("obama",45,"president");

我们创建了两个人物对象,假如我们基于Object创建对象,那么createPerson内的代码就会重复编码.
但是使用这种模式创建的对象任然有一个问题:无法得知创建的对象的类型名.解决这问题的可行方法是使用构造函数创建对象.

使用构造函数模式创建对象
function Person(name,age,job){

    this.name = name;
    this.age = age;
    this.job = job;

    this.sayName = function(){
        alert(this.name);
    }

}

var person1 = new Person("yuhualingfeng",30,"web developer");
var person2 = new Person("obama","45","president");

这里我们创建了一个名为Person的引用类型,然后我们用new 关键字实例化此引用类型,这个过程可以细化为以下四个过程:

创建一个新对象

将构造函数的作用域赋值给新函数(因此this就指向这个新对象)

执行构造函数中的代码(为this对象赋值,等同于为新对象赋值)

返回新对象

我们可以用instanceof来检测person1,person2的对象类型是否为Person.

 
 alert(person1 instanceof Person); //true
 alert(person2 instanceof Person); //true
 alert(person1 instanceof Object); //true 因为Person继承自Object,所以这里一样成立.
  

注:细心的朋友应该会注意到,这里的构造函数的首字母是大写,这里们遵循一个规范,普通函数的首字母大写,普通函数的首字母小写.

构造函数也有自己的缺点,大家可以看到Person包含一个sayName的函数(方法),函数也是对象(函数式Function的实例),所以每实例化一个Person,就会产生一个sayName方法,也就是一个对象,
随着创建的person实例怎多,产生的对象也相应增多,最终导致更多的内存,那么我们能不能找到更好的解决办法呢,答案是肯定的.

使用原型模式创建对象

我们每创建一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象而这个特定对象的用途是包含可以由特定类型的所有实例共享的属性和方法.这就意味着原型对象不会因为实例的增多二占用
更多的内存.每个原型对象都默认有一个constructor属性,故名思议,这个属性指向构造函数.下面展示了通过原型对象来创建对象.

function Person(){
}
Person.prototype.name = "yuhualingfeng";

Person.prototype.age = 30;

Person.prototype.job = "web developer";

Person.prototype.sayName=function(){
alert(this.name);
};

var person1 = new Person();
person.sayName();  //yuhualingfeng
var person2 = new Person();

这里Person.prototype.constructor指向的是Person.当然你也可以向下面这样直接给原型对象赋值来创建对象.

Person.prototype={
constructor:Person,
name:"yuhualingfeng",
age:30,
job:"web developer"
};

这里之所以添加了constructor属性是应为直接给原型对象赋值会把原型对象的指针指向另一个对象,以前默认的值将无法访问到.

顺便给大家介绍两个与原型对象相关的方法和in关键字:

isPrototypeOf:判断是某对象否为实例的原型.

alert(Person.prototype.isPrototypeOf(person));  //true

hasOwnProperty:检测某属性是存在于实例中,还是原型对象中.

alert(person1.hasOwnProperty("name"));  //false,因为属性存在于原型中.

in操作符:in操作符有两种使用方式,一种是多带带使用,一种是和for搭配使用,多带带使用的作用是判断某属性是否在某实例中访问到(无论是在实例自身的还是原型对象中的),for-in是枚举(循环)中使用.

//判断属性是否存在原型中
function hasPrototypeProperty(object,name){

    return object.hasOwnProperty(name) && (name in object);

}

原型模式创建对象的缺点:实例的原型对象是共享的,当修改一个实例的属性,如果属性的值为方法或者基本类型时,不会有什么影响,当属性为引用类型时,会影响其他实例的属性值.
综合构造函数模式和原型模式创建对象,我们结合他们的优点,去粗取精,我们组合使用构造函数模式原型模式.

组合使用构造函数模式原型模式

通过构造函数创建对象的缺点是每个方法都会在实例上重新创建,造成不必要的内存消耗;通过原型创建对象的缺点在于实例引用类型值的属性会相互影响.综上考虑,我们可以把存储值得属性放在构造函数中,把方法放在原型对象中.这种模式是创建对象使用最广泛的一种,可以说是创建对象的默认模式.

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

Person.prototype = {
 constuctor:Person,
 sayName:function(){
     alert(this.name);
 }
};

var person = new Person("yuhualingfeng",30,"web developer");
person.sayName();  

以上就是创建对象的几种模式,大家可以结合它们的优缺点和你自身创建对象的用处进行权衡,然后选择适合你的创建对象的模式.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86014.html

相关文章

  • javascript 面向对象版块理解对象

    摘要:用代码可以这样描述安全到达国外面向过程既然说了面向对象,那么与之对应的就是面向过程。小结在这篇文章中,介绍了什么是面向对象和面向过程,以及中对象的含义。 这是 javascript 面向对象版块的第一篇文章,主要讲解对面向对象思想的一个理解。先说说什么是对象,其实这个还真的不好说。我们可以把自己当成一个对象,或者过年的时候相亲,找对象,那么你未来的老婆也是一个对象。我们就要一些属性,比...

    lovXin 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    Lyux 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    AaronYuan 评论0 收藏0
  • JS面向对象四 【new】 (创建特定对象语法糖)

    摘要:面向对象之四创建特定对象的语法糖个人学习笔记分享为了讲清楚面向对象实际上是需要几个前置知识的。于是之父创造了这个语法糖。 JS面向对象之四 【new】 (创建特定对象的语法糖) 个人学习笔记分享 为了讲清楚面向对象,实际上是需要几个前置知识的。包括前面的几篇文章【原型链】 【this】 和今天要说的【new】 还是先说结论: new只是一个语法糖,这个语法糖被设计出来,使用场景是批量创...

    lauren_liuling 评论0 收藏0
  • 面向对象程序设计原型模式

    摘要:可以用删除实例对象中自己添加的属性可以确定属性是原型中还是实例对象中,当时实例对象中时,返回的是操作符,有两种使用方式,单独使用和循环中。单独使用,通过对象能够访问属性时返回,无论时在原型中还是实例对象中。 原型模式,每个创建的对象都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。 ------------...

    yunhao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<