【JS】JavaScript中对象的创建与原型模式

FR4板材实战:用ADS 2023快速设计微带线低通滤波器(附Line-Cal计算技巧) 本文详细介绍了使用ADS 2023在FR4板材上设计1-3GHz微带线低通滤波器的工程技巧。通过Line-Cal工具快速计算微带线参数,解决FR4板材的介质损耗和阻抗匹配问题,提供从集总参数转换到分布参数的实用方法,并分享版图设计与实测验证的关键要点,帮助工程师高效完成射频滤波器设计。 阅读详情


ECMAScript中没有类的概念,因此它的对象与基于类的语言中的对象有所不同。

1.理解对象

创建对象最简单的方式是创建一个Object实例,再为它添加属性和方法,如下:

<span style="font-family:SimSun;font-size:12px;">var people = new Object();
people.age = 20;
people.sayAge = function(){
    alert(this.age);
};</span>

以对象字面量的方式创建对象:

<span style="font-family:SimSun;font-size:12px;">var people = {
    age:20,
    sayAge:function(){
        alert(this.age);
    }
};</span>


2.创建对象

工厂模式:

<span style="font-family:SimSun;font-size:12px;">function createPeople(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayAge = function(){
        alert(this.age);
    };
    return o;
}
 
var p1 = createPeople("AA", 19);
var p2 = createPeople("BB", 19);</span>

使用工厂模式创建对象的不足在于无法知道一个对象的类型,没解决对象识别的问题(对象都Object类型,这里只是人为给该方法命名为createPeople,使创建出的对象”看似“people),因此引出下一种模式;


构造函数模式:

<span style="font-family:SimSun;font-size:12px;">function People(name, age){
    this.name = name;
    this.age = age;
    this.sayAge = function(){
        alert(this.age);
    };
}
 
var p3 = new People("CC", 21);
var p4 = new People("DD", 22);</span>

使用该模式创建People的实例,要使用new操作符,调用构造函数实际上经过以下四步骤:

  1. 创建新对象;

  2. 将构造函数作用域赋给新对象(因此this指向了这个新对象);

  3. 为新对象添加属性(执行构造函数中的代码);

  4. 返回新对象

使用该模式没有显式创建对象、直接将属性和方法赋给this对象、没return语句。

上面p3、p4都保存有People的一个不同的实例,p3、p4都有一个constructor(构造函数)属性,指向People,如下:

<span style="font-family:SimSun;font-size:12px;">alert(p3.constructor == People);  // true</span>

下面使用instanceof操作符检测对象类型,如下:

<span style="font-family:SimSun;font-size:12px;">alert(p3 instanceof People);  // true
</span>

创建自定义的构造函数可以将它的实例标识为一种特定的类型,解决了工厂模式解决不了的对象识别问题。

对于任何函数,能通过new操作符调用的,就可以作为构造函数;不能有通过new操作符调用的,就跟普通函数一样。



<span style="font-family:SimSun;font-size:12px;">// 作为普通函数调用
People("EE", 23);  // 添加到了window
window.sayAge();  // "EE"
 
// 在另一个对象的作用域中调用(另一个对象作为调用者)
var o = new Object();
People.call(o, "FF", 24);
o.sayAge();  // 24</span>

上面第一个例子中,因为在全局作用域中调用一个函数时,this对象是指向Global对象的,在浏览器中即是window对象,因此可以通过window对象调用sayAge()方法。

    虽然使用构造函数创建对象解决了对象类型识别问题,但这种模式不足就在于每个方法都要在每个实例上重新创建一遍。因为在ECMAScript中的函数也是对象,每定义一个函数也是实例化了一个对象,因此p3、p4中的sayAge()方法并不是同一个Function实例,上面使用构造函数创建对象的模式在逻辑上其实与以下的是等价的。

<span style="font-family:SimSun;font-size:12px;">function People(name, age){
    this.name = name;
    this.age = age;
    this.sayAge = new Function("alert(this.age)"); 
}
alert(p3.sayAge == p4.sayAge );  // false</span>

使用这种方式,不同实例上的同名函数是不相等的,这时可以用下面的方式解决这问题:

<span style="font-family:SimSun;font-size:12px;">function People(name, age){
    this.name = name;
    this.age = age;
    this.sayAge = sayAge;
}
 
function sayAge(){
    alert(this.age);
};
 
