本系列作为EffectiveJavaScript的读书笔记。

在将function当做构造函数使用时,须要确保该函数是通过newkeyword进行调用的。

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

假设在调用上述构造函数时。忘记了使用newkeyword。那么:

var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
u; // undefined
this.name; // "baravelli"
this.passwordHash; // "d8b74df393528d51cd19980ae0aa028e"

能够发现得到的u是undefined。而this.name以及this.passwordHash则被赋了值。可是这里的this指向的则是全局对象。

假设将构造函数声明为依赖于strict模式:

function User(name, passwordHash) {"use strict";this.name = name;this.passwordHash = passwordHash;
}
var u = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
// error: this is undefined

那么在忘记使用newkeyword的时候,在调用this.name= name的时候会抛出TypeError错误。这是由于在strict模式下。this的默认指向会被设置为undefined而不是全局对象。

那么,是否有种方法可以保证在调用一个函数时,不管使用了newkeyword与否,该函数都可以被当做构造函数呢?以下的代码是一种实现方式。使用了instanceof操作:

function User(name, passwordHash) {if (!(this instanceof User)) {return new User(name, passwordHash);}this.name = name;this.passwordHash = passwordHash;
}var x = User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
var y = new User("baravelli", "d8b74df393528d51cd19980ae0aa028e");
x instanceof User; // true
y instanceof User; // true

以上的if代码块就是用来处理没有使用new进行调用的情况的。当没有使用new时。this的指向并非一个User的实例。而在使用了newkeyword时,this的指向是一个User类型的实例。

还有一个更加适合在ES5环境中使用的实现方式例如以下:

function User(name, passwordHash) {var self = this instanceof User ?

this : Object.create(User.prototype); self.name = name; self.passwordHash = passwordHash; return self; }

Object.create方法是ES5提供的方法。它可以接受一个对象作为新创建对象的prototype。

那么在非ES5环境中,就须要首先实现一个Object.create方法:

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

实际上,Object.create方法还有接受第二个參数的版本号,第二个參数表示的是在新创建对象上赋予的一系列属性。

当上述的函数确实使用了new进行调用时。也可以正确地得到返回的新建对象。这得益于构造器覆盖模式(Constructor Override Pattern)。该模式的含义是:使用了newkeyword的表达式的返回值可以被一个显式的return覆盖。

正如以上代码中使用了returnself来显式定义了返回值。

当然。以上的工作在某些情况下也不是必要的。可是,当一个函数是须要被当做构造函数进行调用时,必须对它进行说明,使用文档是一种方式。将函数的命名使用首字母大写的方式也是一种方式(基于JavaScript语言的一些约定俗成)。

总结:

  1. 使用Object.create来保证一个函数确实是被当做一个构造函数进行调用的,不管newkeyword是否被使用了。
  2. 对于作为构造函数的函数。在文档中指明这一点来保证其它用户可以正确的使用它。

Effective JavaScript Item 33 让构造函数不再依赖newkeyword相关推荐

  1. Effective JavaScript Item 40 避免继承标准类型

    本系列作为Effective JavaScript的读书笔记. ECMAScript标准库不大.可是提供了一些重要的类型如Array,Function和Date.在一些场合下.你或许会考虑继承当中的某 ...

  2. Effective JavaScript Item 37 认识this的隐式指向

    本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...

  3. Effective JavaScript Item 23 永远不要修改arguments对象

    本系列作为Effective JavaScript的读书笔记. arguments对象只是一个类似数组的对象,但是它并没有数组对象提供的方法,比如shift,push等.因此调用诸如:argument ...

  4. JavaScript高级笔记_002_构造函数和原型

    JavaScript高级笔记_002_构造函数和原型 构造函数和原型 构造函数和原型 概述 构造函数 构造函数的问题 构造函数原型`prototype` 对象原型`__proto__` (四个下划线) ...

  5. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  6. jquery 替换括号里面内容_【推荐】前端框架 Bootstrap 5.0 alpha 发布,不再依赖 jQuery...

    来源:https://www.oschina.net/news/116540/bootstrap-5-0-alpha-released Bootstrap 团队发布了 Bootstrap 5 的 Al ...

  7. Effective C# 原则33:限制类型的访问(译)

    Effective C# 原则33:限制类型的访问 Item 33: Limit Visibility of Your Types 并不是所有的人都须要知道所有的事.也不是所有的类型须要是公共的.对于 ...

  8. 当我不再依赖你的时候说说_「精选」关于依赖一个人的说说()-说说控

    摘要: 关于依赖一个人的说说 1.不要过份依赖友谊.或者花很多心思去猜度身边的人对你是否真心.一个人生活不会死.体会孤单是成长必修课.谁都要经历.人生路漫长.如果有一段实在 来自说说控粉丝张筱萱的投稿 ...

  9. 【译】JavaScript 工厂函数 vs 构造函数

    译者:前端小智 原文:medium.com/@chamikakas- 当谈到JavaScript语言与其他编程语言相比时,你可能会听到一些令人困惑东西,其中之一是工厂函数和构造函数. 想优质文章请猛戳 ...

最新文章

  1. SAP PM入门系列27 - IW29 Display Notifications
  2. poj 3984
  3. 高德 Serverless 平台建设及实践
  4. 让设计模式在开始就拯救你的项目
  5. VTK:图表之ColorVerticesLookupTable
  6. mysql5.6开发版_mysql-tutorial/2.2.md at master · liuxiaoqiang/mysql-tutorial · GitHub
  7. ASP.NET MVC+Spring.net+Nhibernate+EasyUI+Jquery开发案例(1)
  8. 使用迭代器时如何避免ConcurrentModificationException
  9. 1190. 反转每对括号间的子串 golang反转字符串
  10. .htaccess防盗链方法
  11. syncthing下载_Syncthing中继服务器和发现服务器
  12. RHEL6.4上Samba/NFS服务器简单配置
  13. Linq 操作XML文件
  14. python+selenium自动创建随笔
  15. 一级造价工程师(安装)- 计量笔记
  16. win7计算机怎么录屏,win7电脑怎么录屏,什么电脑录屏软件好用?
  17. 【PC微信探秘】用易语言编写一个微信DLL注入器
  18. word另存为html行距,word文档如何设置行间距
  19. “手把手教你设计”—12个最佳手机APP界面设计教程
  20. ENVI学习总结(三)——图像几何校正

热门文章

  1. Eclipse中输入系统变量和运行参数
  2. CSharp关键字----using
  3. 大话设计模式学习心得2
  4. csu 1536 Bit String Reordering(模拟 bfs+状态压缩)
  5. 现代儿童亟待满足的八种需要
  6. MOCTF-Web-访问限制
  7. socket编程流程与函数(实用篇)
  8. JS原生封装时间函数 日期格式过滤
  9. echarts解决自适应图表被压缩问题
  10. 软件测试反例,基于模型检测多反例对软件进行调试