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'这样的做法会出现数据覆盖问题. 也就是对象引用过程中引用地址一致.导致对象数据被改动的问题. ...
随机推荐
- .NET读写Excel工具Spire.XlS使用(DataExport )
Introduction E-ICEBLUE is developing office.net component, the main products include Spire.Doc, Spir ...
- E-R图的基础练习
第1题: 设有商店和顾客两个实体,“商店”有属性:商店编号.商店名.地址.电话,“顾客”有属性:顾客编号.姓名.地址.年龄.性别.假设一个商店有多个顾客购物,一个顾客可以到多个商店购物,顾客每次去商店 ...
- yii过滤xss代码,防止sql注入
作者:白狼 出处:www.manks.top/article/yii2_filter_xss_code_or_safe_to_database 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明 ...
- 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...
- 在JazzyViewPager中调用其它layout布局xml并使用
开源地址:https://github.com/jfeinstein10/JazzyViewPager 发现网上的例子使用的是直接创建的一个TextView来做的.但是实际上使用,不可能只有这一个控件 ...
- Altium Desiner 警告 adding hidden net
这是因为 一些元件 隐藏了 vcc GND 或者没有使用vcc GND ,用不着它也报警告了. 这里可以将 vcc GND删掉这个管脚.
- 新手必学的java报表开发工具FineReport实用技巧
1.在制作模板时,如何将报表中的值传递到超链接网页呢? 在项目中以frame方法把F1.CPT放到项目的页面中,对F1.CPT做网络报表超链接F2.CPT,然后在F2.cpt页面中,做个超链接的网页, ...
- KVM 介绍(1):简介及安装
学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...
- 学习OpenStack之 (3):Devstack Screen 使用技巧
Devstack环境中,openstack运行在一个screen中,每个service运行在一个window中.我总结的几个tips: 0. 注意需要使用screen启动用户来进行一下操作 1. 查看 ...
- 浅析Java中的访问权限控制
浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...