alert(p3.sayAge == p4.sayAge );  // 使用这种方式会返回true</span>

这样把sayAge()函数的定义定义在构造函数外部,在构造函数里将sayAge属性等于全局的sayAge()函数,这样sayAge属性包含的是一个指向sayAge()函数的指针,因此p3、p4就共享了这个全局的sayAge()函数;那问题又来了,如果对象需要定义很多方法时,那么将要定义很多个全局函数,在此引出下一种模式;

原型模式:

先看一个例子:





<span style="font-family:SimSun;font-size:12px;">function People(){}
 
People.prototype.age = 20;
People.prototype.sayAge = function(){
    alert(this.age);
};
 
var p5 = new People();
p5.sayAge();  // 20
 
var p6 = new People();
p6.sayAge();  // 20
 
alert(p5.sayAge == p6.sayAge );  // true</span>

使用原型对象的好处在于可以让所有实例共享它所包含的属性和方法,不必在构造函数中定义对象的信息,而是将这些信息添加到原型对象上,这里的构造函数是空函数,属性和方法被加到People的prototype属性上,但是使用构造函数创建对象时,对象还是具有这些属性和方法,与传统构造函数不同的是,新对象的属性和方法是由所有实例共享的。要理解原型模式原理,还要先理解原型对象的性质。


    每当创建一个函数时,都会为该函数创建一个prototype属性,这个属性指向函数的原型对象(原型对象的作用是包含可以由特定类型的所有实例共享的属性和方法);而所有原型对象都会自动获得一个构造函数属性(constructor),这个属性包含一个指向prototype属性所在函数的指针。前面的例子就是People.prototype.constructor指向People。

    当调用构造函数创建一个新实例时,该实例 内部将包含一个指针,指向构造函数的原型对象,这个指针一般称为[[Prototype]]。这个连接存在于实例与构造函数的原型对象之间,而不是实例与构造函数间。

    使用对象实例无法访问原型对象,例如p5.prototype是访问不到原型对象的,也没有方式可以访问[[Prototype]],不过一些浏览器在每个对象上都支持一个__proto__属性,通过该属性可以访问到原型对象(p5.__proto__)。

    当访问对象的某一属性时,都会搜索给定名字的属性,首先搜索对象实例本身,如果找到给定名字的属性,则返回;若没找到,再继续搜索指针指向的原型对象,若找到,则返回。这也是多个对象实例共享原型保存的属性和方法的原理。如果人为给实例添加一个与原型中某一属性同名的属性,那么实例中的该属性将屏蔽原型中的那个属性,但原型的被屏蔽的属性的值还是不变的。

    使用hasOwnProperty()方法可以用于检测一个属性是存在于实例中还是原型中,只有在属性存在于实例中时,该方法才返回true。hasOwnProperty()方法常被用于for-in循环中过滤原型中的属性,因为for-in循环默认返回的是所有能通过对象访问的、可枚举的(enumerated)属性,既包括实例中的属性也包括原型中的(这也是for-in循环与传统的for循环的区别)。

接下来使用对象字面量的方式重写上面的原型对象,如下:

<span style="font-family:SimSun;font-size:12px;">function People(){}
 
People.prototype = {
    age:20,
    sayAge:function(){
        alert(this.age);
    }
};</span>

上面将People.prototype设置为等于一个以对象字面量形式创建的新对象,结果也是相同的,唯一例外的是constructor属性不再指向People。因为这里使用{}创建原型对象,每次使用{}都会创建一个新对象,在这里{}就是对象(Object),new Object就相当于{},因为此时constructor属性指向的是Object。

<span style="font-family:SimSun;font-size:12px;">var people = new People();
alert(people.constructor == People);  // false
alert(people.constructor == Object);  // true</span>

使用构造函数与原型模式:

    由前面的介绍可知,使用原型模式下所有实例的属性都是共享的,对其中一个实例的进行修改都会影响到其他实例的属性,但有时我们并不希望实例所有的属性都一样,这时就可以使用组合构造函数与原型模式一起使用,构造函数用于定义实例属性,而原型模式用于定义方法和共享属性。

<span style="font-family:SimSun;font-size:12px;">function People(name, age){
    this.name = name;
    this.age = age;
}
People.prototype = {
    sayAge:function(){
        alert(this.age);
    }
};
 
