1. 总是记得用new关键字来执行构造函数。
前面提到,可以用构造函数创建JavaScript的对象,这个构造函数在使用的时候需要使用new关键字,但如果忘记写入new关键字,会怎么样?事实上这个函数还是会被执行的,没有语法错误,但有逻辑错误。因此如果没有用new关键字,函数里的this指针将不会被存放新的对象的引用,实际存入是的全局对象。如果你在网页里执行代码,这个this就是window。比如,这个时候,构造函数里的this.member指向的就是window.member。如果在全局对象window里没有定义这个member属性,这个属性将会被隐式的声明!这有可能会捅出个大篓子:

// constructor
function Waffle() {
this.tastes = "yummy";
} // a new object
var good_morning = new Waffle();
console.log(typeof good_morning); // "object"
console.log(good_morning.tastes); // "yummy" // antipattern:
// forgotten `new`
var good_morning = Waffle();
console.log(typeof good_morning); // "undefined"
console.log(window.tastes); // "yummy"

这就是为什么我们应该让构造函数的首字母大写,让人一看就知道它是个构造函数。因为它如果不用new关键字执行,是会出问题的。

2. 在构造函数中别用this,用that
既然在构造函数中用了this会有隐患,那么我们可以别用this,改用that。当然,that不是个关键字。所以构造函数会变成这个样子:

function Waffle() {
var that = {};
that.tastes = "yummy";
return that;
}

这看起来有点奇怪,不过的确能提高代码的安全性。如果需要构造的对象足够简单,也可以直接return一个Literal的对象:

function Waffle() {
return {
tastes: "yummy"
};
}

使用这种方法写出的构造函数,总是能返回一个我们需要的对象,不管它是如果被调用的:

var first = new Waffle(),
second = Waffle();
console.log(first.tastes); // "yummy"
console.log(second.tastes); // "yummy"

这种模式的最大问题是,新建的对象与Waffle对象的原型之间的关系丢失了,而通过Waffle的原型加入通用方法将不能奏效。如果要保证新对象和Waffle原型之间的关系,可以使用instanceof做个判断,然后再决定如何创建对象:

function Waffle() {
if (!(this instanceof Waffle)) {
return new Waffle();
}
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true; // testing invocations
var first = new Waffle(),
second = Waffle();
console.log(first.tastes); // "yummy"
console.log(second.tastes); // "yummy"
console.log(first.wantAnother); // true
console.log(second.wantAnother); // true

还有一种通用的方法可以检查调用构造函数的方式 ,就是通过arguments.callee来判断:

if (!(this instanceof arguments.callee)) {
return new arguments.callee();
}

这种方法的原理是,所有的函数对象中,都有一个arguments的成员对象,arguments的其中一个属性叫callee,它指向这个函数的调用者。但这种方法并不适用过严格的JavaScript标准,所以不建议使用。

JavaScript基础有关构造函数、new关键字和this关键字(009)的更多相关文章

  1. JavaScript基础

    JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...

  2. Javascript基础回顾 之(一) 类型

    本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...

  3. JavaScript 基础回顾——对象

    JavaScript是基于对象的解释性语言,全部数据都是对象.在 JavaScript 中并没有 class 的概念,但是可以通过对象和类的模拟来实现面向对象编程. 1.对象 在JavaScript中 ...

  4. javascript基础部分

    javascript基础部分 1  数据类型: 基础数据类型(通过typeof来检测):Number,string,undefined,null,boolean,function typeof只能检测 ...

  5. javascript基础语法——表达式

    × 目录 [1]原始表达式 [2]复杂表达式 前面的话 一般地,关于javascript基础语法,人们听得比较多的术语是操作符和语句.但是,其实还有一个术语经常使用,却很少被提到,这就是javascr ...

  6. 【javascript基础】2、函数

    前言 我在上一篇[javascript基础]基本概念中介绍了javascript的一些基本概念,多谢大家的阅读和意见,自己写的东西可以被大家阅读,真心高兴,刚开始发布的时候我一直盯着阅读人数,虽然知道 ...

  7. JavaScript基础知识(一)

    一.JavaScript基础 1.JavaScript用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 ...

  8. javascript基础修炼(2)——What's this(上)

    目录 一.this是什么 二.近距离看this 三. this的一般指向规则 四. 基本规则示例 五. 后记 开发者的javascript造诣取决于对[动态]和[异步]这两个词的理解水平. 一.thi ...

  9. JavaScript基础视频教程总结(061-070章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

随机推荐

  1. Linux (八)服务

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.服务的概念 操作系统中在后台持续运行的程序,本身并没有操作界面,需要通过端口号访问和操作.CentO ...

  2. (Java实现) 拦截导弹

    1260:[例9.4]拦截导弹(Noip1999) 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4063 通过数: 1477 [题目描述] 某国为了防御敌国的导弹袭击,发展出一 ...

  3. java实现 洛谷 P1540 机器

    import java.util.LinkedList; import java.util.Scanner; public class Main { private static Scanner ci ...

  4. 自己动手写SQL执行引擎

    自己动手写SQL执行引擎 前言 在阅读了大量关于数据库的资料后,笔者情不自禁产生了一个造数据库轮子的想法.来验证一下自己对于数据库底层原理的掌握是否牢靠.在笔者的github中给这个database起 ...

  5. 简单说维特比算法 - python实现

    动态规划求最短路径算法,与穷举法相比优点在于大大降低了时间复杂度; 假如从起点A到终点S的最短路径Road经过点B1,那么从起点A到B1的最短路径的终点就是B1,否则如果存在一个B2使得A到B2的距离 ...

  6. Markdown 主题修改

    加粗字体的颜色修改 strong, b{ color: #111111; } 斜体的颜色修改 em, i { color: #111111; } 高亮字体的背景颜色修改 #write mark { b ...

  7. SpringBoot设置mysql的ssl连接

    因工作需要,mysql连接需要开启ssl认证,本文主要讲述客户端如何配置ssl连接. 开发环境信息: SpringBoot: 2.0.5.RELEASE mysql-connector-java: 8 ...

  8. 利用Jackson将数据转换为Json

    1.确保相关依赖导入 2.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app ...

  9. PageHelper支持GreenPlum

    greenplum是pivotal在postgresql的基础上修改的一个数据库,语法和postgresql通用.使用PageHelper做分页插件的时候,发现目前没有针对greenplum做支持,但 ...

  10. cb21a_c++_string对象的比较

    *cb21a_c++_string对象的比较s.compare(s2)--区分大小的s.compare(pos1,n1,s2)s.compare(pos1,n1,s2,pos2,n2)s.compar ...