对象创建,对象方法

创建对象方式

第一种模式:工厂方式

            // 对象方法。
            //对象首个字母可以不大写也不会出错,但是大写就像不成文的规定一样,大家都是按照这种风格来书写的。
            var obj = function() {  
                console.log( "工厂方式创建对象,将方法写在外面避免重复创建,消耗性能。" )
                return 2
            };  
            //创建对象
            function Parent(){  
                var  Child = new Object();  
                Child.name = "张三";  
                Child.age = "30";  
                //第一个obj指的是对象的属性。第二个obj指的上边定义的变量。
                Child.obj = obj;   
                //必须返回                   
                return Child;  
            };                  
            var  x = Parent();  
            console.log( x.name );
            // 调用对象方法直接打点调用即可。x.obj()。
            // 下边会在控制台输出。不写return 2会显示一个undefined,原因是方法没有返回值。
            console.log( x.obj() );
            console.log( x.age );

一些细节:

1.对象内定义各种属性,属性可以为方法,建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法,消耗性能。

2.工厂方式解决了创建多个相似对象的问题,但是没解决对象识别问题(即怎样知道一个对象的类型)。

3.不推荐使用这种方式创建对象。

第二种模式:构造函数方式

                var obj = function() {  
                    console.log( "构造函数方式创建对象,this指当前对象(是p也就是Parent)。" );
                    return 2;
                };  
                function Parent(){  
                    this.name = "张三";  
                    this.age = "30";  
                    this.obj = obj;  
                };  
                var p = new Parent();
                console.log( p.name );
                console.log( p.age );
                console.log( p.obj() );

一些细节:

1.使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并且函数无需明确return。

2.不推荐使用这种方式创建对象。

第三种模式:原型模式

  1. 什么是原型?
    我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含有特定类型的所有实例共享的属性和方法。

  2. 只要创建了一个新函数,就会为该函数创建一个prototype 属性。在默认情况下,所有prototype属性都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。这样,函数及函数原型之间形成了循环指向。

  3. 每当调用构造函数创建一个新实例后(即”new constructor()”这样的形式),该实例的内部将包含一个指针(一般名为proto),指向构造函数的原型属性。(console.dir( obj )即可查看)

                var obj = function() {  
                    console.log( "原型方式创建对象。" );
                    return 2;
                };  
                function Parent(){};  
                Parent.prototype.name = "张三";
                Parent.prototype.age = "30";
                Parent.prototype.obj = obj;

                var p = new Parent();
                console.log( p.name );
                console.log( p.age );
                console.log( p.obj() );                

一些细节:

1.函数中不对属性进行定义。

2.利用prototype属性对属性进行定义。

3.不推荐使用这样方式创建对象。

第四种模式:混合的构造函数,原型方式(推荐)

                var obj = function() {  
                    // 这里的this指的是p也就是Parent对象,因为obj是Parent的原型方法。
                    console.log( this.name + "是" + this.age + "岁" );
                    console.log( "混合构造函数和原型方式创建对象。" );
                    return 2;
                };  
                function Parent(){
                    this.name = "张三";
                    this.age = "30";                    
                };  
                Parent.prototype.obj = obj;

                var p = new Parent();
                console.log( p.name );
                console.log( p.age );
                console.log( p.obj() );                

一些细节:

1.该模式是指混合搭配使用构造函数方式和原型方式。

2.将所有不是方法的属性定义在函数中(构造函数方式),将所有属性值为方法的属性利用prototype在函数之外定义(原型方式)

3.推荐使用这样方式创建对象。

4.:好处:通过这种方式,不仅每个实例都有自己的一份实例属性的副本,而且同时又共享着对方法的引用,最大限度的节省了内存。而且这种混合模式还支持向构造函数传递参数,可谓是集两种模式之长。

5.关于基本类型(string,number,boolean,null,undefined)和引用类型(object),或许有助于你理解第4点的好处。

1、复制基本类型:

这里写图片描述

2、复制引用类型:

这里写图片描述

一个引用的例子。

即使在函数内部修改了参数的值,但是原始引用不变,实际上。当函数内部重写obj时,这个变量引用就是一个局部对象了。局部对象会在函数执行完毕后销毁。

        function setName( obj ) {
            obj.name = "liu"
            obj = new Object()
            obj.name = "yong"
        }
        var person = new Object()
        setName( person )
        console.log( person.name )

        //  liu

第五种模式:动态原型方式

                function Parent(){
                    this.name = "张三";
                    this.age = "30";        
                    // this.obj = function() {
                    //     return 1;
                    // } 
                    if( typeof this.obj != "function" ) {
                         Parent.prototype.obj = function() {
                            console.log( this.name + "是" + this.age + "岁" );
                            return 2;
                         };
                    };           
                };  
                // Parent.prototype.obj = function() {
                //     return 3;
                // } 
                var p = new Parent();
                console.log( p.name );
                console.log( p.age );
                console.log( p.obj() );      

一些细节:

1.动态原型方式可以理解为混合构造函数,原型方式的一个特例。

2.该模式中,为方法的属性直接在函数中进行了定义,但是因为

Parent.prototype.obj = function() {
           console.log( this.name + "是" + this.age + "岁" );
           return 2;
           };

从而保证创建该对象的实例时,属性的方法不会被重复创建。

3.

第六种模式:字面量方式

            // 1.字面量方式创建对象。
            var Parent = {
                // 属性之间用逗号分开。
                name: "张三",
                age: "30",
                show: function () {
                console.log( "字面量方式创建" )
                    return 3;
                }
            }
            console.log(Parent.show())

对象方法

            //基类(父类)
            function Base( name, age ) {
                this.name = name,
                this.age = age,
                // showInfo()基类对象方法。
                this.showInfo = function(){
                    console.log('姓名:' + this.name + ',年龄' + this.age);
                }
            }
            // showInfos()基类的类方法。(类的静态方法)
            Base.showInfos = function() {
                console.log('类方法,姓名:' + this.name);
            }
            // showAge()基类原型方法。(类的实例方法)
            Base.prototype.showAge = function() {
                console.log('原型方法,年领:' + this.age);
            }

一些细节:
1.静态方法不可以被继承,也不能被重写,类加载时便加载了;而实例方法,则在实例化后加载。如果一个方法经常被调用,并且与自身的对象没有什么关系,就用静态方法;如果一个方法在必然使用它的情况下才需要调用,就用实例方法。

2.对象方法包括构造函数中的方法以及构造函数原型上面的方法,如果类生成一个实例,那么该实例就能使用该方法。

3.类方法,不需要通过生成实例就可以使用的方法,其实这里的类就是一个函数,在js中由于函数也是一个对象,所以可以为函数添加属性以及方法,这种方法在node中用的比较多。

4.原型方法一般用于对象实例共享,比如Person.prototype.sayName=function(){console.log(this.name);};在原型上面添加该方法,就能实现共享。这样就不用每一次初始化一个实例的时候,为其分配相应的内存了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值