JavaScript中达成不加new关键字的构造函数
发布时间:2021-11-19 10:55:33 所属栏目:教程 来源:互联网
导读:一般而言,在JavaScript中创建对象时需要使用关键字new,但是某些时候,开发者希望无论new关键字有没有被显式使用,构造函数都可以被正常调用,即构造函数同时还具备简单工厂的职能。JavaScript的一个特性使得这样的实现变得可行:如果构造函数中返回了对象,
|
一般而言,在JavaScript中创建对象时需要使用关键字new,但是某些时候,开发者希望无论new关键字有没有被显式使用,构造函数都可以被正常调用,即构造函数同时还具备简单工厂的职能。JavaScript的一个特性使得这样的实现变得可行:如果构造函数中返回了对象,无论有没有使用new关键字,最终返回的值都是函数return的值。 基于这点特性,本文介绍了四种实现方式,抛砖引玉,欢迎拍砖~ 1. 在构造函数中返回对象字面量 function Person(name) { return { name: name, getName: function () { return this.name; } }; } console.log(new Person('Ralph').getName()); //Ralph console.log(Person('Ralph').getName()); //Ralph 缺点: 不方便控制prototype属性,不利于高效扩展对象方法,instanceof操作符失效且constructor属性丢失 2. 在构造函数中使用内部函数构造对象 function Person(name) { // lazy loading,在Person函数第一次被调用时初始化内部函数_Person if (!Person.inited) { Person._Person = function (name) { this.name = name; }; // 可以利用prototype进行方法扩展 Person._Person.prototype = { // 正常使用constructor属性 constructor: Person, getName: function () { return this.name; } }; // 可以正常使用instanceof操作符 Person.prototype = Person._Person.prototype; // 标记为已初始化 Person.inited = true; } return new Person._Person(name); } console.log(new Person('Ralph').getName()); //Ralph console.log(Person('Ralph').getName()); //Ralph 缺点: 编码相对较为复杂,需要_Person作为辅助的内部构造函数,且需要手动修改prototype和constructor等属性 3. 利用instanceof操作符 function Person(name) { // 如果使用了new,this指向新生成的Person实例 // 如果直接调用Person没有使用new,这里的this指向window对象 if (!(this instanceof Person)) { return new Person(name); } this.name = name; } Person.prototype.getName = function () { return this.name; }; console.log(new Person('Ralph').getName()); //Ralph console.log(Person('Ralph').getName()); //Ralph 缺点: 在判断this instanceof Person时需要指明构造函数名称Person,抽象程度不够高,修改构造函数名称时需要手动修改该语句 4. 利用callee属性和constructor属性 function Person(name) { // arguments.callee指向Person函数 // this.constructor仅在使用了new的情形下指向Person函数 if (arguments.callee !== this.constructor) { return new arguments.callee(name); } this.name = name; } Person.prototype.getName = function () { return this.name; }; console.log(new Person('Ralph').getName()); //Ralph console.log(Person('Ralph').getName()); //Ralph 缺点: strict模式下无法使用callee属性 ![]() (编辑:开发网_开封站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |



浙公网安备 33038102330459号