构造函数其实就是一个使用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作用域安全构造函数的更多相关文章

  1. javascript --- 设计模式之构造函数模式

    在JavaScript里,构造函数通常是认为用来实现实例的,JavaScript没有类的概念,但是有特殊的构造函数.通过new关键字来调用定义的否早函数,你可以告诉JavaScript你要创建一个新对 ...

  2. ife task0003学习笔记(一):JavaScript作用域

    在学习JavaScript作用域概念之前,首先要明白几个概念:执行环境.变量对象.作用域链. 一.JavaScript执行环境(execution context): 在<Professiona ...

  3. JavaScript作用域

    JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...

  4. 关于Javascript作用域及作用域链的总结

    本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...

  5. JavaScript作用域链

    之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...

  6. [译] 你该知道的javascript作用域 (javascript scope)(转)

    javascript有一些对于初学者甚至是有经验的开发者都难以理解的概念. 这个部分是针对那些听到 : 作用域, 闭包, this, 命名空间, 函数作用域, 函数作用域, 全局作用域, 变量作用域( ...

  7. Python自动化 【第十六篇】:JavaScript作用域和Dom收尾

    本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...

  8. 深入理解javascript作用域系列第一篇——内部原理

    × 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...

  9. 深入理解javascript作用域系列第二篇——词法作用域和动态作用域

    × 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...

随机推荐

  1. iOS上获得MAC地址

    很多时候我们都需要唯一来确定一台设备,苹果设备本来有个UDID号,可以实现这个目的.在iOS5.0以前,还有一个uniqueIdentifier的API用来获得这个number.不过iOS5之后,这个 ...

  2. Oracle中的阻塞锁SQL(阻塞在哪个数据上)

        SELECT (   '节点 '           || a.inst_id           || ' session '           || a.sid           || ...

  3. mapreduce: InputFormat详解 -- RecordReader篇

    InputFormat是MapReduce中一个很常用的概念,它在程序的运行中到底起到了什么作用呢? InputFormat其实是一个接口,包含了两个方法: public interface Inpu ...

  4. PICK定理模板

    PICK定理: S=I+O/2-1 S为多边形面积,I多边形内部的格点,O是多边形边上的格点 其中边上格点求法: 假设两个点A(x1,y1),B(x2,y2) 线段AB间格点个数为gcd(abs(x1 ...

  5. 关于开源框架GPUImage 的简单说明

    GPUImage是一个非常棒的图像处理的开源库,里面提供了非常非常多的滤镜效果来加工图片. 不过就是因为太多效果了,而且对于程序员来说,那么多效果并不清楚知道要用那一个.于是我就使用提供的默认值,加上 ...

  6. C# 获取ttf文件字体名称

    1.第一种方法 using System.Windows.Media; String fontFilePath = "PATH TO YOUR FONT"; GlyphTypefa ...

  7. 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 ...

  8. 一例胜千言,详谈SQL Sever数据库锁

    1 前言 数据库大并发操作要考虑死锁和锁的性能问题.看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一 ...

  9. LinkedList源码解析

    LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明.1.链表的概念链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和 ...

  10. linux下安装

    挂载 1.虚拟机里选择ios文件2.挂载光驱命令: cd / mount /mnt/cdrom/ cd /mnt/cdrom/ ls 卸载 cd /umount /mnt/cdrom/ 安装 XXX. ...