本文深入解析JavaScript面向对象编程核心,详细阐述构造函数的定义特点、new操作符的执行流程及this绑定机制。通过对比直接调用与new调用的差异,结合new.target特性实现兼容写法,并手动模拟实现构造函数逻辑,帮助开发者掌握JS对象创建的本质原理。
前言
在面向对象编程范式中,每个对象都充当独立的功能中心,拥有明确的职责分工,负责信息的处理与交互。这种编程方式具备高度的灵活性、代码复用性和模块化优势,尤其适用于需要多人协作的大型项目开发。
1. 构造函数
构造函数的主要职责是创建对象,即生成具有相同结构特征的实例。与Java语言通过类(Class)来定义面向对象不同,JavaScript采用构造函数作为对象的模板,并借助prototype属性来实现继承机制。
构造函数的几个特点
- 在构造函数内部,this关键字指向正在被创建的新对象。
- 构造函数通常需配合new操作符使用,以正确初始化对象。
- 按照惯例,构造函数的首字母通常大写,以此与普通函数进行区分。
- 构造函数默认返回新创建的对象(即this)。若手动返回一个引用数据类型,则会覆盖默认的返回值。
function Person(name ){
this.name = name;
};
const jack = new Person('jack'); //Person {name: 'jack'}
function Person(name ){
this.name = name;
return name;
};
const jack = new Person('jack'); //Person {name: 'jack'}
function Person(name ){
this.name = name;
return ['jack'];
};
const jack = new Person('jack'); //['jack']2. new的过程
- 首先创建一个新对象,并将其绑定给this。
- 将该新对象的原型([[Prototype]])设置为构造函数的prototype属性。
- 执行构造函数内的代码,向this对象添加属性和方法。
- 最后返回this对象。
2.1 基础使用
function Person(name ){
this.name = name;
};
const jack = new Person('jack');
const tom = new Person('tom');
console.log(jack); //Person {name: 'jack'}
console.log(tom); //Person {name: 'tom'}如果直接执行构造函数会发生什么?
function Person(){
this.name = name;
};
const jack = Person('jack'); //undefined此时构造函数的this指向全局对象window,且不会返回新对象。为解决此问题,我们可以采用以下兼容写法:
function Person(name){
if(!(this instanceof Person)){
return new Person(name);
};
this.name = name;
};
经过上述处理,现在可以直接正常使用构造函数了。
Person(name); //Object { name: "jack" }
2.2 new.target
在函数内部可以使用new.target属性。如果函数是通过new操作符调用的,则返回被调用的构造函数本身;否则返回undefined。
function Person(){
console.log(new.target);
};
new Person(); //function Person(){...}
Person(); //undefined
利用new.target特性,我们可以进一步优化构造函数的兼容逻辑。
function Person(name){
if(!(new.target === Person)){
return new Person(name);
};
this.name = name;
};
console.log(Person('jack')); //Object { name: "jack" }
3. 手动实现一个构造函数
function myNew() {
const args = Array.prototype.slice.call(arguments);
const construct = args.shift();
//创建this,并将原型设置为构造函数的prototype
const context = Object.create(construct.prototype);
//执行构造函数,注意这里参数是数组形式所以使用apply
construct.apply(context, args);
//返回
const res = construct();
if ((typeof res === 'object' || res === 'function') && typeof res !== 'null') {
return res;
} {
return context;
}
};
function Person(name, age) {
this.name = name;
this.age = age;
};
const jack = myNew(Person, 'jack', 21);
//Person {name: 'jack', age: 21}到此这篇关于JavaScript面向对象编程实现模拟的文章就介绍到这了,更多相关JS面向对象内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!