JavaScript创建对象的9种方式

2023-10-27

JavaScript创建对象的九种方式

Object构造函数创建对象

不再赘述

对象字面量

不再赘述

工厂模式

用函数来封装以特定接口创建对象的细节

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 person = createPerson("Tom", 25, "Software Engineer");

缺点: 都是Object实例,无法区分所创建对象的类型。

构造函数模式

自定义构造函数,创建特定类型的对象,同一个构造函数创建出来的对象属于一类

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

}

var person = new Person("Tom", 25, "Software Engineer");

缺点: 对于一些可以共享且相同的函数方法,却要多次创建在实例化对象中,占用内存,且复用性差。

原型模式

让所有的对象实例共享原型对象所包含的属性和方法,不必在构造函数中定义然后多次在实例对象中创建了,只需要添加给原型即可

function Person() {
}

Person.prototype.name = "Tom";
Person.prototype.age = 25;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
    alert(this.name);
};

// 当然也可以通过用对象字面量来重写整个原型对象,比上面的更简洁,但不要忘了constructor变化
// Person.prototype = {};

var person1 = new Person();

// 可以指定实例属性,屏蔽来自原型的属性值
person1.name = "Jerry";

缺点: 省略了传递给构造函数初始化参数这一环节,导致所有的实例默认都具有相同的属性值。更大的问题是对于原型上的引用类型属性,所有的实例之间会共享修改,丧失了独特性。

混合构造函数原型模式

最常见的创建自定义类型方式,构造函数中定义实例属性,原型对象中添加共享属性和方法

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);
    }
}

var person1 = new Person("Tom", 25, "Software Engineer");
var person2 = new Person("Jerry", 24, "Software Engineer");

person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"

alert(person1.sayName === person2.sayName); //true

优点: 支持向构造函数传递参数,每个实例都有自己的一份实例属性的副本,每个实例共享对方法的引用,最大限度节省内存。

动态原型模式

将构造函数和原型对象等定义统一到一个函数中,封装性更强,并且通过检测必要情况来决定是否初始化原型,效率更高

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);
        };
    }
} 

var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); 

评价: 原型方法的添加只执行一次,对原型所做的修改也能立即在实例中反映,可以说相当完美,但是需要注意不能使用对象字面量重写原型,否则会切断现有实例与新原型的联系。

寄生构造函数模式

当有特殊需求比如说创建一个具有额外方法的数组,由于不能直接修改Array,就可以使用这个模式

function SpecialArray(){

    //创建数组
    var values = new Array();

    //添加值
    values.push.apply(values, arguments);

    //添加方法
    values.toPipedString = function(){
        return this.join("|");
    };

    //返回数组
    return values;
}

var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green" 
  • 除了使用了new操作符,并且把使用的包装函数叫做构造函数外,其余和工厂模式一模一样。

  • 注意: 返回的对象与构造函数和原型没有关系,与在构造函数外部创建的对象没有什么不同,因此不能使用instanceof操作符来确定对象类型。

  • 建议在可以使用其他模式的情况下,不要使用这种模式。

稳妥构造函数模式

用来创建没有公共属性,不引用this的安全稳妥对象

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的值。

  • 与寄生构造函数模式类似,使用稳妥构造函数模式创建的对象与构造函数之间没有什么关系,因此instanceof操作符也没有意义。

详细解读请见笔记 : JavaScript高级程序设计: 创建对象

