function User(name, passwordHash) {
this.name = name;
this.passwordHash = passwordHash;
}

当使用User函数创建一个构造函数时,程序依赖于调用者是否记得使用new操作符来调用该构造函数。注意的是,该函数假设接收者是一个全新的对象。
如果调用者忘记使用new关键字,那么函数的接收者将是全局对象。

// undefined
var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');

该函数不但会返回无意义的undefined,而且会灾难性地创建全局变量name和passwordHash。

如果将User函数定义为ES5的严格代码,那么接收者默认认为是undefined

function User(name, passwordHash) {
'use strict'; // Cannot set property 'name' of undefined
this.name = name;
this.passwordHash = passwordHash;
} var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');

在这种情况下,这种错误的调用会导致一个即使错误:Cannot set property 'name' of undefined

一个更为健壮的方式是提供一个不管怎样调用都工作如构造函数的函数。实现这样的函数一个简单的方法是检查函数的接收者是否是一个正确的User实例。

// 检查函数的接受者是否是一个正确的User实例
// 缺点,不适应于可变参数函数
function User(name, passwordHash) {
if (!(this instanceof User)) {
return new User(name, passwordHash);
}
this.name = name;
this.passwordHash = passwordHash;
}
// User {name: "zhangsan", passwordHash: "djkgjk23lkl4332l3k289ds"}
var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');

这种模式的一个缺点是它需要额外的函数调用,而且不适应可变参数函数(因为没有直接模拟apply方法将可变参数函数作为构造函数调用的方法)。一种更为高效的方式是利用ES5的Object.create函数。

function User(name, passwordHash) {
var self = this instanceof User ? this : Object.create(User.prototype);
console.log(self);
self.name = name;
self.passwordHash = passwordHash;
return self;
}
// User {name: "zhangsan", passwordHash: "djkgjk23lkl4332l3k289ds"}
var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');

Object.create需要一个原型对象作为参数,并返回一个继承自该原型对象的新对象。

Object.create只有在ES5环境下才是有效的,这里提供了一个兼容版的。

if (typeof Object.create === 'undefined') {
Object.create = function(prototype) {
var C = function() {};
C.prototype = prototype;
return new C;
}
};

这里只实现了单参数版本的Object.create函数。

参考:编写高质量JavaScript代码的68个有效方法

JS使构造函数与new操作符无关的更多相关文章

  1. [Effective JavaScript 笔记]第33条:使构造函数与new操作符无关

    当使用函数作为一个构造函数时,程序依赖于调用者是否记得使用new操作符来调用该构造函数.注意:该函数假设接收者是一个全新的对象. 一个例子 function User(name,pwd){ this. ...

  2. JS中构造函数和普通函数有什么区别

    JS中构造函数有普通函数有什么区别? 1.一般规则 构造函数都应该以 一个大写字母开头,eg: function Person(){...} 而非构造函数则应该以一个小写字母开头,eg: functi ...

  3. js 时间构造函数

    js 时间构造函数,js中没有类似ToString("yyyy-mm-dd HH:mm:ss") 的方法,但是可以用下面的方式来初始化 var cdate = new Date(& ...

  4. C++学习基础六——复制构造函数和赋值操作符

    1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作 ...

  5. C++中复制构造函数和赋值操作符

    先看一个例子: 定义了一个类:

  6. C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

    一.本文目的与说明 1. 本文目的:理清在各种继承时,构造函数.复制构造函数.赋值操作符.析构函数的执行顺序和执行内容. 2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是也具有一定的 ...

  7. js高级——构造函数,实例对象和原型对象——prototype、__proto__和constructor构造器

    一.前言 了解JavaScript面向对象,需要先了解三个名词: 构造函数,实例对象和原型对象. 注意:JavaScript中没有类(class)的概念,取而代之的是构造函数,两者类似却又有很大的差别 ...

  8. [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符

    /* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...

  9. JS基础——构造函数VS原型

    JS是一种基于对象的语言.在使用过程中不免遇到复制对象的问题.但通常我们採用的直接赋值'obj1=obj2'这样的做法会出现数据覆盖问题. 也就是对象引用过程中引用地址一致.导致对象数据被改动的问题. ...

随机推荐

  1. Java调用webservice接口方法

                             java调用webservice接口   webservice的 发布一般都是使用WSDL(web service descriptive langu ...

  2. hadoop2.6分布式部署时 livenodes等于1的原因

    1.问题描述 在进行hadoop2.x版本的hdfs分布式部署时,遇到了一个奇怪的问题: 使用start-dfs.sh命令启动dfs之后,所有的datanode节点上均能看到datanode进程,然而 ...

  3. su认证失败&文件夹里打开终端的方法&atom安装

    很久没用笔记本上的ubuntu,用不顺手,比在公司调教了半年多的电脑差远了.一步一步来.先解决最不顺手的三件事 1.su认证失败. 新安装的ubuntu系统是无法切换到root账户的,得做一番修改 s ...

  4. linux cpu占有率居高不下 调试

    今天调试程序,使用top命令后,发现程序的cpu占有率很高,一直在99,这很可怕,所以来调试. 使用top命令,得如下结果 PID USER PR NI VIRT RES SHR S %CPU %ME ...

  5. 如何让django方法自动地定期执行

    实现思路:1.首先把需要自动执行的django method写成django command2.将自己定义的django command添加到cron中使用cron服务实现定期执行 Part1 在dj ...

  6. Eclipse和PyDev搭建完美Python开发环境(Windows篇)

    目录安装Pythonpython for eclipse插件安装配置PyDev插件测试 安装Python从网站上下载最新的版本,从http://python.org/download/下载.安装过程与 ...

  7. Mysql数据库笔记

    出错记录: 1.mysql服务启动不了,进程意外终止 1067    错误显示:can not connect to mysql server on local hosts(1061)    解决方法 ...

  8. 配置安装DVWA

    本文地址:http://www.cnblogs.com/go2bed/p/4162313.html —————————————————— 什么是DVWA? Damn Vulnerable Web Ap ...

  9. Assembly - Registers

    Processor operations mostly involve processing data. This data can be stored in memory and accessed ...

  10. STM32 DMA USART ADC

    转载自:http://www.cnblogs.com/UQYT/articles/2949794.html 这是一个综合的例子,演示了ADC模块.DMA模块和USART模块的基本使用. 我们在这里设置 ...