var p1 = new People('AA', 20);
p1.name = 'CC';  // 修改p1的name属性
var p2 = new People('BB', 21);
 
alert(p1.name);
alert(p2.name);
alert(p1.name == p2.name);  // false
alert(p1.sayAge == p2.sayAge);  // true</span>

Author:顾故

Sign:别输给曾经的自己





















课题申报新手入门必备指南!利用AI辅助搞定 6大关键部分,高效提升申报成功率(附AI提示词) 以下是我(或团队)与本课题相关的已有基础:【如:承担过的公开课、校本教研活动、教学改革实践、课程建设、区级/校级课题、教学反思积累等】请你完成以下任务:1)判断哪些内容与本课题的研究目标和内容具有直接或间接关联;以下是我当前的研究设想(可能比较笼统):【填写你的研究想法 / 教学困惑 / 初步设想】,请你帮我完成以下任务:1)先判断该设想中隐含的核心研究问题是什么;以下是我目前拟定的研究目标,请你从课题评审视角进行校正:【逐条粘贴你已有的研究目标】,请你帮我:1)判断每个目标是否具体、清晰、可评估; 阅读详情

相关推荐

CODESYS做Modbus TCP主站踩坑记:从IP配置到数据映射的完整避坑指南

本文详细记录了在CODESYS中配置Modbus TCP主站的全过程,从IP配置到数据映射的常见问题及解决方案。重点解析了网络适配器选择、Slave ID误解、地址偏移陷阱等关键问题,并提供了实用的调试技巧和性能优化建议,帮助工业通信开发者高效避坑。

weixin_30642561的博客 625

javascript (对象定义)原型模式

 每个函数中都有一个prototype(原型)属性,它是一个指针,指向一个对象。 按照原型定义,prototype通过调用构造函数而创建的对象实例的原型对象。使用原型对象的好处是可以让所有实例共享它包含的属性和方法。 代码例子: function Person(){} Person.prototype.name="Nicholas"; Person.prototype.

Draven 535

机器人导航学习历程(四)local planner

local planner   我们先来回顾一下Navigation的框架,可以看出位于红框中的local_planner是move_base节点的一部分,输入包括来自global_planner的全局的规划路径、里程计信息以及local_costmap的信息,输出是速度控制指令,作为控制器的输入。 base_local_planner   局部规划一般是用base_local_planner包...

yuniruchujian的博客 4413

在javascript中的对象与原型模式

在javascript中的对象第一种是直接创建一个新的空对象,然后通过对象给它的属性赋值用分号隔开&lt;script&gt;     /*创建一个新的对象,然后赋值*/     var person = new Object();     person.name  = "张三"     person.pwd = 123;     person.age = 23;     person.show ...

Golden_soft的专栏 238

空间节省算法在Rowhammer防御中的应用与优化

空间节省算法(Space-Saving)是一种高效的流式数据处理算法,主要用于在有限内存条件下实时识别数据流中的高频项。其核心原理是通过维护固定大小的计数器表,动态跟踪最活跃的元素,适用于处理无限数据流场景。该算法在内存安全领域具有重要价值,特别是在Rowhammer攻击防御中,能够有效检测异常高频访问的DRAM行地址。通过结合计数器衰减策略(如DSAC)和混合架构设计,空间节省算法可以在保证低硬件开销的同时,提供高精度的攻击检测能力。这些技术已成功应用于现代DDR5内存控制器,展现出优异的工程实践价值。

weixin_31139479的博客 606

基于激光雷达的目标跟随功能移植到自己的ROS机器人小车上

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、下载目标跟随的源码二、修改话题名称1.修改/cmd_vel话题名称2.修改/scan话题名称3.修改双电机正反转4.目标跟随功能测试 前言 本人尝试把github上的一个目标跟随项目移植到自己的机器人小车上,并且成功了,最终小车可以跟着人移动,在这里分享一下心得。基于激光雷达的目标跟随,通过获取激光雷达的信息,跟随最近的物体。 提示:以下是本篇文章正文内容,下面案例可供参考 一、下载目标跟随的源码 源码地址:https:

weixin_44574633的博客 4463

初学JavaScript:JS中创建对象的模式(工厂模式/构造函数模式/原型模式/组合模式)

工厂模式 构造模式 原型模式 组合模式

lalala_dxf的博客 2187

KUKA机器人在自动运行时,动作不流畅,每个点位都有停顿的解决办法

