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. ASP.NET中使用Entity Framework开发登陆注册Demo

    这里更多的是当作随身笔记使用,记录一下学到的知识,以便淡忘的时候能快速回顾 当前步骤是该项目的第一部分 第一部分(当前) 第二部分 大完结版本 直接上步骤,有类似的开发登陆注册也可以参考. 登陆注册的 ...

  2. Java实现 蓝桥杯VIP 算法训练 采油区域

    算法训练 采油区域 时间限制:2.0s 内存限制:512.0MB 提交此题 查看参考代码 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整 ...

  3. Java实现 LeetCode 155 最小栈

    155. 最小栈 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) – 将元素 x 推入栈中. pop() – 删除栈顶的元素. top() – 获取 ...

  4. Java实现 LeetCode 99 恢复二叉搜索树

    99. 恢复二叉搜索树 二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2 输出: [3,1,nu ...

  5. Java实现 洛谷 P1579 哥德巴赫猜想(升级版)

    题目背景 1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和.质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是 ...

  6. java实现不连续处断开

    不连续处断开 下列代码运行结果为: 12345 23456 89 23456789 即把一个串从数字不连续的位置断开.试完善之. String s = "123452345689234567 ...

  7. java代码(5) ---guava之Multiset

    guava之Multiset  一.概述 Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关,Multiset继承于JDK的Collection接口,而不是Se ...

  8. NumPy之计算两个矩阵的成对平方欧氏距离

    问题描述 设 \({X_{m \times k}} = \left[ {\vec x_1^T;\vec x_2^T; \cdots ;\vec x_m^T} \right]\) (; 表示纵向连接) ...

  9. 用mvc框架查询数据库数据

    介绍下mvc框架,mvc框架一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑. 首先我们 ...

  10. linux中c多线程同步方法

    https://blog.csdn.net/jkx01whg/article/details/78119189 Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥 ...