[转]JavaScript作用域安全构造函数
构造函数其实就是一个使用new操作符调用的函数。当使用new调用时,构造函数内用到的this对象会对指向新创建的对象实例,如下的例子所示:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
var person =("Nicholas",29,"Software Engineer");
上面这个例子中,Person构造函数使用this对象给三个属性赋值:name、age和job。当和new操作符连用时,则会创建一个新的Person对象,同事会给它分配这些属性。问题在当没有使用new操作符来调用构造函数的情况时。由于该this对象是在运行时绑定的,所以直接调用Person(),this会映射到全局对象window上,导致错误对象属性的意外增加。例如:
var person =Person("Nicholas",29,"Software Engineer");
alert(window.name);//"Nicholas"
alert(window.age);//
alert(window.job);//"Software Engineer"
这里,原本针对Person实例的三个属性被加到window对象上,因为构造函数是作为普通函数调用的,忽略了new操作符。这个问题是由this对象的晚绑定造成的,在这里this呗解析成了window对象。由于window的name属性是用于识别链接目标和框架的,所以这里对该属性的偶然覆盖可能会导致该页面上出现其它错误。这个问题的解决方法就是创建一个作用域安全的构造函数。
作用域安全的构造函数在进行任何更改前,首先确认this对象是正确类型的实例。如果不是,那么会创建新的实例并返回。请看下面的例子:
function Person(name, age, job){
if(this instanceof Person){
this.name = name;
this.age = age;
this.job = job;
}else{
return new Person(name, age, job);
}
}
var person1 =Person("Nicholas",29,"Software Engineer");
alert(window.name);//""
alert(person1.name);//"Nicholas"
var person2 =new Person("Shelby",34,"Ergonomist");
alert(person2.name);//"Shelby"
这段代码中的Person构造函数添加了一个检查并确保this对象是Person实例的if语句,它表示要么使用new操作符,要么在现有的Person实例环境中调用构造函数。任何一种情况下,对象初始化都能正常进行。如果this并非Person实例环境中调用构造函数。任何一种情况下,对象初始化都能正常进行。如果this并非Person的实例,那么会再次使用new操作符调用构造函数并返回结果。最后的结果是,调用Person构造函数时无论是否使用new操作符,都会返回一个Person的新实例,这就避免了在全局对象上意外设置属性。
[转]JavaScript作用域安全构造函数的更多相关文章
- javascript --- 设计模式之构造函数模式
在JavaScript里,构造函数通常是认为用来实现实例的,JavaScript没有类的概念,但是有特殊的构造函数.通过new关键字来调用定义的否早函数,你可以告诉JavaScript你要创建一个新对 ...
- ife task0003学习笔记(一):JavaScript作用域
在学习JavaScript作用域概念之前,首先要明白几个概念:执行环境.变量对象.作用域链. 一.JavaScript执行环境(execution context): 在<Professiona ...
- JavaScript作用域
JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...
- 关于Javascript作用域及作用域链的总结
本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...
- JavaScript作用域链
之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...
- [译] 你该知道的javascript作用域 (javascript scope)(转)
javascript有一些对于初学者甚至是有经验的开发者都难以理解的概念. 这个部分是针对那些听到 : 作用域, 闭包, this, 命名空间, 函数作用域, 函数作用域, 全局作用域, 变量作用域( ...
- Python自动化 【第十六篇】:JavaScript作用域和Dom收尾
本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...
- 深入理解javascript作用域系列第一篇——内部原理
× 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...
- 深入理解javascript作用域系列第二篇——词法作用域和动态作用域
× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...
随机推荐
- vnc执行,报xauth could not run
/usr/bin/gnome-terminal [INFO-10%]生成随机密码 [INFO-20%]生成密码文件 [INFO-30%]完成初始化,准备打开连接 Error: could not ru ...
- PO > Create PO时关于汇率问题需要注意的步骤
为了使得RMB采购的PO在审核时不会提示汇率丢失(如下图),在创建PO时需要注意几个步骤. 1)手动创建PO:在建立PO行之前,应该选择好正确的"地点","币 ...
- java里的静态变量是放在了堆内存还是栈内存?
堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对 ...
- POJ_3185_The_Water_Bowls_(反转)
描述 http://poj.org/problem?id=3185 20个碗,要全部反转过来.反转某个碗,其相邻的碗(左右两边)也要反转. The Water Bowls Time Limit: 10 ...
- windows安装PHP5.4.8+Apache2.4.3+Mysql5.5.28
最近听说PHP5.4速度很快,所以想建立一个本地环境测试下.我打算用本地windows xp sp3下安装PHP5.4.8.Apache2.4.3和Mysql5.5.28. 首先去下载PHP.Apac ...
- DNS----域名解析系统
DNS就是域名解析系统,它可以将IP转换成域名,也可以将域名转换成IP 1. 安装DNS服务 开始—〉设置—〉控制面板—〉添加/删除程序—〉添加/删除Windows组件—〉“网络服务”—〉 ...
- WinForm触摸屏程序功能界面长时间不操作自动关闭回到主界面 z
操作者经常会在执行了某操作后,没有返还主界面就结束了操作然后离开了,程序应该关闭功能窗体自动回到主界面方便下一位操作者操作.那么对于WinForm程序怎么实现呢? 实现原理:拦截Application ...
- 测试一个函数的运行时间(C++)
#include <ctime> static clock_t Start,Finish; Start=clock(); fun(); Finish = clock(); double t ...
- Storm系列(十七)DRPC介绍
Storm版本0.9.5 在storm中DRPC服务应用于远程分布式计算,根据客户端提交的请求参数,而返回Storm计算的结果. DRPC服务启动流程(远程模式) 启动DRPC服务,启动命令:stor ...
- hadoop部署小结的命令
hadoop部署总结的命令 学习笔记,转自:hadoop部署总结的命令http://www.aboutyun.com/thread-5385-1-1.html(出处: about云开发)