• JavaScript基础Literal 与 Constructor(008)


    JavaScript支持以字面声名法(Literal)的方式来声名对象和数组,相对于构造函数(constructor)的方式,Literal的声 名方式更简洁,更易读,也更少导致Bug。事实上,JSON就是用Literal的方式定义的JavaScript数据格式。

    1. 用Literal的方式创建对象
    JavaScript里的对象大概就好像是一个装着一堆“键-值对”的哈希表。下面我们给出以Literal方式声名对象的语法:

    • 用花括号把对象的内部包起来(即{});
    • 对象中的各个键值对之间要用逗号分开;
    • 键与值之间用冒号分开;
    • 当你把这个对象赋值给一个变量,别忘记在后面的花括号}那里标识赋值语句的结束(即加分号';')。


    对于”值“来说,有可能是简单的数据类型,也可能是其它的对象,还可以是方法。通过Literal的方式创建出来的对象,其内容可以随时修改。比如:

    // start with an empty object
    var dog = {};
    
    // add one property
    dog.name = "Benji";
    
    // now add a method
    dog.getName = function () {
        return dog.name;
    };
    

     上面的代码里先是创建了一个空的对象,然后向它添加了属性和方法。你还可以修改属性的值,或是重新定义方法:

    dog.getName = function () {
        // redefine the method to return
        // a hardcoded value
        return "Fido";
    };
    

     甚至删除属性:

    delete dog.name;
    

     再加入新的属性和方法:

    dog.say = function () {
        return "Woof!";
    };
    dog.fleas = true;
    

     这个例子一开始定义的是个空的对象,实际的情况下也可以在最初给这个对象定义一些内容:

    var dog = {
        name: "Benji",
        getName: function () {
            return this.name;
        }
    };
    

     补充说明一下,上面提到的”空的对象“其实在JavaScript里并不”空“。因为当你声名了一个{}对象,它立即就从Object.prototype中继承了属性和方法,说它是个”空的对象“,意思是我们还没有给它定义自己的属性和方法而已。

    2. 用JavaScript内置的构造函数创建Object对象

     再次说明一下,JavaScript里没有”类“这个概念。创建JavaScript对象时不需要有”蓝本“。在JavaScript里,对象的构造函数有点像”类“的定义,特别是在把构造函数用起来的时候。下面看一下用Literal和内置的构造函数这两种方法的具体做法:

    // one way -- using a literal
    var car = {goes: "far"};
    // another way -- using a built-in constructor
    // warning: this is an antipattern
    var car = new Object();
    car.goes = "far";
    

     很明显,一行的Literal声名可以完成两行Contructor声名的工作。另外,Literal的方式也能体现JavaScript里对象的实际情况:其实就是一堆的键值对,而不是由一个蓝本”类“实例化而来。所以我们应该总是用Literal的方式来声名Object对象,而不是用 JavaScript内置的new Object()的方式。new Object()还有一个问题。当你给这个构造函数传递参数的时候,它可能会热心的帮你生成一个特殊类型的对象,这时可能会发生一些意思不到的问题:

    // Warning: antipatterns ahead
    // an empty object
    var o = new Object();
    console.log(o.constructor === Object); // true
    
    // a number object
    var o = new Object(1);
    console.log(o.constructor === Number); // true
    console.log(o.toFixed(2)); // "1.00"
    
    // a string object
    var o = new Object("I am a string");
    console.log(o.constructor === String); // true
    // normal objects don't have a substring()
    // method but string objects do
    console.log(typeof o.substring); // "function"
    
    // a boolean object
    var o = new Object(true);
    console.log(o.constructor === Boolean); // true
    

     3. 自定义的构造函数来创建特定的对象
    除了new Object()以外,我们也可以用自己编写构造函数来创建特定的对象,比如:

    var adam = new Person("Adam");
    adam.say(); // "I am Adam"
    

     这段代码看起来很像是Java里创建Person对象。虽然语法相似,但在JavaScript里没有”类“,而且Person其实也不过只是个函数。下面就是Person这个用于构造对象的函数的定义方式:

    var Person = function (name) {
        this.name = name;
        this.say = function () {
            return "I am " + this.name;
        };
    };
    

     当使用new关键字执行上面的函数时,发生了下面的几件事:

    • 一个空的对象被创建了出来;
    • 使这个对象继承Object.proptotype(JavaScript里的对象原型),并把对象的引用赋给this;
    • 在函数的最后隐式返回this引用。

    也就是说:

    var Person = function (name) {
        // create a new object
        // using the object literal
        // var this = {};
        // add properties and methods
        this.name = name;
        this.say = function () {
            return "I am " + this.name;
        };
        // return this;
    };
    

     上面的代码表明,new Person()对于JavaScript来说,并不是创建了一个类的实例,而是创建了一个新的函数,并把这个函数的引用交给了this。我们以后再谈谈 JavaScript里的函数与对象的关系,以及对象原型和继承,这里先看看say()方法。为了简化这个例子,我们为Person对象加入了say() 方法,但这种做法在效率上并不高:因为每个新的对象里的say方法都是一样的。对于这种情况,其实应该为Person的原型加入say()方法,而不是在创建的时候为每个对象加入相同的say方法:

    Person.prototype.say = function () {
        return "I am " + this.name;
    };
    

     更清楚明白地说,其实构造函数创建的对象并不”空“,也就是说这里:

    // var this = {};
    

     应该是创建了Object原型的一个拷贝才对:

    // var this = Object.create(Person.prototype);
    

     当然,隐式的return如果被显式地加入,你就可以返回一个你想返回的任何对象,这时返回的就不是this引用了。比如:

    var Objectmaker = function () {
        // this `name` property will be ignored
        // because the constructor
        // decides to return another object instead
        this.name = "This is it";
        // creating and returning a new object
        var that = {};
        that.name = "And that's that";
        return that;
    };
    // test
    var o = new Objectmaker();
    console.log(o.name); // "And that's that"
    
  • 相关阅读:
    TP5.1 分页CSS样式(转载)
    简单的layui二级联动
    关于layui部分表单不显示的问题(Select, checkBox)
    MySQL 开启远程访问权限 | 宝塔系统
    tp5.1 本地正常, 线上route.php不起作用的问题
    cocos自动图集
    微信小程序video
    nuxt https
    接口数据加密
    node里读取命令行参数
  • 原文地址:https://www.cnblogs.com/Bryran/p/3969144.html
Copyright © 2020-2023  润新知