美文网首页程序员让前端飞
作用域安全的构造函数。

作用域安全的构造函数。

作者: 黄清淮 | 来源:发表于2017-03-02 15:15 被阅读0次

构造函数的作用域还有安全这么一说。很多人估计都不知道,下面通过一个例子来说明,什么是作用域不安全的构造函数。

//大众化的造人函数
function Person(name,age,sex){
  this.name = name;
  this.age = age;
  this.sex = sex;
}
var xiaoming = new Person("小明","20","boy"); //造了个小明 这样做是不会有问题的
var kangkang = Person("康康","21","boy"); //这样写就会出问题了 大问题
console.log(this.name); //康康

以上代码的输出在部分人看来或许是没错啊 构造函数中把name的值赋给this了。控制台输出的也是之前赋的值。但是,请注意这边的this并不是 kangkang 这个新的对象 而是 window 对象 相当于把要给新对象的属性值 加到了全局对象上了。导致了新建的对象在取属性值时报错,而且在全局对象上新增了属性(方法)造成了污染。


以上说了那么多,就是想说像上面第二种方法实例化对象的时候,由于没有new关键字,导致操作的this并不是新的实例而是全局对象,从而可能引起页面的问题。如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)
以下是处理的办法

//还是那个造人函数
function Person(name,age,sex){
  if (this instanceof Person){
    this.name = name;
    this.age = age;
    this.sex = sex;
  }else{
    return new Person(name, age, job);
  }
}
var xiaoming = new Person("小明","20","boy"); //造了个小明 这样做是不会有问题的
var kangkang = Person("康康","21","boy"); //这样写就会出问题了 大问题
console.log(this.name); //undefined

如此就能确保不管有没有 new 关键字都能正确的生成我们想要的对象实例。
当然以上修改后一定程度上解决了以上的问题。但是,若使用了构造函数窃取模式(个人理解:构造函数B中用call调用A构造函数 想使B中的this 带有A构造函数中的属性或方法)的继承且不使用原型链,那么就可能会破坏这个继承。

//还是那个造人函数
function Person(name,age,sex){
  if (this instanceof Person){
    this.name = name;
    this.age = age;
    this.sex = sex;
  }else{
    return new Person(name, age, job);
  }
}

function Programmer(skill){
  Person.call(this,"xiaoming","20","boy");
  this.skill = skill;
}
var xiaoming = new Programmer("java"); //造了个会java的小明
console.log(xiaoming .name); //undefined

相信很多人都找到了问题的关键所在。在实例化时由于this继承的并不是 Person 所以用 call 调用的时候 返回的对象是新的 Person对象(执行else里面的) this也是新的实例的 而不是属于Programmer构造函数中的this,新生成的Programmer实例并没有得到增长 call 调用后返回的值也没用到 所以得到的值会是undefined;
若使用原型链就可以解决上面的问题了。

......省略上面的两个构造函数
Programmer.prototype = new Person()//  ******这里的代码是关键******
//以上代码会使一个Programmer实例同时也是Person的实例。this就能通过if判断
var xiaoming = new Programmer("java"); //造了个会java的小明
console.log(xiaoming .name); //xiaoming

作用域安全的构造函数在很多看来并没多少用处,但是为了避免造成一些难以追踪的问题,特别是在多人协同编写功能的情况下,还是推荐使用作用域安全的构造函数。

2017.03.02

相关文章

  • 谈谈js中的高级函数

    1.作用域不安全的构造函数 如下: 作用域安全的构造函数会,然后再进行更改,如下: 实现这个安全模式,相当于锁定了...

  • 作用域安全的构造函数

    作用域安全的构造函数 构造函数(非new操作)在构造函数中,使用new操作符的时候,函数的内部this指向创建的新...

  • 作用域安全的构造函数。

    构造函数的作用域还有安全这么一说。很多人估计都不知道,下面通过一个例子来说明,什么是作用域不安全的构造函数。 以上...

  • JS高级函数

    高级函数 在 JavaScript 中使用函数的高级方法。 数据类型的安全检测 构造函数的安全作用域 惰性载入函数...

  • 构造函数 作用域安全

    非new调用Person时,防止this绑定到全局变量window上,引起数据覆盖和污染。 注意:安全作用域函数在...

  • JS高程:读书摘要(十八)高级技巧

    一、高级函数 安全类型检测 作用域安全的构造函数 如果使用上述写法,当你借用构造函数来实现继承的时候,会被破坏。P...

  • 作用域安全的构造函数

    当被new调用时,设置name属性;不能不是new调用,而是普通函数调用,则以new递归调用自己来为对象创建正确的实例

  • 作用域安全的构造函数

  • 第二十二章 高级技巧

    1. 作用域安全的构造函数:在进行任何更改前,首先确认this对象是正确类型的实例(锁定可以使用构造函数的环境,避...

  • C++作用域解析符号 ::

    作用域解析符号,用于标志函数或变量的作用域,如上代码所示,该构造函数属于Myclass域下,明确标出所属。...

网友评论

    本文标题:作用域安全的构造函数。

    本文链接:https://www.haomeiwen.com/subject/cdnhgttx.html