转载于:https://www.cnblogs.com/longyincug/p/8702079.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript创建对象的9种方式 的相关文章

  • 【问题解决】Centos7 yum命令异常报错Could not retrieve mirrorlist http://mirrorlist.centos.org

    问题出现 在把虚拟机的ip改为静态ip之后 yum install就会出现这样子的问题 root etcd yum install y wget 已加载插件 fastestmirror Determining fastest mirrors
  • 01rapidJson学习之rapidJson的初始化

    01rapidJson学习之rapidJson的初始化 1 rapidJson的初始化 由于我们经常通过初始化添加值到string字符串中 所以这里封装成一个简单函数 rapidJson有3种初始化方式 1 改造初始化 2 set方法初始化
  • unity安卓so包与其他第三方so包冲突问题 Unable to find main / No implementation found for

    最近公司项目需要 在安卓端使用了视频直播的第三方包和unity的第三方包 问题来了 引用了视频直播的包之后 unity的嵌入程序启动会报错 Process e unitry3d PID 30302 java lang Unsatisfied
  • Linux用户与群组管理

    用户账户与群组概念 Linux操作系统是多用户多任务的操作系统 系统依据账户来区分属于每个用户的文件 进程 任务 并给每个用户提供特定的工作环境 例如 用户的工作目录 shell版本以及图形化的环境配置等 Linux系统下的用户分为三种 1
  • Centos7 离线安装kafka

    Centos7 离线安装kafka 1 准备 1 提前下载kafka与jdk rpm包 2 开始 1 将rpm包导入到服务器 2 执行 rpm ivh kafka 1 1 1 20200608 x86 64 rpm 下载 https dow
  • 华为OD机试-喊7游戏

    题目描述 喊7 是一个传统的聚会游戏 N个人围成一圈 按顺时针从1 7编号 编号为1的人从1开始喊数 下一个人喊得数字是上一个人喊得数字 1 但是当将要喊出数字7的倍数或者含有7的话 不能喊出 而是要喊过 假定N个人都没有失误 当喊道数字k
  • IDEA 编译时 报 “常量字符串过长” 解决办法

    在编译项目时 出现错误为 常量字符串过长 java constant string too long 解决 File gt gt Settings gt gt Build Execution Deployment gt gt Compile
  • @font-face 加载字体引用字体之后不起作用

    如题 最近在学习css的时候遇到如下情况 使用 font face加载多种字体不起作用 反思 是我搞错了 字体加载可能就是要一条一条的写 文件结构目录 代码如下
  • Android 报错:Call requires API level 26/设置SDK最小的版本

    报错如下图所示 我尝试了升级Android Studio 到新版本 报错仍然存在 原因是某些控件仅仅支持一些较高SDK的版本 所以修改模块的gradle文件的SDK的最小版本 改完之后报错消失 备注 SDK Software Develop
  • in和=无法查出为NULL的值

    select from base persons x where x pname in null select from base persons x where x pname null 以上两句查询结果为空 虽然表里有相应的值 Id N
  • PAT 1152 Google Recruitment

    原题链接 1152 Google Recruitment 20分 题意 从任一给定的长度为 L 的数字中 找出最早出现的 K 位连续数字所组成的素数 关键词 字符串 判断质数 输入格式 输入在第一行给出 2 个正整数 分别是 L 和 K 接
  • python机器学习之数据的预处理(五种方式数据处理案例详解)

    数据的预处理 数据下载地址 gt 点这里下载 到入文件时可以直接复制地址然后用r 包裹起来 例如 data pd read cav r C work data csv 或者也可以以直接将 换成 也可以导入 1 归一化 在sklearn当中
  • Nginx四层代理和7层反向代理

    Nginx四层代理和7层反向代理 文章目录 Nginx四层代理和7层反向代理 Nginx四层代理配置 Nginx四层代理配置步骤 配置好两台Nginx七层代理服务器 在四层代理的Nginx服务器上做相关配置 测试结果 Nginx四层代理配置
  • vscode设置选项卡换行

    ctrl shift p打开命令输入窗口 输入preference 选择打开工作区设置 输入wrap tabs 勾选wrap tabs 可以多行显示了
  • Vue应用方法、实例属性、实例方法$refs、vm.$nextTick等

    应用方法 实例属性 实例方法 Vue 中对部分特殊的属性和功能方法进行特殊指代定义 用于提供独立的执行和 获取方式 应用方法 mount 所提供 DOM 元素的 innerHTML 将被替换为应用根组件的模板渲 染结果 unmount 卸载
  • java prepare_java中prepareStatement与createStatement的区别

    首先来看两段代码 第一个使用createStatement 1 public void delete intid 2 try 3 Connection c DBUtil getConnection 4 Statement s c creat
  • Nginx之location匹配规则

    什么是location nginx就是通过拦截到的请求去对配置好的location块 location block 进行请求代理的 被代理的URL去对location后边的字符串 或正则 根据一定的规则进行匹配 然后执行对应location
  • 你是否曾质疑过DB-Engine的数据库排名?

    在谈论数据库的最新趋势时 我们习惯了参考DB Engine上所提供的排名信息 每当新的报告出来时 我们也时常看到各个媒体网站争先发布关于最新排名的分析内容 如标题所言 你是否曾质疑过DB Engine所给出的这份排名 如下是2018年3月份
  • php后台接收blob文件流,php – 我们如何访问服务器中的文件blob?

    在上传大于maxChunkSize的文件时 我们如何在服务器中单独访问每个上传的文件blob 我的问题是我需要使用后端api将上传的文件在单独的blob中转发到不同的服务器 到目前为止 看看wiki 对于1 mb的块 我在js中添加了以下内
  • Python logging将日志输出到Kafka

    Python logging用于输出Python程序运行的日志 现实中往往一个项目会部署在多台机器之上 这种情况下 为了方便对各主机运行日志进行收集 往往会使用消息队列 通过消息队列将各台机器上的日志收集并写入日志文件 本文使用Python

