美文网首页
JavaScript:对象学习

JavaScript:对象学习

作者: 勇往直前888 | 来源:发表于2017-03-21 20:06 被阅读68次

    JavaScript有数组,但是没有字典这种结构,对象从形式上看就是一种字典结构。并且对象的key统一为String类型,(用其他类型也不会出错,只是内部会调用toString接口自动转),value可以是简单的值,对象,函数,数组等。
    可以简单理解为对象就是字典的键值对,跟JSON互转非常方便。个人非常认同这种简单的处理方式。
    当然,有map这种类似字典的结构,至少名字不叫字典,并且目前更愿意用数组的map()方法。
    一切都是对象,比如数组、函数本身都是对象。数字,布尔量等等也都是对象。

    对象创建

    JavaScript没有类的概念,而是采用原型链的方式来定义类。平时使用的时候直接调用构造函数创建类。并且也没有析构函数的概念。delete也只是删除对象的属性,而不是回收对象。对象的回收由GC统一负责,不需要操心
    使用对象
    Javascript 创建对象方法的总结
    JavaScript prototype
    JavaScript 对象

    直接{}初始化

    大多数时候,对象就是一些键值对的组合,比如MVC设计模式中的M,只有属性,没有方法,并且字段名都确定。那么最简单的方式就是直接定义变量,给初始化值。对象定义和初始化一并完成了。对象{}可以嵌套,跟JSON很相似:

    var myCar = {
        color: "red", 
        wheels: 4, 
        engine: {
            cylinders: 4, 
            size: 2.2
        }
    };
    console.dir(myCar);
    

    构造函数

    如果Model在好几个地方用,那么直接初始化的方法就不大合适,一不小心属性名字就写的不一样了。可以定义一个构造函数,然后用的地方调用这个构造函数创建对象,可以保证大家的属性名字是一样的,只是对象的名字和属性值不一样。
    这里包括定义构造函数和定义变量并初始化两个步骤

    function Car(make, model, year) {
      this.make = make;
      this.model = model;
      this.year = year;
    }
    var myCar = new Car("Eagle", "Talon TSi", 1993);
    console.dir(myCar);
    

    动态添加属性

    一开始只知道要用一个对象,但是字段一个都不知道。等到用的时候才知道字段的名字和值。这种场景,可以通过直接添加属性的方式创建对象。这种形式使用起来最方便。

    person = {};  // person = new Object();
    person.firstname="John";
    person.lastname="Doe";
    person.age=50;
    person.eyecolor="blue";
    console.dir(person);
    

    添加方法

    • 属性的keyString,值是对象(数字也是对象);函数的key也是String,值是函数,也是对象;所以函数成员和普通的数据成员没有本质区别。
    • 不过从面向对象设计的概念来说,数据是私有的,每个对象一份copy,大家互不影响,是合理的。而函数只是定义了做事的方法,并没有实际工作,不需要每个对象持有一份copy,只要大家共享一份就可以了。这样省内存啊。
    • 除了函数以外,有些数据成员也希望多个对象共享一份数据。行为相当于静态变量。
      希望共享的成员,(函数或者数据都一样),就添加到对象的prototype
    function Person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
    }
    
    Person.prototype = {
        friends:["Jams","Martin"],
        sayFriends:function() {
            alert(this.friends);
        }
    };
    
    var person1 = new Person("kevin",31,"SE");
    var person2 = new Person("Tom",30,"SE");
    person1.friends.push("Joe");
    person1.sayFriends(); // Jams,Martin,Joe
    person2.sayFriends(); // 也是Jams,Martin,Joe;因为属性friends在prototype定义,所有Person对象共享
    console.dir(person1);
    console.dir(person2);
    

    如果要把prototype部分的定义放到构造函数中,要注意保护只做一次。因为构造函数会被多次调用,但是定义prototype只要1次就可以了。推荐还是这种将prototype拿到构造函数外面定义的方式。

    访问对象

    • 访问属性一般用点语法:objectName.propertyName
    • 访问方法一般用点语法:objectName.methodName()
    • 访问属性也可以用[]。一个属性的名称如果不是一个有效的 JavaScript 标识符(例如,一个由空格或连字符,或者以数字开头的属性名),就只能通过方括号标记访问。这个标记法在属性名称是动态判定(属性名只有到运行时才能判定)时非常有用。例如:
    // 同时创建四个变量,用逗号分隔
    var myObj = new Object(), str = "myString", rand = Math.random(), obj = new Object();
    
    myObj.type              = "Dot syntax";
    myObj["date created"]   = "String with space";
    myObj[str]              = "String value";
    myObj[rand]             = "Random Number";
    myObj[obj]              = "Object";
    myObj[""]               = "Even an empty string";
    
    console.dir(myObj);
    

    原型对象(prototypical object)

    • JavaScript是基于原型的语言:只有对象,没有类。
    • 原型对象可以作为一个模板,新对象可以从中获得原始的属性。只是简单的copy,没有继承的功能。通过“原型链”,可以实现类似继承的效果。
    • 通过原型继承来的属性是所有对象共享的,这点要注意。对象特有的变量要用this关键字写在构造函数中
    • 特殊的 __proto__属性是在构建对象时设置的;设置为构造器的 prototype 属性的值。
      所以表达式 var a = new Foo() 将创建一个对象a,其中 a.__proto__ == Foo.prototype
    • 对象先找本地自己的构造函数中用this表示的变量,找到了就返回了,不去管原型链中是否有相同名字的属性。效果相当于子类覆盖父类的属性
    • 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部 - 也就是 Object.prototype - 但是仍然没有找到指定的属性,就会返回 undefined
    • hasOwnPropertyObject.prototype的一个方法,它可是个好东西,他能判断一个对象是否包含自定义属性而不是原型链上的属性,因为hasOwnPropertyJavaScript中唯一一个处理属性但是不查找原型链的函数。
    // 修改 Object.prototype
    Object.prototype.bar = 1;
    
    var foo = {moo: 2};
    for(var i in foo) {
        console.log(i); // 输出两个属性:bar 和 moo
    }
    
    for(var i in foo) {
        if (foo.hasOwnProperty(i)) {
            console.log(i);   // 只输出 moo
        }
    }      
    

    参考文章

    javaScript原型链理解
    这个文章讲得比较清楚,特别是那张图要好好理解。

    对象模型的细节

    深入理解JavaScript系列(5):强大的原型和原型链

    彻底理解javascript中的原型链

    相关文章

      网友评论

          本文标题:JavaScript:对象学习

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