资讯专栏INFORMATION COLUMN

JavaScript面向对象 - 创建对象(上)

sourcenode / 3089人阅读

摘要:对象字面量创建对象张三学生这种方式的好处显而易见,就是解决了之前的缺点。构造函数模式张三学生李四学生与之前工厂模式的方法对比变量名首字母大写了在函数内没有显式的创建及返回对象而使用了创建时使用了关键字。

面向对象是JS的重点与难点,但也是走向“掌握JS”的必经之路,有很多的文章或书籍中都对其进行了详细的描述,本没有必要再写这些,但是对于学习来说,讲给别人听对自己来说是一种更好的受益方式。我想通过简洁的语言来描述创建对象的方法以及这种方法的优缺点。

本系列内容:

基本创建模式

对象字面量创建对象

工厂模式

构造函数模式

更新时间

2015年12月6日:创建

2017年7月8日:精简内容,修正错误

一、创建对象

创建对象的方法有许多,各有利弊。知其然,做到会用;知其所以然,做到为什么用这种方法。才能是真正的掌握。

1.1 基本创建模式
var person = new Object();
person.name = "张三";
person.job = "学生";
person.viewName = function(){
    console.log(this.name);
}

这是一种最基础的创建对象的方法,使用新建Object的方法创建对象,并且为其添加属性和方法。

但这种方式有个不好的地方是重复使用了多个person变量,而且没有任何的封装性可言,于是就出现了更受开发人员喜爱的对象字面量形式。

1.2 对象字面量创建对象
var person = {
    name: "张三",
    job: "学生",
    viewName: function(){
        console.log(this.name);
    }
}

这种方式的好处显而易见,就是解决了之前的缺点。

但在实际需求中,需要创建一批类似的对象就有些力不从心了。比如一个小组有六个成员,我要基于每个组员进行对象实例化,那么我要写6遍以上的代码,并且为其命名为person1~person6。如果可以像流水线一般创建对象就好了:给其提供原料(名字和职务),让其自动创建出组员,使用函数恰好能做到。

1.3 工厂模式
var person = function(name, job){
    var o = new Object();
    o.name = name;
    o.job = job;
    o.viewName = function(){
        console.log(this.name);
    }
    return o;
};
var person1 = person("张三","学生");
var person2 = person("李四","学生");

工厂模式利用"创建对象函数"形成流水线的模式,使其流程化,将创建的过程都封装到函数中,对外只暴露每个对象的特性(通过参数的形式传入)。

具体的实现流程是:在函数内创建了一个对象,将传入的参数作为对象的属性,在最后将其返回。调用函数,函数就会返回拥有特定属性的对象。

工厂模式流程化了创建对象的方法,使其创建对象变得非常简便,但其中出了一个问题,既然person1和person2都使用person函数创建,那么,有什么方法可以证明person1和person2"师出同门"呢?或者用JS的话说是怎样解决对象识别问题,答案是工厂模式不能证明。于是又出现了构造函数模式,用此模式可以确定person1和person2的关系。

1.4 构造函数模式
var Person = function(name, job){
    this.name = name;
    this.job = job;
    this.viewName = function(){
        console.log(this.name);
    }
}
var person1 = new Person("张三","学生");
var person2 = new Person("李四","学生");

与之前工厂模式的方法对比:

Person变量名首字母大写了

在函数内没有显式的创建及返回对象而使用了this

创建时使用了new关键字。

Person变量首字母大写是为了区别普通函数,除此之外,别无它用。既然Person的首字母大写只是为了让自己一眼辨别出他是构造函数,在功能上是相同的。那么写成person当然可以,只是这样不推荐(无法区分普通函数与构造函数)。

使用new操作符必须经历四个步骤

创建一个新的对象

将构造函数的作用域赋值给新对象

执行构造函数的代码:为其添加属性和方法

返回新的对象

使用new操作符创建的对象都有一个constructor属性,该属性指向构造函数。

person1.constructor == Person; // true
person1.constructor === person2.constructor;// true
console.log(person1.constructor);// 返回构造函数
//function (name, job){
//    this.name = name;
//    this.job = job;
//    this.viewName = function(){
//        console.log(this.name);
//    }
//}

在测试的时候发现一个问题:不使用new关键字创建Object对象为什么constructor有值?

共享方法

再回到原来的需求,小组有两个人,我要创建两个对象,对象的名字和职位可能不一样,但是打印每个人的名字这个方法是一样的。

对于以上几种模式创建的对象。

person1.viewName === person2.viewName;// false

我每次创建一个对象,都创建一次viewName,但是每次都不相等(person1.viewName == person2.viewName返回false)。且如果有一天我们想把viewName方法改成return返回name值,我要每个对象都改吗?我们只要把这个方法做成对象公用的就好了,我们可以这样:

var Person = function(name, job){
    this.name = name;
    this.job = job;
    this.viewName = viewName;
}
function viewName(){
    console.log(this.name);
}
var person1 = new Person("张三","学生");
var person2 = new Person("李四","学生");

但是这又出现了一个问题,没有封装性可言啊,viewName明明是Person的私有方法,但是放在外面,变成了谁都可以调用,原型函数模式解决了这个问题。

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

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

相关文章

  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论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
  • 面向对象JavaScript

    摘要:是完全的面向对象语言,它们通过类的形式组织函数和变量,使之不能脱离对象存在。而在基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的。 JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或者只是部分具备一些面向对象的特征。本文将回归面向对象本意,从对语言感悟的角度阐述为什...

    novo 评论0 收藏0
  • 重新认识JavaScript面向对象: 从ES5到ES6

    摘要:基于原型的面向对象在基于原型的语言中如并不存在这种区别它只有对象不论是构造函数,实例,原型本身都是对象。允许动态地向单个的对象或者整个对象集中添加或移除属性。为了解决以上两个问题,提供了构造函数创建对象的方式。 showImg(https://segmentfault.com/img/remote/1460000013229218); 一. 重新认识面向对象 1. JavaScript...

    VishKozus 评论0 收藏0

发表评论

0条评论

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