KUKA机器人在自动运行时,动作不流畅,每个点位都有停顿的解决办法

Robot_PLC_HMI_Automation 4580

【JS】JavaScript创建对象 - 工厂模式 - 构造函数模式 - 原型模式 - 原型链 - 组合模式

文章目录0. 创建单个普通对象1. 工厂模式2. 构造函数模式3. 原型模式4. 组合模式5. 动态原型模式6. 寄生构造函数模式参考 0. 创建单个普通对象 简单的创建一个对象,可以使用Object构造函数,也可以直接使用字面量的方式。 let o = new Object(); let obj = {}; 如果我们需要创建一些类似的对象,这样就会产生很多重复的代码。 过去的JavaScript中也没有类的概念,为此聪明的JavaScript程序员使用了很多模式来创建对象 1. 工厂模式 functio

YK菌的博客 473

FPGA实现串口升级及MultiBoot(十)串口升级SPI FLASH实现

采用软核进行串口升级的原因主要有以下几点:1、官方推荐:官方以前也推出了针对逻辑进行升级的程序《XAPP1081_QuickBoot》,但是从今年起(2024年)官方就停止更新相关例程了(详见下面截图),所以采用官方推荐的软核更新;2、简单并具有通用性:针对SPI或者BPI官方都有相关的IP,可应对市场上80%以上的FLASH,并且官方IP通用性极强,只需要修改几个参数就可以对不同厂家的芯片进行升级操作;

OpenFPGA的博客 2000

工程测量不用愁,120个视频动画帮你忙,简单易学直观明了!

工程测量不用愁,120个视频动画帮你忙,简单易学直观明了!文末提供下载地址。 下载地址: 链接:https://pan.baidu.com/s/11S6XDq9Eaa3DG3VKRMBIPg

智慧空间实验室 1019

JavaScript对象创建的基石:原型模式详解

在JavaScript的世界里,对象的创建方式犹如一座迷宫。有人热衷于字面量写法,有人执着于工厂函数,还有人推崇类语法糖。然而,这些看似不同的创建方式背后,都指向同一个核心机制——**原型模式**。本文将带您深入探索这个JavaScript语言的"灵魂"机制。

JakeMa1024的博客 942

【Codecs系列】x265编码器(十二):子像素运动搜索

在基于块运动补偿的视频编码框架中,运动搜索是最为重要的环节之一,同时也是编码端最为耗时的模块。运动搜索包括整像素运动搜索和子像素运动搜索,其中整像素运动搜索已经有很多快速算法,比如经典的三步搜索法、菱形搜索、六边形搜索以及TZSearch等等;但子像素搜索的快速算法却比较少,本文主要讲解x265编码器中的子像素搜索方法以及相关的快速搜索方法。

优快云明星博主,认证博客专家,视频、Matlab领域优质创作者。 749

Js创建对象的六种方法

Js创建对象的六种方法 第一种 new 操作符 + Object 创建对象 var person = new Object(); 第二种 字面式创建对象 var person ={ name: "lisi", age: 21, family: ["lida","lier","wangwu"], say: function(){ alert(this.name); } }; 以上两种方#法在使用

weixin_52139094的博客 488

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

原生js-—工厂模式、构造函数模式、原型模式

