资讯专栏INFORMATION COLUMN

JS中创建对象的几种设计模式

Galence / 2807人阅读

摘要:构造函数模式定义构造函数模式是语言创建对象的通用方式。但两种语言用构造函数创建对象的方式略有不同在中没有类的概念,函数即为一等公民,因此,不必显式声明某个类,直接创建构造函数即可,类的方法和属性在构造函数中或原型对象上处理。

工厂模式

定义:工厂模式非常直观,将创建对象的过程抽象为一个函数,用函数封装以特定接口创建对象的细节。通俗地讲,工厂模式就是将创建对象的语句放在一个函数里,通过传入参数来创建特定对象,最后返回创建的对象。

缺陷:工厂模式虽然可以创建多个相似的对象,但却不能解决对象标识的问题,即怎样知道一个对象的类型(如下,我只知道s1是Object--万物皆对象,但我并不知道s1到底是Student类型还是Person类型?就好像是一个孤儿一样,只能知道他是个人,但不知道他是哪家人。。。)

function createStudent(name,sex,grade){                                                         
    var o = new Object();
    o.name = name;
    o.sex = sex;
    o.grade = grade;

    o.sayName = function(){
        console.log(this.name);
    }
    return o;
}
var s1 = createStudent("Claiyre","famale",1);
构造函数模式

定义:构造函数模式是java语言创建对象的通用方式。(但两种语言用构造函数创建对象的方式略有不同)

在JavaScript中没有类的概念,函数即为一等公民,因此,不必显式声明某个类,直接创建构造函数即可,类的方法和属性在构造函数中(或原型对象上)处理。

function Student(name,sex,grade){                                                   
    this.name = name;
    this.sex = sex;
    this.grade = grade;
    this.sayName = function(){
        console.log(this.name);
    }
}
var s2 = new Student("孙悟空","male",2);

注意:构造函数的函数名首字母是大写的,而普通函数首字母则是小写,这是众多OO语言约定俗成的规定,虽然大多数情况下不大写也不会报错,但是为了代码的规范性和可读性,还是应该将构造函数的首字母大写,与普通函数区别开。

优势:与工厂模式相比,用构造模式创建对象有以下几点不同:

没有显示地创建对象

直接将属性和方法赋给this对象

没有return语句

缺陷:每个方法都要在每个实例上创建一遍:在ECMAScript中,函数即对象,因此每定义一个函数,也就是实例化了一个对象。通过构造函数实例化的多个对象的方法,是多个不同的方法,但它们内部的代码以及实现的功能是相同的,这就造成了一定的资源浪费。

原型模式

定义:js中,每个函数都有一个prototype属性,它指向一个对象,叫做原型对象,原型对象包含了可以由特定类型的所有实例对象共享的属性和方法。此外,这个对象有一个与生自来的属性constructor,指向创建对象的构造方法。使用原型模式可以让所有的实例共享原型对象中的属性和方法,也就是说,不必再构造函数中定义对象实例的信息。

function Student_1(){

}
Student_1.prototype.name = "Claiyre";
Student_1.prototype.sex = "female";
Student_1.prototype.class = 5;
Student_1.prototype.sayName = function (){
    console.log(this.name);
}

var s5 = new Student_1();                                                         
s5.sayName();    //Claiyre
var s6 = new Student_1();
s6.sayName();    //Claiyre

引申知识点:

Object.getPrototypeOf(object)方法返回参数对象的原型对象。

Object.keys(object)方法返回对象上枚举的实例属性。

缺陷:原型中的所有属性都是被所有实例所共享的,这种共享对于函数来说非常合适,对于包含基本值的属性也说的过去(实例属性会覆盖原型同名属性),但对于那些包含引用类型的属性,可有大麻烦了:

Student_1.prototype.friends = ["aa","bb"];

console.log("s6的朋友" + s6.friends); // s6的朋友aa,bb
s5.friends.push("cc");
console.log("s5的朋友" + s5.friends); // s5的朋友aa,bb,cc
console.log("s6的朋友" + s6.friends); // s6的朋友aa,bb,cc
// 我们只想改变s5的朋友列表,但由于原型模式的共享本质,s6的朋友列表也随之改变了
组合使用构造函数和原型模式

定义:构造函数模式用于定义实例属性,原型模式则用于定义方法和共享的属性。这种混合模式不仅支持向构造函数传入参数,还最大限度地节约了内存,可谓是集两模式之长。

 function Student(name,sex,grade){                                                   
    this.name = name;
    this.sex = sex;
    this.grade = grade;
}

Student.prototype.sayName = function(){
        console.log(this.name);
}
Student.prototype.school = "Joooh school";
其他模式

除了以上几种常见的模式外,批量创建对象的方式还有

动态原型模式:仅在第一次调用构造函数时,将方法赋给原型对象的相应属性,其他示例的处理方式同构造函数模式

寄生构造函数模式:仅仅封装创建对象的代码,然后再返回新创建的对象,仍使用new操作符调用

稳妥构造函数模式:没有公共属性,只有私有变量和方法,以及一些get/set方法,用以处理私有变量

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

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

相关文章

  • Js中创对象几种方式

    摘要:对象字面量的方式今年创建实例的发明者我是今年属性是可以动态添加,修改的构造函数无参构造函数有参构造函数我叫,今年岁实例化创建对象调用方法由于指针在对象实例的时候发生改变指向新的实例。是我的名字混合方式构造函数原型我是,今年 javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON;方法很多,也能混合使用。 对象字面量的方式: var pers...

    willin 评论0 收藏0
  • JS中创函数几种方式

    使用 函数声明 创建函数 语法: * function 函数名([形参1,形参2...形参N]){ * 语句... * } */ function fun2(){ console.log(这是我的第二个函数~~...

    Joyven 评论0 收藏0
  • js对象几种方式

    摘要:可以无数次地调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象构造函数模式原型模式组合使用构造函数模式和原型模式创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。 JS中创建对象的主要模式有 工厂模式 工厂模式抽象了具体创建对象的过程例如 function createPerson(name, age, job){     var o = new Object(...

    seanlook 评论0 收藏0
  • 文件上传几种方法——webuploader篇

    摘要:本来想把这几种方法放在同一篇写的,写完,已经很长了,想想还是分开的比较好。是由团队开发的一个简单的以为主为辅的现代文件上传组件。因为是,就拿着的来用一下选择文件的按钮。也可以重写上传事件。如果不自动上传的话,可以通过触发。 本来想把这几种方法放在同一篇写的,写完xhr,已经很长了,想想还是分开的比较好。webuploader是由Baidu WebFE(FEX)团队开发的一个简单的以HT...

    Amos 评论0 收藏0
  • 判断是否是数组几种方法— (js基础复习第1期)

    摘要:如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。 1. 首先,typeof肯定是不行的 对于一些基本类型,typeof是可以判断出数据类型,但是判断一些引用类型时候,不能具体到具体哪一种类型 再来复习一下typeof的...

    supernavy 评论0 收藏0

发表评论

0条评论

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