Javascript中实现不加new关键字的构造函数

一般而言,在Javascript中创建对象时需要使用关键字new,但是某些时候,开发者希望无论new关键字有没有被显式使用,构造函数都可以被正常调用,即构造函数同时还具备简单工厂的职能。Javascript的一个特性使得这样的实现变得可行:如果构造函数中返回了对象,无论有没有使用new关键字,最终返回的值都是函数return的值。

基于这点特性,本文介绍了四种实现方式,抛砖引玉,欢迎拍砖~

1. 在构造函数中返回对象字面量

 1 function Person(name) {
 2     return {
 3         name: name,
 4         getName: function () {
 5             return this.name;
 6         }
 7     };
 8 }
 9 console.log(new Person(‘Ralph‘).getName()); //Ralph
10 console.log(Person(‘Ralph‘).getName()); //Ralph

缺点:
不方便控制prototype属性,不利于高效扩展对象方法,instanceof操作符失效且constructor属性丢失

2. 在构造函数中使用内部函数构造对象

 1 function Person(name) {
 2     // lazy loading,在Person函数第一次被调用时初始化内部函数_Person
 3     if (!Person.inited) {
 4         Person._Person = function (name) {
 5             this.name = name;
 6         };
 7         // 可以利用prototype进行方法扩展
 8         Person._Person.prototype = {
 9             // 正常使用constructor属性
10             constructor: Person,
11             getName: function () {
12                 return this.name;
13             }
14         };
15         // 可以正常使用instanceof操作符
16         Person.prototype = Person._Person.prototype;
17         // 标记为已初始化
18         Person.inited = true;
19     }
20     return new Person._Person(name);
21 }
22 console.log(new Person(‘Ralph‘).getName()); //Ralph
23 console.log(Person(‘Ralph‘).getName()); //Ralph

缺点:
编码较为复杂,需要_Person作为辅助的内部构造函数,且需要手动修改prototype和constructor等属性

3. 利用instanceof操作符

 1 function Person(name) {
 2     // 如果使用了new,this指向新生成的Person实例
 3     // 如果直接调用Person没有使用new,这里的this指向window对象
 4     if (!(this instanceof Person)) {
 5         return new Person(name);
 6     }
 7     this.name = name;
 8 }
 9 Person.prototype.getName = function () {
10     return this.name;
11 };
12 console.log(new Person(‘Ralph‘).getName()); //Ralph
13 console.log(Person(‘Ralph‘).getName()); //Ralph

缺点:
在判断this instanceof Person时需要指明构造函数名称Person,不够抽象,修改构造函数名称时需要手动修改该语句

4. 利用callee属性和constructor属性

 1 function Person(name) {
 2     // arguments.callee指向Person函数
 3     // this.constructor仅在使用了new的情形下指向Person函数
 4     if (arguments.callee !== this.constructor) {
 5         return new Person(name);
 6     }
 7     this.name = name;
 8 }
 9 Person.prototype.getName = function () {
10     return this.name;
11 };
12 console.log(new Person(‘Ralph‘).getName()); //Ralph
13 console.log(Person(‘Ralph‘).getName()); //Ralph

缺点:
strict模式下无法使用callee属性

(全文完)

时间: 2025-01-11 08:43:29

Javascript中实现不加new关键字的构造函数的相关文章

JavaScript中的普通函数与构造函数比较

问题 什么是构造函数?构造函数与普通函数区别是什么?用new关键字的时候到底做了什么?构造函数有返回值怎么办?构造函数能当普通函数调用吗? thisthis永远指向当前正在被执行的函数或方法的owner.例如: 1 2 3 4 5 function test(){   console.log(this); } test(); //Window {top: Window, window: Window, location: Location, external: Object, chrome: O

如何在Javascript中利用封装这个特性

对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢? 我们会把现实中的一些事物抽象成一个Class并且把事物的属性(名词)作为Class的Property把事物的动作(动词)作为Class的methods.在面向对象的语言中(C#等)都会有一些关键字来修饰类或者属性(Private,public,protect),这些关键词描述了访问的权限,不多做解释.泗阳县民用航空局 我们来看看Javascript的易变的特性

译:理解并掌握 JavaScript 中 this 的用法

原文链接:http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ 文章描述:本文原文来自 Javascript.isSexy 这个网站.这篇文章和文中提到的另一篇文章解决了我一直以来对 this 和 apply, call, bind 这三个方法的困惑.我看过很多国内相关的技术文章,没有一篇能让我彻底理解这些概念的.因此我决定把它译过来,不要让更多的初学者像我一样在这个问题上纠结太长时

JavaScript中的构造函数

function Accom(){};    //创建一个构造函数 //创建两个对象 var house=new Accom(); var apartment=new Accom(); 通过构造函数创建的对象有一个属性constructor,这个属性指向创建该对象时所用的Javascript构造函数. house.constructor===Accom;  或者   house instanceof Accom;     //true JavaScript中的每个构造函数都有一个prototyp

Javascript中this关键字详解

原文出处:http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html Quiz 请看下面的代码,最后alert出来的是什么呢? 1 var name = "Bob"; 2 var nameObj ={ 3 name : "Tom", 4 showName : function(){ 5 alert(this.name); 6 }, 7 waitShowNa

Javascript中构造函数的返回值问题和new对象的过程

首先明确一点:javascript中构造函数是不需要有返回值的,这一点跟java很类似.可以认为构造函数和普通函数的最大差别就是:构造函数中没有return语句,普通函数可以有return语句:构造函数中会使用this关键字定义成员变量和成员方法,普通的函数不会使用this关键字定义成员变量和方法. function Person(name,sex) { this.name = name; this.sex = sex; // return 1; //return true; //return

JavaScript中以构造函数的方式调用函数

转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明.函数表达式或者函数构造器(见以前的随笔)等方式来构造函数对象.函数构造器和其它函数的区别在与它们的调用方式不同. 要以构造函数的方式调用函数,只需要在调用时在函数名称前加new 关键字,比如:function whatsMyContext(){ return this; }; 调用:new what

JavaScript中的this关键字

"this"关键字是JavaScript中广泛应用的一种特性,但它经常也是这门语言中最容易混淆和误解的特性."this"的实际意义是什么?它是如何求值的? 本文试图以清晰的方式澄清和解释这问题的答案. 有过其他编程经验的人对"this"关键字并不陌生,大部分时候当通过构造函数实例化一个类的实例时,它指新创建的对象.例如,如果我有一个类Boat(),其拥有一个moveBoat()方法,当在moveBoat方法中引用"this"的

JavaScript中this关键字的使用比较

JavaScript中this关键字的使用比较 this关键字在JavaScript中,用的不能说比较多,而是非常多.那么熟悉this关键字的各种用法则显得非常关键. this有时候就是我们经常说的上下文,这个东西的指代对象.它灵活多变,有时候你看它是对象,有时候是window宿主对象. 1.this指向宿主对象 function myWindow() { this.id = 1; // 等价于window.id = 1 console.log(this); // 这里的this就是window