创建一个对象的多种姿势

一般创建对象的方式


    var box = new Object();//创建一个 Object 对象

    box.name = 'Lee';//创建一个 name 属性并赋值

    box.age = 20;//创建一个 age 属性并赋值

    box.run = function () {//创建一个 run()方法并返回值

        return this.name + this.age + '岁!';

    }

    console.info( box.run() );  //Lee 20 岁!

工厂模式


// 1.封装一个方法来创建对象可以利用 arguments 对象获取参数设置属性

function createCar(){

    var args = arguments;

    var obj = {

        name : args[0],

        age : args[1],

        showName : function () {
            console.info(this.name);

        }

    return obj;

}

var axing = createCar('axing');
axing.showName();   //axing

var tom = createCar('tom',20)
tom.showName();     //tom   

// 2. 通过传参数设置属性

function Car(name,age){

    var obj = {

        name : name || '兰博基尼',

        price : price || 1000000,

        carName : function () {

            console.info(this.name);

        }
    }

    return obj;

}

var bsj = Car('保时捷');
bsj.carName();
console.info(bsj.price);    //1000000

var msld = Car('玛莎拉蒂',2000000);
msld.carName();
console.info(msld.price);    //2000000

构造器方法


    //定义一个 showPrice 方法

    function showDoor(){      

        return this.price;

    }

    function Car(Color,Price){

        this.color = Color || 'blue';     

        this.price = Price || 1000000;

        this.showPrice = function(){

            return this.price;

        }

        this.showPrice = showPrice();
        //每个 Car 对象共享同一个 showDoor 方法 (方法有自己的作用域,不用担心变量被共享)

    }

    var myCar = new Car('red',2000000);
    var price = myCar.showPrice();
    console.info( price );  //通过构造器创建一个对象并调用其对象方法

prototype 方式


    function Car3(){}

    Car3.prototype = {

        doors : 3,

        color : 'blue',

        drivers : new Array('Mike','John'),

        showColor : function(){

            console.info(this.color);

        }
    }

    var car3_1 = new Car3();

    var car3_2 = new Car3();

    console.info(car3_1.color);//blue

    console.info(car3_2.color);//blue

    console.info(Car3.prototype.color);//blue

    car3_1.drivers.push('Bill');

    console.info(car3_1.drivers);//"Mike","John","Bill"

    console.info(car3_2.drivers);//"Mike","John","Bill"

    console.info(Car3.prototype.drivers);//"Mike","John","Bill"

    //直接修改实例对象的属性,解析器会先去找实例对象是否有这个属性(不会去找实例对象的 _proto_ 属性内的那些类的 prototype 属性,而是直接查看这个实例是否有对应的属性(与_proto_同级))

    //如果没有则直接给这个实例对象添加该属性,但不会修改类的prototype域的同名属性,既实例对象的_proto_属性内的那些类 prototype 域属性不会被修改

    car3_1.color = "red";//car3_1对象内无名为 color 的对象属性,故将该属性添加到该对象上

    //解析器对实例对象读取属性值的时候会先查找该实例有无同名的直接属性

    //如果没有,则查找__proto__属性内保存的那些 当前类的 prototype 域的属性

    //有就返回,无则继续查找是否有原型链中的对应的方法属性

    //有就返回,无则返回undefined

    alert(car3_1.color);//red

    alert(car3_2.color);//blue

    alert(car3_2.color2);//undefined

    //直接修改类的 prototype 域内的属性,不会影响该类的实例对象的对象属性,但会影响实例对象的_proto_属性(_proto_属性内存放的是类的 prototype 域的内容)

    Car3.prototype.color = "black";

    alert(car3_1.color);//red 该对象有同名的直接属性,故不会去_proto_属性内查找类的 prototype 域的属性

    alert(car3_2.color);//black 受影响

    //直接修改实例对象的方法,解析器会先去找实例对象是否有这个方法(不会去找实例对象的 _proto_ 属性内的那些类的 prototype 域的方法,而是直接查看这个实例是否有对应的方法(与_proto_同级))

    //如果没有则直接给这个实例对象添加该方法,但不会修改类的prototype域的同名方法,既实例对象的_proto_属性内的那些类 prototype 域方法不会被修改

    //car3_1对象内无名为 showColor 的对象方法属性,故将该方法属性添加到该对象上

    car3_1.showColor = function () {

        alert("new function");

    }

    //解析器对实例对象调用方法属性的时候会先查找该实例有无同名的直接方法属性

    //如果没有,则查找_proto_属性内保存的那些 当前类的 prototype 域的方法属性

    //有就返回,无则继续查找是否有原型链中的对应的方法属性

    //找到就返回,无则报错

    car3_1.showColor();//new function

    car3_2.showColor();//blue

    car3_1.abcd();//直接报错

    //直接修改类的 prototype 域内的方法属性,不会影响该类的实例对象的方法属性,但会影响实例对象的_proto_属性(_proto_属性内存放的是类的 prototype 域的内容)

    Car3.prototype.showColor = function () {

        alert("second function");

    }

    car3_1.showColor();//new function 该对象有同名的方法属性,故不会去_proto_属性内查找类的 prototype 域的方法属性

    car3_2.showColor();//second function 受影响