zoukankan      html  css  js  c++  java
  • 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标准,所以不建议使用。

  • 相关阅读:
    基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布
    jeecg-boot 简易部署方案
    JeecgBoot版本4月份新版即将发布,抢先体验。。
    Jeecg-Boot 1.0版本发布,企业级快速开发平台
    jeecg之弹窗插件lhgdialog小结
    JEECG 集成KiSSO单点登录实现统一身份认证
    sass
    http1.1管线话 vs htttp2.0 多路复用
    http 状态码
    http参考
  • 原文地址:https://www.cnblogs.com/Bryran/p/3969107.html
Copyright © 2011-2022 走看看