JavaScript无new实例化对象的两种实现方式详解

作者:纸飞机

时间:2026-10-30

浏览:386

本文详解JavaScript中不使用new关键字创建对象的两种常见模式。第一种通过直接调用原型方法实现,但会导致所有实例共享同一对象状态;第二种结合new操作符与原型指向修正,在保持无new调用便捷性的同时,确保每个实例拥有独立的作用域和属性,是jQuery等库的核心实现思路。

文章目录

JavaScript无new构建实例详解

在研读jQuery源码时,其对象创建机制起初令人费解,经过深入分析后理清了思路,现将相关原理整理如下。

第一种无new构建方式分析

第一种实现方式如下:


var A = function(){
return A.prototype.init();
}
A.prototype = {
init:function(){
this.age = 50;
console.log(this);
return this;
},
age:100
}
console.log(A() === new A());

JavaScript无new构建实例详解

首先分析为何该方式返回结果为true。

函数A()内部实际执行的是A.prototype.init()方法。

当使用new A()时,内部会调用构造函数,该构造函数定义为function(){return A.prototype.init();},因此最终同样执行A.prototype.init()方法。

接下来分析A.prototype.init()函数的返回值。

关键在于this的指向。由于该方法作为原型对象的属性被调用,此时this指向原型对象A.prototype本身。

采用这种创建方式,无论调用多少次A(),返回的都是同一个对象实例。因此,对变量b的修改会直接影响变量a,具体表现见下图。


var a = A();
var b = A();
console.log(a.age);
console.log(b.age);
b.age = 22;
console.log(a.age);
console.log(b.age);

JavaScript无new构建实例详解

第二种无new构建方式及原理

为解决上述共享状态的问题,下面介绍第二种方式,这也是jQuery所采用的方案。

第二种实现方式如下:


var A = function(){
return new A.prototype.init();//①
}
A.prototype = {
init:function(){
this.age = 50;
console.log(this);
return this;
},
age:100
}

 A.prototype.init.prototype = A.prototype;//②
var a = new A();
var b = new A();
console.log(a===b);
console.log(a.age);
console.log(b.age);
b.age = 22;
console.log(a.age);
console.log(b.age);

JavaScript无new构建实例详解

对代码中标记①和②的部分进行详细分析。

语句①中new A.prototype.init()主要执行了三个步骤。

第一步是创建一个空对象,即var obj = {};。

第二步是将obj对象的__proto__属性指向函数A.prototype.init的prototype属性。

第三步是将A.prototype.init函数的this上下文替换为obj对象,执行A.prototype.init.call(obj),并返回新创建的对象。

由于语句①返回的对象原型是A.prototype.init.prototype,这与A.prototype并无直接关联。为了使新返回的对象能够继承自A.prototype,语句②将A.prototype.init.prototype重新指向A.prototype。

因此,方式二既成功创建了实例,又保证了各个实例间作用域的独立性。

以上介绍了JavaScript中无new构建对象的两种实例详解,希望对读者有所帮助。如需了解更多相关信息,敬请关注本站后续更新。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章