js中用构造器创建对象与字面量创建对象的区别

本文探讨了JavaScript中使用构造器和字面量创建对象的不同之处。通过示例对比了这两种方式如何实现对象的创建,并分析了它们在属性继承方面的细微差别。

 http://m.blog.csdn.NET/blog/z1547840014/9734179

    当用new操作符调用一个函数时,就会创建一个新的JavaScript对象.接着,该函数会作为该新建对象的this值被调用,而在原始调用中所使用的参数也都将一并传递给该函数调用

        
        下面我们来研究下使用构造器处创建对象和使用字面量创建对象的区别到底是什么,先看下面的代码
        function Circle(radius){
            this.radius = radius;
        }
        var cicr = new Circle(6);
        
        var cicr2 = {radius:6};
        
        上面两个对象都会拥有2个属性,如果对js这块熟悉的同学想必已经猜到了这2个属性,一个是radius属性,另一个就是从object.prototype继承而来的属性.对于radius属性,他们没有任何区别。但是对于这个原型属性,内部实现上有细小的区别。cicr2是直接继承了object.prototype属性,而cicr是间接继承了object.prototype属性。cicr首先继承了Circle上的原型属性,这个原型属性又继承了object.prototype属性,所以它也完成了对object.prototype的继承。
<think> 首先,用户的问题是基于他们提供的引用,询问Java中使用new关键字创建对象的详细说明。我必须参考用户提供的引用,特别是引用[1][2],因为它们直接讨论new关键字。 关键引用: - 引用[1]:提到new关键字的基本应用,包括特殊情况如ClassLoaderConstructor.newInstance(),它们间接使用new关键字。 - 引用[2]:提供了new关键字创建对象的详细过程:类加载、内存分配、初始化零值、构造函数初始化、返回对象引用。 - 其他引用如[3]、[4]、[5]讨论数组创建、不使用new创建对象(如序列化)、transient关键字等,但用户的问题焦点是new关键字。 用户指令: - 系统级指令:确保所有行内数学表达式在$...$内;独立公式在$$...$$内;LaTeX语法正确;使用中文回答;生成相关问题。 - 回答结构:参考站内引用,末尾添加引用标识如[^1];结构清晰,真实可靠;帮助用户逐步解决问题。 我的回答结构: 1. **引言**:简要介绍new关键字的作用。 2. **详细说明创建对象的步骤**:基于引用[2],分解过程:类加载、内存分配、初始化零值、构造函数初始化、返回引用。 3. **特殊情况**:基于引用[1],讨论间接使用new的方式(如反射API)。 4. **其他相关点**:如果需要,提到数组创建(引用[3])或不使用new的方式(引用[4]),但焦点是new关键字。 5. **总结**。 6. **生成相关问题**:根据指令,在末尾添加相关问题。 使用中文回答:整个回答必须用中文。 添加引用标识:在相关段落末尾自然地添加[^1]、[^2]等。例如,当引用[2]的内容结束时添加[^2]。 生成相关问题:在回答结束后,添加一个部分如“相关问题”,列出3-5个相关问题。问题应基于主题,如优化、应用场景、常见错误等。 确保真实可靠:基于提供的引用Java知识。引用[2]给出了详细步骤,我可以扩展一下。 步骤分解(来自引用[2]): 1. 类加载:检查类是否加载,未加载则加载字节码。 2. 内存分配:在堆上分配内存。 3. 初始化零值:设置默认值(如0或null)。 4. 构造函数初始化:执行构造函数代码。 5. 返回对象引用。 在回答中,使用LaTeX如果有数学表达式,但这里可能不需要,因为是Java代码解释。如果有变量,如int x = 0; 可以写成行内$...$,但通常Java代码用代码块更好。 代码块:用户示例中有Python代码块。我应该添加Java代码块来演示new关键字的使用。例如: ```java MyClass obj = new MyClass(); ``` 引用标识:在描述结束时添加,如“这个过程包括... [^2]”。 相关问题示例: - new关键字创建对象时有哪些性能考虑? - 如何在反射中使用new关键字间接创建对象? - new关键字其他创建对象的方式有何区别? 完整大纲: 1. 引言:new关键字是Java中创建对象的主要方式。 2. 基本语法示例。 3. 详细步骤解释。 4. 特殊情况(反射等)。 5. 总结。 6. 相关问题。 </think> ### Java中使用`new`关键字创建对象的详细说明 在Java中,`new`关键字是创建对象实例的核心机制,它负责在堆内存中动态分配空间并初始化对象。以下是基于引用资料的详细说明,包括基本语法、工作原理特殊情况。整个过程遵循Java虚拟机的规范,确保对象的正确创建初始化。 #### 1. **基本语法示例** - 语法:`ClassName objectName = new ClassName();` - 示例: ```java // 创建一个Point对象 Point point = new Point(); point.x = 5; // 初始化属性 point.y = 6; ``` 这里的`new`运算符触发对象的创建流程:分配内存、调用构造函数并返回引用[^2]。 #### 2. **创建对象的详细步骤** `new`关键字创建对象的过程是一个严格的序列化操作,包括以下五个步骤: 1. **类加载(Class Loading)** 当使用`new`关键字时,Java虚拟机(JVM)首先检查该类是否已加载。如果未加载,JVM通过类加载器(ClassLoader)将类的字节码文件加载到内存中,并生成一个对应的`Class`对象。这一步确保类的元数据(如方法表)在内存中可用[^2]。 2. **内存分配(Memory Allocation)** 类加载完毕后,JVM根据对象实例的大小(由类定义决定)在堆(Heap)区分配连续的内存空间。内存大小计算包括对象头(存储哈希码、GC信息等)实例变量。分配是动态的,依赖于当前堆状态[^2]。 3. **初始化零值(Zero Initialization)** 分配的内存会被初始化为默认零值: - 基本类型:例如,`int`初始化为$0$,`boolean`初始化为$false$。 - 引用类型:初始化为`null`。 这一步确保对象状态在构造函数执行前处于一致状态[^2]。 4. **构造函数初始化(Constructor Initialization)** JVM调用类的构造函数(如`ClassName()`),执行以下操作: - 初始化实例变量(例如,显式赋值如$x=5$)。 - 执行构造函数内的逻辑(如方法调用)。 - 构造函数链:如果类有父类,先调用父类构造函数(通过`super()`)。 示例: ```java public class Point { int x; int y; public Point() { // 构造函数 x = 0; // 显式初始化 y = 0; } } ``` 此步骤将对象从“默认状态”转换为“有效状态”[^2]。 5. **返回对象引用(Reference Return)** 构造函数执行完毕后,JVM将对象的引用(内存地址)返回给调用代码。此引用允许程序通过变量访问对象的属性方法。例如: ```java Point p = new Point(); // p 持有堆内存地址 ``` 整个过程确保了对象的完整性安全性,但可能涉及性能开销(如内存分配构造函数调用)[^2]。 #### 3. **特殊情况:间接使用`new`关键字** 在某些场景下,`new`关键字并非直接使用,而是通过反射或类加载器间接调用: - **反射API(Constructor.newInstance())** 例如,`Constructor.newInstance()`方法内部使用`new`分配内存,但允许运行时动态创建对象(即使类名在编译时未知): ```java Class<?> clazz = Class.forName("com.example.Point"); Constructor<?> constructor = clazz.getConstructor(); Point point = (Point) constructor.newInstance(); // 间接调用new ``` 这种方法常用于框架(如Spring)以实现依赖注入[^1]。 - **类加载器方法(ClassLoader.newInstance())** `ClassLoader`的`newInstance()`方法也依赖`new`关键字,但开发者不直接操作`new`: ```java ClassLoader loader = getClass().getClassLoader(); Object obj = loader.loadClass("com.example.Point").newInstance(); ``` 适用于插件系统或动态加载类[^1]。 #### 4. **其他创建方式的对比** - **不使用`new`的方式**:如序列化(`ObjectInputStream.readObject()`)或克隆(`Object.clone()`),这些方法不直接调用`new`,但内部可能依赖JVM的低级内存操作[^4]。 - **数组创建**:`new`关键字也可用于对象数组,但需注意数组元素需逐个初始化: ```java Point[] pointArr = new Point[3]; // 分配数组内存 pointArr[0] = new Point(); // 每个元素需显式创建对象 pointArr[0].x = 5; ``` 错误示例(如引用[3])可能导致`NullPointerException`,因为数组元素未实例化[^3]。 #### 5. **总结** `new`关键字是Java对象创建的基石,通过严格的步骤(类加载、内存分配、初始化、构造调用)确保对象完整。虽然直接使用最常见,但反射等间接方式扩展了其灵活性。开发者应关注内存开销(如堆分配)初始化逻辑,以避免性能瓶颈或错误[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值