• JS使构造函数与new操作符无关


    function User(name, passwordHash) {
        this.name = name;
        this.passwordHash = passwordHash;
    }
    

    当使用User函数创建一个构造函数时,程序依赖于调用者是否记得使用new操作符来调用该构造函数。注意的是,该函数假设接收者是一个全新的对象。
    如果调用者忘记使用new关键字,那么函数的接收者将是全局对象。

    // undefined
    var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');
    

    该函数不但会返回无意义的undefined,而且会灾难性地创建全局变量name和passwordHash。

    如果将User函数定义为ES5的严格代码,那么接收者默认认为是undefined

    function User(name, passwordHash) {
        'use strict';
    
        // Cannot set property 'name' of undefined
        this.name = name;
        this.passwordHash = passwordHash;
    }
    
    var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');
    

    在这种情况下,这种错误的调用会导致一个即使错误:Cannot set property 'name' of undefined

    一个更为健壮的方式是提供一个不管怎样调用都工作如构造函数的函数。实现这样的函数一个简单的方法是检查函数的接收者是否是一个正确的User实例。

    // 检查函数的接受者是否是一个正确的User实例
    // 缺点,不适应于可变参数函数
    function User(name, passwordHash) {
        if (!(this instanceof User)) {
            return new User(name, passwordHash);
        }
        this.name = name;
        this.passwordHash = passwordHash;
    }
    // User {name: "zhangsan", passwordHash: "djkgjk23lkl4332l3k289ds"} 
    var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');
    

    这种模式的一个缺点是它需要额外的函数调用,而且不适应可变参数函数(因为没有直接模拟apply方法将可变参数函数作为构造函数调用的方法)。一种更为高效的方式是利用ES5的Object.create函数。

    function User(name, passwordHash) {
        var self = this instanceof User ? this : Object.create(User.prototype);
        console.log(self);
        self.name = name;
        self.passwordHash = passwordHash;
        return self;
    }
    // User {name: "zhangsan", passwordHash: "djkgjk23lkl4332l3k289ds"} 
    var u = User('zhangsan', 'djkgjk23lkl4332l3k289ds');
    

    Object.create需要一个原型对象作为参数,并返回一个继承自该原型对象的新对象。

    Object.create只有在ES5环境下才是有效的,这里提供了一个兼容版的。

    if (typeof Object.create === 'undefined') {
        Object.create = function(prototype) {
            var C = function() {};
            C.prototype = prototype;
            return new C;
        }
    };
    

    这里只实现了单参数版本的Object.create函数。

    参考:编写高质量JavaScript代码的68个有效方法

  • 相关阅读:
    BootStrap .row-cols 类的用法
    苹果手机浏览器$(document).on(“click”,function(){})点击无效的问题
    $("节点名").html("字符串")和$("节点名").text("字符串")区别
    linux 安装Nginx
    linux安装nginx
    vue dev开发环境跨域和build生产环境跨域问题解决
    正在载入中......loading页面的几种方法
    浏览器断点调试js
    vue组件之间传值方式解析
    基于Vue + Vuex + Vue-router + Webpack 2.0打造微信界面
  • 原文地址:https://www.cnblogs.com/mackxu/p/new.html
Copyright © 2020-2023  润新知