面向对象 创建对象

1.面向过程的思维方式:

    就是把解决问题的关注点,放到解决问题的每一个详细的步骤上面!

 面向对象的思维方式:(面向对象就是一种思维方式,与代码关系不大)

就是把解决问题的关注点,放到解决问题需要的一系列对象身上

2.面向对象编程的相关概念:

 1、什么是对象!!!!  万物皆对象

 2、对象的特征

     对象的特征就是用来描述对象的相关信息

     比如一个人对象,特征就有:name  age  gender  height

 3、对象的行为

     对象行为就是描述对象的行为

     比如一个人对象,行为就有:吃 跑 跳 睡 唱 抽烟 喝酒 烫头

 4、在JS当中 什么是对象?

     键值对儿的组合就是对象  其中值可以是数据或函数

 5、现实生活中的对象的特征对应到JS当中是对象的属性!

 6、现实生活中的对象的行为对应到JS当中就是对象方法!

创建对象的方式

1. 对象字面量{key: value, key: value....}

只能创建一次对象,复用性较差,如果要创建多个对象,代码冗余度太高

2.使用内置构造函数(Array,Object)       构造函数本身也是函数,只不过可以用来创建对象而已

 var obj = new Object();
 
         obj.name = "一千个伤心的理由";
         obj.singer = "张学友";
         obj.sing = function () {
             console.log("一千个伤心的理由");
         }
 
         var obj1 =new Object();
         obj.name = "一千个伤心的理由";
         obj.singer = "张学友";
       obj.sing = function () {
            console.log("一千个伤心的理由");
      }

要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4
个步骤:
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。

任何函数,只要通过 new 操作符来调用,那它就可以作为构造函数;而
任何函数,如果不通过 new 操作符来调用,那它跟普通函数也不会有什么两样。

创建出来的对象都是空的对象,要手动的去为对象添加属性。造成代码重复。

构造函数的执行过程

         1.使用new关键字创建对象

         2.调用构造函数,把新创建出来的对象赋值给构造函数内的this

         3.在构造函数内使用this为新创建出来的对象新增成员

         4.默认返回新创建的这个对象 (普通的函数,如果不写返回语句,会返回undefined)

构造函数的返回值

         1.如果不写返回值,默认返回的是新创建出来的对象 (一般都不会去写这个return语句)

         2.如果我们自己写return语句 return的是空值(return;),或者是基本类型的值或者null,都会默认返回新创建出来的对象

         3.如果返回的是object类型的值,将不会返回刚才新创建的对象,取而代之的是return后面的值

构造函数存在问题
    构造函数中的方法,每新创建一个对象的时候,该对象都会重新的创建一次这个方法,每个独享独占一个方法
    但是该方法内容完全相同,所以造成资源浪费
    1.解决办法1
    将构造函数内的方法,进行提取,放在构造函数外面,在构造函数内部进行引用赋值
    那么创建出来的对象,都会指向构造函数外面的这个函数,达到共享的目的
    问题:全局变量增多,造成全局变量污染,代码结构混乱,不容易维护
    2.解决办法2
    使用原型

3.工厂函数(不推荐使用)

 function createSong(songName,singerName){
            var o =new Object();
            o.name = songName;
            o.singer = singerName;

            o.sing = function () {
                console.log("让我来唱首歌");
            }
            return o; {name:"",singer:"",sing:function...}
        }

        var obj = createSong("演员","薛之谦");

        var obj1 = createSong("一言难尽","张宇");

工厂模式虽然解决了创建
多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)

4.原型模式

在构造函数创建出来的时候,系统会默认的帮构造函数创建并关联一个对象,这个对象就是原型   原型默认的是一个空的对象  默认的原型对象中会有一个属性constructor指向该构造函数

原型的作用:原型中的属性和方法 可以被使用该构造函数创建出来的对象使用。

如何访问构造函数的原型:构造函数.prototype。 

注意 prototype是构造函数的属性,跟对象没有关系

原型对象的使用
    1. 使用对象的动态特性,为原型对象添加成员
    2. 直接替换原型对象
    注意事项:
        直接替换原型对象,会导致替换之前创建的对象的原型和替换之后创建的对象的原型不一致
原型的使用该注意事项
    1.使用对象访问属性的时候,会现在对象中查找,如果找到了就直接使用
    如果没有找到,就去原型中查找
    2.使用对象设置属性的时候(点),只会在对象本身中查找,不会去原型中查找,如果在对象本身中没有找到这个属性
    则给该对象新增一个属性,如果在对象中有这个属性,修改这个属性
    3.如果在原型对象中有引用类型的属性,那么使用对象进行修改该属性内容,则其他所有跟这个原型对象相关的对象都会受到影响
    Person.prototype.car = {};
    var p = new Person( );
    p.car = {}; //这是修改属性
    p.car.brand= ""; //这是修改属性的内容
    4.一般情况下不会将属性添加到原型对象中
    只会将需要共享的方法,添加到原型对象中
__proto__
    1.这个属性不是标准属性,所以存在通用性问题
    2.一般不推荐使用这个属性
    3.调试的时候,可以使用这个属性
    4.这个属性是原型中的属性(??不是实例的?)
替换原型时候的注意事项:
    在新替换的原型中,没有constructor属性,会影响三角结构关系的合理性
    so,在新替换的原型中,手动添加constructor属性,以保证关系的合理性,赋值为关联的构造函数

如何给原型对象添加属性和方法?

使用对象的动态特性

当使用对象去访问属性和方法的时候,会首先在对象自己内部进行查找,如果找到了,就直接使用

如果没有找到,就去原型中查找,查找到之后,使用。如果原型中还没有, 如果是属性,就是Undefined。如果是方法,就报错。

原文地址:https://www.cnblogs.com/aimeeblogs/p/9514393.html