Js 使用new关键字调用函数和直接调用函数的区别

最近开始学习js,在看到书上的一个例子时,引发了我的一系列思考:

书上例子:

function Person(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 friend=new Person("Nicholas",29,"Software Engineer");

friend.sayName();

 

Person函数创建了一个对象,并以相应的属性和方法初始化该对象,然后又返回了这个对象,除了使用new操作符且把使用的包装函数叫做构造函数之外,这个模式跟工厂模式是一模一样的。

注意:构造函数在不返回值的情况下,默认返回新对象实例。

看到这里,我就将上面的例子的new关键字去掉,发现和原来结果一样。

而后,我写了一下几个例子,进行比较:

function Person(name,age){

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

}

//var person=new Person("张三",20); //此处为 构造对象,构造对象的话,返回的新对象是由解析器自己生成的。
var person=Person("张三",20); //报错 person undefined 此处为普通函数调用,又没有给定返回值,出错。
person.sayName();

 

得出结论:使用new关键字是将函数当作构造函数调用,即为构造对象,若没有人为的重写调用构造函数时返回的值,那么返回的对象是由解析器自己生成的。不使用new关键字调用函数,即为普通函数调用。

随即想到若是函数返回值是function型的呢?

例子:

function Test() {
  this.name = 'Test';
  return function() { return true; }
}

//var test = Test();// test function() { return true; }
  var test01 = new Test();// 构造对象
  var test02=Test();//函数调用
  alert(test01==test02);//false  虽然浏览器运行结果一样,但是比较结果还是false,因为 Javascript  对于 Object 和 Function 的比较是基于引用的。

浏览器运行监视结果发现:

 

最后我将返回值改成String类型:

function Test() {
  this.name = 'Test';
  return "Test" ;
}

//var test = Test();// test function() { return true; }
var test01 = new Test();
var test02=Test();
alert(test01==test02);//false

浏览器下运行监视结果:

 

 

最后得出一个猜测:

如果函数返回值为常规意义上的值类型(Number、String、Boolean)时,new 函数将会返回一个该函数的实例对象,而如果函数返回一个引用类型(Object、Array、Function),虽然new函数与直接调用函数产生的结果等同,但是是两个不同的过程,一个是构造对象、一个是函数调用。

通过在 Test函数中返回不同类型的值进行测试,可以证实这一点。

转载于:https://www.cnblogs.com/jstarseven/p/4442747.html

<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、付费专栏及课程。

余额充值