JS使构造函数与new操作符无关
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操作符无关的更多相关文章
- [Effective JavaScript 笔记]第33条:使构造函数与new操作符无关
当使用函数作为一个构造函数时,程序依赖于调用者是否记得使用new操作符来调用该构造函数.注意:该函数假设接收者是一个全新的对象. 一个例子 function User(name,pwd){ this. ...
- JS中构造函数和普通函数有什么区别
JS中构造函数有普通函数有什么区别? 1.一般规则 构造函数都应该以 一个大写字母开头,eg: function Person(){...} 而非构造函数则应该以一个小写字母开头,eg: functi ...
- js 时间构造函数
js 时间构造函数,js中没有类似ToString("yyyy-mm-dd HH:mm:ss") 的方法,但是可以用下面的方式来初始化 var cdate = new Date(& ...
- C++学习基础六——复制构造函数和赋值操作符
1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作 ...
- C++中复制构造函数和赋值操作符
先看一个例子: 定义了一个类:
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
一.本文目的与说明 1. 本文目的:理清在各种继承时,构造函数.复制构造函数.赋值操作符.析构函数的执行顺序和执行内容. 2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是也具有一定的 ...
- js高级——构造函数,实例对象和原型对象——prototype、__proto__和constructor构造器
一.前言 了解JavaScript面向对象,需要先了解三个名词: 构造函数,实例对象和原型对象. 注意:JavaScript中没有类(class)的概念,取而代之的是构造函数,两者类似却又有很大的差别 ...
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- JS基础——构造函数VS原型
JS是一种基于对象的语言.在使用过程中不免遇到复制对象的问题.但通常我们採用的直接赋值'obj1=obj2'这样的做法会出现数据覆盖问题. 也就是对象引用过程中引用地址一致.导致对象数据被改动的问题. ...
随机推荐
- 小试ildasm,ilasm,ilspy
选择了微耕的软件(为什么选择它,因为微耕的二次开发实在太牛了,只给文档,一切技术问题都不回答.文档也是只公开基本的东西) 第一个功能:换文字 第二个功能:插入一个新的程序集,在做某些事情前先做我想做的 ...
- 0. CMMI快乐之旅——内容简介及目录
摘要: 这是我几年前发表于 www.cmmionline.net 网站(现在升级为www.umlonline.org 网站)数十篇文章,全方位分享了我对CMMI的理解,现我打算整理这些文章陆续在CSD ...
- 用户故事地图(User Story Mapping)之初体验
北京这几日的天儿真是好的出奇,白天风和日丽,晚上繁星漫天:在这样一个周六的下午,小编参加了一次北京敏捷社区(微信号:Agile1001)组织的活动:<用户故事地图User Story Mappi ...
- BootStrap入门教程 (一)
BootStrap入门教程 (一) 2011年,twitter的"一小撮"工程师为了提高他们内部的分析和管理能力,用业余时间为他们的产品构建了一套易用.优雅.灵活.可扩展的前端 ...
- 预定义接口-迭代器Iterator
<?php /* 可在内部迭代自己的外部迭代器或类的接口. Iterator extends Traversable { abstract public mixed current ( void ...
- python抓取网页中图片并保存到本地
#-*-coding:utf-8-*- import os import uuid import urllib2 import cookielib '''获取文件后缀名''' def get_file ...
- https协议了解,以及相关协议的解析
HTTPS简介 HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版. ...
- hdu 5057 Argestes and Sequence(分块算法)
Argestes and Sequence Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HowTo: Linux Server Change OR Setup The Timezone
Method 1 #tzselect # select timezone e.g. Asia/Shanghai#echo 'Asia/Shanghai' > /etc/timezone # se ...
- MySQL Database on Azure 的用户名
MySQL Database on Azure是中国版Windows Azure上的一个PaaS服务,类似于AWS上的RDS.MySQL Database on Azure的用户名与on-premis ...