js里面常见的设计几种模式 1.工厂模式(不需要new):用函数来封装以特定接口创建对象的细节; 来看一个例子,就明白啦; function createObject(name,age,hobby){ var o = {}; o.name = name; o.age = age; o.hobby = hobby; o.show = function(){ a...

代码小宝宝的博客 615

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JavaScript 笔记03(创建对象/原型模式/js 继承/BOM)

js 笔记3 接笔记2 13.创建对象 工厂模式 function createNewObject(name, age, job) { let o = new Object(); o.name = name; o.age = age; o.job = job o.sayName = function() { console.log(name)...

keep moving 232

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

在JS中如何通过原型模式创建对象(一)

在js中可以像“后端”一样使用原型模式创建对象。在调式的过程中,发现原型模式的确可以创建对象,而且相当于引用类型,也就是说,比如通过它来创建两个对象,那么这两个对象创建完后,若其中一个对象改变了原型模式中的属性的值,那么另一个对象也会受到影响,这也就是说不管创建多少个对象,那么这些对象都指向同一个存储空间,这也就是原型模式的一个优势,避免了资源的浪费,因为所有通过它创建的对象,都指向同一...

NC_star的博客 570

js创建对象(js小知识)

js创建对象 工厂模式 工厂模式最大的问题就是不能识别对象,这就引出了构造函数。 function Person(name, age){ var o = new Object(); o.name = name; o.age = age; o.sayName = function(){ console.log(this.name); }; retu...

qq_28500793的博客 175

JS面向对象编程之封装

我们所熟知的面向对象语言如 C++、Java 都有类的的概念,类是实例的类型模板,比如Student表示学生这种类型,而不表示任何具体的某个学生,而实例就是根据这个类型创建的一个具体的对象,比如zhangsan、lisi,由类生成对象体现了抽象模板到具体化的过程,这叫做基于类的面向对象方式,而 JavaScript 没有类的概念,是基于原型的面向对象方式(虽然 Es6 增加了class,实质是对...

zhouminit的博客 344

JavaScript 创建对象 (工厂模式、构造函数模式、原型模式、组合使用构造函数模式与原型模式)

JavaScript 创建对象工厂模式构造函数模式三级目录 总结JS创建对象的几个模式及各自优缺点 工厂模式 function createPerson(name,age,job){ var obj = new Object(); obj.name = name; obj.age = age; obj.job = job; obj.sayName = function(){ console.log(this.name); }; return obj; } var person1 = cre

Ahua_Core的博客 6054

JavaScript对象的几种创建方式

一,对对象的理解? 1,对对象的理解,对象是什么? 编程中的定义:类的实例。 自己的理解:包含属性和方法的就是对象。 定义:对象包含属性和方法,属性是静态的,变化的,通常写在构造函数中,方法是动态的,公用的,通常写在原型中。 js更具体的的实现:var obj = new Object()。==》obj是对象,Object是类;对象是类的实例和具体,类是对象的集合,这是对象和类的关系。 二,J...

moshangyanhua的博客 425

JavaScript(十八)Js中的五种开发模式

一、工厂模式 function stu(){ var s=new Object(); s.name="张三"; return s; } stu(); 说明: 在函数中定义对象,并定义对象的各种属性 调用函数,返回对象 二、构造函数模式 function stu(){ //属性+方法 ...

We_jia的博客 801

JS创建对象

ECMAScript没有类的概念,因此面向对象与传统的静态语言有很大不同。 创建自定义对象简单的方式有两种: var person1 = new Object(); //创建object实例 var person2 = {}; //对象字面量 然后可以给对象动态的添加需要的属性和方法,就可以获得对象的属性,调用对象的方法了。 对于这两种创建对象的方式没有什么区别。不过...

dhxzfdv7839214的博客 156

图解JavaScript原型模式创建对象

JavaScript面向对象这一块的底层原理是很难掌握的,基本是看了忘,忘了再看的循环过程。最近深入理解new运算符底层原理的时候,又看了一遍关于面向对象这一块的知识点,从而有了新的认识。本篇只讨论基于原型模式创建对象,对涉及到的知识点只做简单补充,后续进行细化和整体的对比。 function Person() { } Person.prototype.name = "...

一起的远方的博客 536

javascript创建对象方法总结

javascript创建对象方法的总结。 对象是什么?   js中对象是“无序属性的集合,其属性可以包含基本值,对象或者函数”,简单来说,它就是一个名值对,有key和value,value可以是数据和函数。 怎样创建对象? 创建对象的方法有很多种,它们都有优缺点,下面从简单的开始介绍。 一、使用Object构造函数或者对象字面量方法创建实例对象 使用这种方法创建单个对象,如果...

218

终极指南:Day.js如何通过原型模式实现高效的对象克隆

Day.js作为一款2kB轻量级的日期时间库,以其与Moment.js相同的现代API和 immutable 特性广受开发者青睐。本文将深入解析Day.js如何利用原型模式实现对象克隆,帮助开发者理解其高效设计背后的核心原理。 ## 什么是原型模式? 原型模式是一种创建型设计模式,它通过复制现有对象(原型)来创建新对象,而无需依赖类的实例化。在JavaScript中,每个对象都有一个原型对象,

gitblog_01424的博客 958
上一篇: 【Java】浅谈JDBC事务处理
下一篇: 【HTML】Canvas(1)-绘制图形
励志故事
博客等级 码龄12年 99粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值