JS 面向对象之对象的建立

在学习了面向对象,咱们了解了面向对象的三大特性:封装、继承、多态。下面咱们须要了解对象的建立方式:css

1 字面量建立方式

对象有不少描述方式,好比键值对(key--value)的集合、字典、工具包。对象的本质是对变量和函数进行封装,将变量封装成属性,函数封装为方法;这里咱们就是采用字典的方式来建立对象,将属性和方法名做为keyhtml

1.1 建立一个书对象
 
var book = {
    name:"js入门教学",
    price:"¥34",
    author:"刘忻欢",
    showName: function () {
        console.log(this.name);
    }
}
/*调用对象 */
console.log(book.name);
 

特色:字面量建立方式比较简单,把方法和属性写在{}中,可是当须要建立多个同类型的对象的时候,代码的重复性就比较高,它不适用于批量的建立同类型的对象。函数

1.2 建立多个书对象
 var book1 = {
        name:"js入门教学",
        price:"¥34",
        author:"刘忻欢",
        showName: function () {
            console.log(this.name);
        }
    }
    var book2 = {
        name:"html+css深刻浅出",
        price:"¥50",
        author:"张某某",
        showName: function () {
            console.log("jjjj");
        }
    }

 

2 内置构造函数建立方式

js内置构造函数有:Object   Function  Date   String   Number   Array  .....工具

建立方式分为两步:性能

 /*首先 建立一个空对象*/
    var obj = new Object();

    /*其次  设置属性|方法*/
    obj.name="内置构造函数建立对象";
    obj.ways = function () {
        console.log("2步");
    }

 

特色:利用内置构造函数建立对象和字面量方式建立同样,须要建立多个同类型的对象时,会出现大量重复的代码。学习

 

3 简单工厂函数建立对象方式

3.1 建立书的工厂函数this

    function createBook(name,author,price){
        /*建立一个空对象*/
        var book = new Object();
        book.name = name;
        book.author = author;
        book.price = price;
        book.log = function () {
            console.log("eee");
        }
        return book;
    }

3.2 建立多个书对象spa

    var book1 =new createBook("三毛流浪记","张乐平","南方出版社");
//         打印书名
        console.log(book1.name);
    var book2 = new createBook("阿衰","猫小乐","云南出版集团公司");
//       打印book2对象
        console.log(book2);

特色:① 利用工厂函数建立对象,只要经过 new 函数()  就能够建立出不一样的对象 。prototype

        ② 可是有多个工厂函数,且属性和方法相同时,建立出来的对象就没法识别对象的类型,由于建立对象都是使用Object的原生构造函数来完成的。3d

3.3 多个工厂函数

 function createPerson(name,age,eating){
        var person = new Object();
        person.name = name;
        person.age = age;
        person.eat = function () {
            console.log(eating);
        }
return person; }
function createDog(name,age,eating){ var dog = new Object(); dog.name = name; dog.age = age; dog.eat = function () { console.log(eating); }
return dog; }

构造了建立人和狗的两个方法,他们的属性和方法同样

 var person1 = new createPerson("小明","23","吃米饭");
    var dog1 = new createDog("小小明","2","狗粮");

    console.log(person1);
    console.log(dog1);

打印结果:

 

 

 

 

 

 

 

 

 

 

 

 

问题:咱们没办法区分哪一个对象是 createPerson方法建立 ,哪一个是createDog  方法建立

总结:为何将这种方式叫作工厂呢,由于它的模式和工厂十分类似。工厂的特色:批量生产(原料 --- 加工 --- 产品)

 

4 自定义构造函数建立对象方式

什么是构造函数:① 构造函数和普通函数本质上没有区别

                       ② 构造函数一般首字母大写(这是为了 人为的区分)

                       ③ 在调用时,构造函数必需要和 new关键字 结合

 

4.1 构造函数的核心过程

                      ① 提供一个构造函数

                      ② 在构造函数内部经过 this  设置属性和方法

                      ③ 经过 new 函数() 建立对象

