JS 面向对象之对象的创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS 面向对象之对象的创建相关的知识,希望对你有一定的参考价值。

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

1 字面量创建方式

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

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 创建书的工厂函数

    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 创建多个书对象

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

特点:① 利用工厂函数创建对象,只要通过 new 函数()  就可以创建出不同的对象 。

        ② 但是有多个工厂函数,且属性和方法相同时,创建出来的对象就无法识别对象的类型,因为创建对象都是使用Object的原生构造函数来完成的。

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



以上是关于JS 面向对象之对象的创建的主要内容,如果未能解决你的问题,请参考以下文章

浅谈JS面向对象之创建对象

JS面向对象之创建对象模式

js之面向对象

js面向对象程序设计之构造函数

JS 面向对象之对象的创建

PHP面向对象之选择工厂和更新工厂