• 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标准,所以不建议使用。

  • 相关阅读:
    TSINGSEE青犀视频构建pion webrtc运行broadcast示例步骤
    当WebRTC Pion示例无音频流的时候,如何添加音频模块并通过浏览器播放?
    TSINGSEE青犀视频编译EasyPlayer项目H265播放器通过webpack合并报错ERROR in EasyPlayer-element.min.js的处理办法
    EasyDarwin编译全过程:Linux系统下编译运行最新版本EasyDarwin步骤介绍
    (转载)C#压缩解压zip 文件
    Angularjs 学习笔记-2017-02-06-双向数据绑定
    Angularjs 学习笔记-2017-02-05-初识Angular及app、model、controller、repeat指令和fileter、orderBy
    KnocoutJs+Mvc+BootStrap 学习笔记(Mvc)
    Visual stuio2015 升级 Update 3+安装.Net Core 安装包之后,无法创建Mvc项目
    Sqlserver2014 Master....提示异常,IIS未安装
  • 原文地址:https://www.cnblogs.com/Bryran/p/3969107.html
Copyright © 2020-2023  润新知