/*1 提供一个构造函数*/
    function Person(){
         /* 2 在函数内部经过  this 设置属性和方法*/
        this.name = "张三";
        this.age = 23;
        this.sex ="男";
    }
    /*3 经过 new 函数() 来建立对象*/
    var zhangsan =new Person();
    console.log(zhangsan);

自定义构造函数建立对象须要咱们完成的核心过程就这三步,可是其内部默认完成的工做其实复杂的多:

内部实现细节:

             ① 默认在内部会建立一个空的对象   var o = new Object();

             ② 默认会把新建立的对象赋值给 this   this = o;

             ③ 默认会设置新建立的对象的原型对象为当前的原型对象   o.prototype = Person.prototype;

             ④ 默认会设置新建立对象的构造器属性为当前构造器属性    o.constructor = Person

             ⑤ 经过 this设置属性和方法(这是咱们本身完成的操做)

             ⑥ 默认会返回新建立的对象     return o;

注意点:

          Ⅰ.若是咱们没写  return   ,那么默认返回新建立的对象

          Ⅱ. 若是咱们写了 return:

                 ⅰ.若是返回的是值类型(null |  undefined | "string" | number...),那么咱们本身写的 return 语句会被忽略,返回的仍然是新建立的对象;

                 ⅱ. 若是返回的是引用类型,那么就会直接返回 咱们写的 renturn 后面的对象,而内部默认建立的 return 会被忽略。

 

4.2 对注意点的验证

当返回数值类型:

 /*1 提供一个构造函数*/
    function Person(){
         /* 2 在函数内部经过  this 设置属性和方法*/
        this.name = "张三";
        this.age = 23;
        this.sex ="男";
        return "zzzzz;
    }
    /*3 经过 new 函数() 来建立对象*/
    var zhangsan =new Person();
    console.log(zhangsan);

输出结果:

 

 

 

 

 

 

当返回引用类型:

 

  /*1 提供一个构造函数*/
    function Person(){
         /* 2 在函数内部经过  this 设置属性和方法*/
        this.name = "张三";
        this.age = 23;
        this.sex ="男";
        return Array("zhang",1,3,6);
    }
    /*3 经过 new 函数() 来建立对象*/
    var zhangsan =new Person();
    console.log(zhangsan);

 

输出结果:

4.3 利用自定义构造函数建立不一样类型的对象
  function Person(name,age,eating){
        this.name = name;
        this.age = age;
        this.eat = function(){
            console.log(eating);
        }
    }
    function Dog(name,age,eating){
        this.name = name;
        this.age = age;
        this.eat = function(){
            console.log(eating);
        }
    }

    var person1 =new Person("张撒",23,"食物");
    var dog1 =new Dog("阿黄",2,"狗粮");
    console.log(person1);
    console.log(dog1);

    /* 采用类型判断*/ console.log(person1 instanceof Person); console.log(dog1 instanceof Dog);

输出结果:

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

注意点:全部的对象都是Object类型,所以全部对象  obj1 instanceof Object  的返回值都是true.

总结:

自定义构造函数建立对象可以区分对象的类型

4.3 构造函数建立对象的问题

 

 function Person(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex =sex;
        this.showName = function () {
            console.log(this.name);
        }
    }
    var person1 = new Person("zhangsan",23,"男");
    var person2 = new Person("zhangsan",22,"女");
    console.log(person1.showName ==person2.showName);  //false
    person1.showName = function () {
        console.log("123");
    }
    person1.showName();   //123
    person2.showName();   //zhangsan

对代码建立对象结构分析以下:

 

总结:由输出结果以及结构分析,能够看出person1.showName  与 person2.showName 是不一样的,他们各占一个内存空间,这样当要建立大量的对象的时候,就会建立出大量一样的 方法,这样会浪费性能空间,那么如何让不一样的对象共享同一个方法呢?下一章我将为你们分析  采用原型对象解决方法共享问题。

 

eating
相关文章
相关标签/搜索