JavaScript中调用一个函数使用new关键字和直接调用的区别

本文探讨JavaScript中使用new关键字调用函数与直接调用的区别。通过构造器和工厂模式的示例,解析不同调用方式产生的对象类型及作用域差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

随着JavaScript的功能不止可以运行在客户端浏览器作为脚本,还是可以运行在服务器端的NodeJs,对于一个程序员,开发人员来说,不管是做前端,还是做后台,js的使用已经成为一个必备的能力,在此讨论一下js中调用一个函数使用new关键字和直接调用的区别,希望能带给新手一些帮助。也希望得到大神的指导。
[b]一 构造器模式:[/b]
先看一下代码:

function Person(name,age){
this.name=name;
this.age=age;
}
p1=Person('tom',20);
p2=new Person('mary',21);
console.log(p1);//undefined
console.log(p2);//Person {name: "mary", age: 21}
console.log(typeof p1);//undefined
console.log(typeof p2);//object

为什么会有以上差别呢?请看一下分析:
1.使用new则是将之当做构造函数来调用,会创建一个该类的实例对象,这个对象的type是这个函数名,中间使用this.propertyName=value会对该实例对象的属性赋值,并且无论有没有return,都会返回这个对象。

2.而如果是直接调用就是简单执行里面的代码,不会创建实例对象,this指向的调用环境下的this对象,如果是在全局中直接调用,就是window,没有默认返回值。

p1就是函数Person()执行的返回值,也就是undefined. 在函数执行过程中,属性被加到全局作用域或者Person方法所属的对象上了。执行以下代码,发现属性加在了window上:

console.log(window.name);//tom
console.log(window.age);//20

而p2是Person()的实例,Person {name: "mary", age: 21}

[b]二 工厂模式:[/b]
如果将Person函数构造为以下情况,结果会出现例外情况:

function Person(name,age){
var obj = new Object();
obj.name=name;
obj.age=age;
return obj;
}
p3=Person('jim',20);
console.log(p3);//Object {name: "jim", age: 20}
console.log(typeof p3);//object

这个就不需要加new,p3是一个Object,不是Person的实例。

Date();不加new返回当前时间,是一个字符串。加new的话,返回当前时间或者把参数格式化得到的时间,是一个Date对象。

String():不加new将参数格式化为字符串,加new则返回的是String对象。案例如下:

var str1=new String("abc");
var str2=String("abc");
console.log(str1);//String {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
console.log(str2);//abc
console.log(typeof str1);//object
console.log(typeof str2);//string
str1.prop = 1;
console.log(str1.prop);//1
str2.prop = 1;
console.log(str2.prop);//undefined

Number类似于String。

总结以上内容有以下两点结论:
1. 直接调用函数的时候它叫“普通函数”,此时用全局对象window做上下文。
2. 用new关键字调用的时候它叫“构造函数”,此时用这个新生的对象做上下文。

限于个人能力,只能总结到这个程度,不喜勿喷!
<think>好的,我现在需要回答用户关于如何使用函数构造函数创建对象的问题。用户提供了四个选项,分别是a到d。首先,我得回忆一下JavaScript中构造函数的相关知识。 首先,构造函数JavaScript中通常是通过定义一个函数,然后使用`new`关键字调用的。构造函数内部使用`this`来添加属性,而`new`操作符会自动创建一个新对象,并将其绑定到构造函数中的`this`,然后返回这个新对象。因此,选项c“使用new关键字调用函数构造函数”应该是正确的。 接下来,看看其他选项。选项a提到用return显式返回对象。虽然技术上可以在构造函数使用return返回一个对象,但这并不是标准的做法,而且会改变构造函数的行为,导致无法正确继承原型链上的方法,所以这可能不是正确的方法,除非题目特别说明这种情况,但通常不推荐,所以a应该不正确。 选项b说使用this关键字直接返回对象。这里可能存在误解,因为this在构造函数中指向新创建的对象,但构造函数本身并不会返回this,而是通过new操作符隐式返回。如果直接返回this,而没有使用new,那么this可能指向全局对象(比如在非严格模式下),所以b的说法不正确。 选项d提到使用class关键字。虽然ES6引入了class语法,但class本质上是构造函数的语法糖。使用class确实可以创建对象,但题目明确问的是“使用函数构造函数”,因此d可能不是题目要求的答案,特别是如果题目强调的是传统的构造函数而非class的话。但需要确认题目的意图,如果用户的问题允许使用class的话,可能d也是正确的。不过根据题目的选项描述,选项cd都有可能正确,但要看具体语境。例如,如果视频中讨论的是ES5的构造函数,则c是正确答案,如果是ES6的class,则d正确。但题目问的是“函数构造函数”,所以更可能指的是传统的构造函数,即选项c。 总结下来,正确选项应该是c,使用new关键字调用函数构造函数。同时,如果有使用class的情况,可能d也是正确的,但需要看问题是否接受ES6的语法。但根据常规的构造函数定义,c是正确答案。</think>### 正确方案 **✅ 答案c是标准实现方式** #### 核心原理 通过 **`new` 运算符**调用构造函数时: 1. 自动创建空对象 `{}` 2. 将该对象绑定到构造函数内的 `this` 3. 自动返回新对象(无需显式`return`) #### 标准代码示例 ```javascript // 1. 定义构造函数 function Person(name) { this.name = name; // ✅ 通过this添加属性 this.greet = function() { console.log(`Hello, ${this.name}!`); }; } // 2. 使用new创建实例 const user = new Person("Alice"); // ✅ 答案c正确 user.greet(); // 输出: Hello, Alice! ``` --- ### 错误选项解析 | 选项 | 问题说明 | 错误示例 | |------|----------|----------| | **a. return语句** | 破坏构造函数特性,返回非预期对象 | ```javascript function WrongObj() { return {a:1}; // ❌ 强制返回对象会丢失原型链 } console.log(new WrongObj() instanceof WrongObj); // false ``` | **b. this直接返回** | `this`无法主动返回,需依赖`new`机制 | ```javascript function FailObj() { this.value = 10; return this; // ❌ 未用new时,this指向全局对象 } console.log(FailObj().value); // 污染全局作用域 ``` | **d. class关键字** | class本质是语法糖(题目限定用函数构造函数) | ```javascript class MyClass {} // ✅ 有效但不符合题干要求 ``` --- ### 关键特性对比 | 方式 | 原型继承 | 需`new`调用 | `instanceof`检测 | 适用场景 | |---------------------|----------|-------------|------------------|------------------| | 构造函数+new(答案c) | ✅ | ✅ | ✅ | 兼容性要求高的代码 | | class(答案d) | ✅ | ✅ | ✅ | ES6+项目 | | 工厂函数+return | ❌ | ❌ | ❌ | 需要灵活控制对象 | --- ### 进阶最佳实践 1. **强制`new`调用保护**(防止忘记`new`): ```javascript function SafeConstructor(name) { if (!(this instanceof SafeConstructor)) { return new SafeConstructor(name); // 自动补new } this.name = name; } ``` 2. **原型方法优化**(节省内存): ```javascript function Animal(type) { this.type = type; } // ✅ 方法挂在原型上 Animal.prototype.getType = function() { return this.type; }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值