随机推荐

  • linux库概念及其编程

    分文件编程案例 好处 分文件编程思想 功能责任划分 方便调试 主程序简洁 例子 demo c include
  • 在外包做了3年,离职后成功入职字节跳动....

    最近换了份工作 当时和群里的朋友也聊过换工作的话题 他们都觉得这是一次非常冒险的行为 说我这是一次豪赌 成了会有更好的职业发展 没成可能就会出现两三年的发展断层 甚至影响职业生涯路径 一步错 步步错 我当时也仔细的考虑过了 的确有很大的风险
  • STM32标准IIC驱动

    IIC Inter Integrated Circuit 总线是一种由 PHILIPS 公司开发的两线式串行总线 用于连接 微控制器及其外围设备 也是目前很流行的通讯总线 使用IIC总线做产品能够很大程度上降低PCB的布线难度 以及布线数量
  • fio使用good blog

    Linux应用 磁盘IO读写测试工具 FIO详解 协议森林的博客 CSDN博客 fio读写测试 编译安装 常用参数 实例 结果说明 SSD测试第一神器 FIO 磁盘IO体系架构与存储解决方案 pudn com 磁盘性能指标 IOPS与吞吐量
  • DC-5靶场(一般详细)

    目录 简介 一 找IP地址 二 扫描IP端口 三 找web漏洞 文件包含 四 拿webshell 五 提权 总结 简介 dc系列靶场是比较适合新手的黑盒测试靶场 其中dc 5靶场下载连接如下 dc 5靶场下载地址 一 找IP地址 netdi
  • 蓝桥杯2013c++真题:振兴中华

    思路一 dfs暴力搜索 从我做起振兴中华分别为12345678 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 迷宫问题模板 dfs x y path 从 x y 深度优先搜索 if x y为终点坐标 x y
  • 静态库的生成与使用

    1 静态库的生成与使用 1 我自己写一个 c 文件 里面存放我定义的函数 1 include
  • 酷炫网页按钮,炫酷变色效果(附源码)

    酷炫网页按钮 效果如下图 目录如下 html代码如下 index html a href sunbtton a css代码 inedex css margin 0px padding 0px body
  • 【C++】封装map和set(红黑树实现)

    前言 前面 我们学习了set和map的用法 这两个容器可以完成查找 排序等操作 后来我们在学习过二叉搜索树的基础上又学习了两种特殊的二叉搜索树 AVL树和红黑树 他们俩可以是效率进一步提高 其实set和map的底层就是由红黑树封装而成的 所
  • Camunda 入门开发指南 - 1 初始化spring boot项目

    目录 Camunda Platform Initializr 代码结构 Application spring boot启动类 Camunda在spring中的配置 Camunda流程定义文件 Camunda Modeler 工作流定义 图形
  • 面试总结 - 计算机网络

    计算机网络 1 OSI 七层模型 TCP与UDP 响应状态码 OSI 模型 应用层 计算机用户 以及各种应用程序和网络之间的接口 其功能是直接向用户提供服务 完成用户希望在网络上完成的各种工作 HTTP SMTP FTP DNS 表示层 负
  • permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

    错误 permission denied while trying to connect to the Docker daemon socket at unix var run docker sock Get http 2Fvar 2Fru
  • 基于springboot开发项目架构之Eureka

    Eureka介绍 Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装 它实现了服务治理的功能 Spring Cloud Eureka提供服务端与客户端 服务端即是Eureka服务注册中心 客户端完成微服务
  • STL容器(持续更新中)

    一 string类 1 构造函数 常用的构造函数如下 构造函数原型 含义 string 默认构造函数 创建一个默认string对象 长度为0 string const string s 拷贝构造函数 用一个string对象初始化另一个str
  • jstree的简单使用例子

    最近使用到了jstree 感觉是一款灵活的 可多项定制的tree插件 我这边使用过程记录下 参考的jstree api网站 以及demo介绍 https www jstree com api jstree api github https
  • china变为glmre

    include
  • OpenDRIVE地图中Geometry线段对应x/y坐标的计算

    OpenDrive地图解析代码可以参考 https github com liuyf5231 opendriveparser 在OpenDRIVE地图的解析和绘制过程中 最关键的一点 在x y坐标系下 利用起点 x y 曲线的相对长度 s坐
  • the vm session was closed before any attempt to power it on

    今天启动VBOX出现这个问题 the vm session was closed before any attempt to power it on 然后在网上搜索了下 没有满意答案 大多建议重新选择以前的VDI文件 我可不想把我辛辛苦苦写
  • Visual Studio 设置默认编码格式为 UTF-8

    1 添加高级保存选项 2 更改编码格式
  • JavaScript创建对象的9种方式

    JavaScript创建对象的九种方式 Object构造函数创建对象 不再赘述 对象字面量 不再赘述 工厂模式 用函数来封装以特定接口创建对象的细节 function createPerson name age job var o new