JavaScript基础有关构造函数、new关键字和this关键字(009)
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)的更多相关文章
- JavaScript基础
JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...
- Javascript基础回顾 之(一) 类型
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- JavaScript 基础回顾——对象
JavaScript是基于对象的解释性语言,全部数据都是对象.在 JavaScript 中并没有 class 的概念,但是可以通过对象和类的模拟来实现面向对象编程. 1.对象 在JavaScript中 ...
- javascript基础部分
javascript基础部分 1 数据类型: 基础数据类型(通过typeof来检测):Number,string,undefined,null,boolean,function typeof只能检测 ...
- javascript基础语法——表达式
× 目录 [1]原始表达式 [2]复杂表达式 前面的话 一般地,关于javascript基础语法,人们听得比较多的术语是操作符和语句.但是,其实还有一个术语经常使用,却很少被提到,这就是javascr ...
- 【javascript基础】2、函数
前言 我在上一篇[javascript基础]基本概念中介绍了javascript的一些基本概念,多谢大家的阅读和意见,自己写的东西可以被大家阅读,真心高兴,刚开始发布的时候我一直盯着阅读人数,虽然知道 ...
- JavaScript基础知识(一)
一.JavaScript基础 1.JavaScript用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 ...
- javascript基础修炼(2)——What's this(上)
目录 一.this是什么 二.近距离看this 三. this的一般指向规则 四. 基本规则示例 五. 后记 开发者的javascript造诣取决于对[动态]和[异步]这两个词的理解水平. 一.thi ...
- JavaScript基础视频教程总结(061-070章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
随机推荐
- Redis 入门到分布式 (四) 瑞士军刀Redis其他功能
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 目录: 慢查询 Pipeline 发布订阅 Bitmap(位图) HyperLogLog GEO 一.慢 ...
- Java实现 蓝桥杯 算法提高金属采集
问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连,所有的节点和道路形成了一棵树.一共有 n 个节点,这些节点被编号为 1~n .人类将 ...
- JVM中堆的介绍
一.堆的概述 一个JVM实例只有一个堆内存,堆也是Java内存管理的核心区域,堆在JVM启动的时候创建,其空间大小也被创建,是JVM中最大的一块内存空间,所有线程共享Java堆,物理上不连续的逻辑上连 ...
- 【大厂面试07期】说一说你对synchronized锁的理解?
synchronized锁的原理也是大厂面试中经常会涉及的问题,本文主要通过对以下问题进行分析讲解,来帮助大家理解synchronized锁的原理. 1.synchronized锁是什么?锁的对象是什 ...
- 移动端响应式布局,rem动态更新
(function(){ var fontSizeMatchDeviceWidth = function(){ var deviceWidth = document.documentElement.c ...
- 安装并配置Samba
1. 安装 samba ~$sudo apt-get install samba 2. 修改 samba 的配置文件 ~$sudo gedit /etc/samba/smb.conf 添加如下内容 [ ...
- Nginx思维导图
1. Nginx简介 1.1 nginx概述 1.2 nginx的安装及程序环境 1.3 零复制&五种IO模型 1.4 nginx的基本配置 2. Nginx配置详解 2.1 main配置段详 ...
- Tournament Chart【模拟+vector+map+string】
Tournament Chart 传送门:链接 来源:UPC10889 题目描述 In 21XX, an annual programming contest, Japan Algorithmist ...
- TensorFlow从0到1之TensorFlow超参数及其调整(24)
正如你目前所看到的,神经网络的性能非常依赖超参数.因此,了解这些参数如何影响网络变得至关重要. 常见的超参数是学习率.正则化器.正则化系数.隐藏层的维数.初始权重值,甚至选择什么样的优化器优化权重和偏 ...
- springboot整合Mybatis(有xml)
pom.xml <!-- mybatis 支持 SpringBoot --> <dependency> <groupId>org.mybatis.spring.bo ...