美文网首页
【js基础】创建对象&函数的六种模式

【js基础】创建对象&函数的六种模式

作者: SophieRabbit | 来源:发表于2019-05-15 19:53 被阅读0次

*为更加清晰的了解原生JavaScript中的创建对象&函数,本文均采用ES5的语法。 

一、最简单的创建对象

1.使用new关键字创建Object

var student = new Object;

student.id = 12345;

student.name = "xiaoming";

student.sex = "male";

student.word = function() {

    alert("I am Xiaoming!")

}

2.对象字面量

var student = {

    id: 12345,

    name: "xiaoming",

    sex: "male",

    word: function() {

        alert("I am Xiaoming!")

    }

}

上面的两种方式,会产生大量的代码,而且没有复用性。由此,我们可以考虑采用工厂模式,即类似于工厂用一条流水线,批量生产的方式创建对象:

二、工厂模式

function createStudent(name,sex,id) {

    var o = new Object();

    o.name = name;

    o.sex = sex;

    o.id = id;

    o.word = function(){

        alert(this.name);

    }

    return o;

}

上面定义的函数createStudent,就是使用工厂模式的方式创建对象的。每次调用函数时,新建一个对象并给其属性赋值。

var student1 = createStudent("xiaoming", "male", 12345);

var student2 = createStudent("xiaoling", "female", 54321)

和直接创建对象相比,工厂模式大大节省了代码量,并且可复用,解决了重复实例化多个对象的问题。但同时也有一定的弊端:没有解决对象识别的问题。在JavaScript中,对象还包括Date、Array等特殊对象,仅通过工厂模式无法解决对象类型的识别。由此,我们可以采用构造函数:

三、构造函数模式

function Student(name,sex,hobby)  {

    this.name = name;

    this.sex = sex;

    this.hobby = hobby;

    this.word = function(){

        alert(this.name);

    }

}

以此方法调用构造函数步骤 {

1、创建一个新对象

2、将构造函数的作用域赋给新对象(将this指向这个新对象)

3、执行构造函数代码(为这个新对象添加属性)

4、返回新对象

}

//调用并生成对象

var student1 = new Student ("xiaoming", "male", ["singing", "soccer", "game"]);

var student2 = new Student ("xiaoling", "female", ["comic", "dancing", "reading"]);

console.log(student1 instanceof Object);  //true

console.log(student1 instanceof Student);  //true

console.log(student2 instanceof Object);  //true

console.log(student2 instanceof  Student );  //true

console.log(student1.constructor);   //constructor 属性返回对创建此对象的数组、函数的引用

instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置。由上例可以看出,通过构造函数创建的student1、student2既是Student的实例,也是Object的实例。这说明通过构造函数创建的对象是可以判断其对象类型的。

构造函数对比工厂模式有以下不同之处:

1、没有显式地创建对象

2、直接将属性和方法赋给了 this 对象

3、没有 return 语句

构造函数依然存在一些问题。虽然不再重复的显式创建对象,但是每次new一个Student时,其实也是每次都创建了一个Function。而Function也是对象的一种类型。其本质是多次创建了函数。为解决这个问题,产生了原型模式。

四、原型模式

function Student() {

}

Student.prototype.name = "xiaoming";

Student.prototype.sex = "male";

Student.prototype.hobby= ["singing", "soccer", "game"];

Student.prototype.word = function(){

    alert(this.name);

};

由上面代码可以看出,Student的属性定义在了它的原型(prototype)上。这样的方式可以使得Student所有对象实例共享它的属性和方法,无需在每次创建对象时都要创建一份新的属性和方法,直接定义属性和方法在对象的原型上,可以使得所有实例都直接继承。

console.log(Student.prototype);  //Object{name: 'xiaoming', sex: "male", hobby: Array[3]}

var student1 = new Person();        //创建一个实例person1

console.log(student1.name);        //xiaoming

student1.name = "xiaojun";

console.log(student1.name);        // xiaojun

上文可以看出,在实例上再次定义同名的属性(私有属性),可以覆盖其原型上的公有属性。

五、组合模式(构造函数模式+原型模式)

单纯的构造函数和原型模式各有优缺点。因此,我们可以利用构造函数模式定义实例属性,原型模式用于定义方法和共享的属性,结合两者的优点使用。

//构造函数定义属性:

function Student(name,sex,hobby){

    this.name = name;

    this.sex= sex;

    this.hobby= hobby;

}

//原型定义方法:

Student.prototype = {

    constructor: Student,  //让构造器指向自身

    word: function(){

        alert(this.name);

    }

}

var student1 = new Student("xiaoming","male",["singing", "soccer", "game"]);

console.log(student1);

上面代码中的constructor的意思是,每个函数都有prototype属性,指向该函数原型对象,原型对象都有constructor属性,是一个指向prototype属性所在函数的指针。具体对面向对象的constructor的解读,可看文章连接:https://www.jianshu.com/p/49e5e848fee0

在其他面向对象的语言中,属性和方法往往是封装在一起的,而在组合模式中,构造函数和原型是分开定义了属性和方法的,所以并没有真正意义上的封装,因此,动态原型模式正是解决这一问题的方案。

六、动态原型模式

动态原型模式是将属性和方法都封装在构造函数中(包括原型属性和实例属性),通过在构造函数中实例化原型(仅在必要的情况下)实现封装,又保持了同时使用构造函数和原型的优点。其本质是在构造函数中加了一层对于方法的判断,从而实现动态生成原型上的方法。

function Student(name,sex,hobby){

        this.name = name;

        this.sex = sex;

        this.hobby = hobby;

        if(typeof this.word != "function") {//这段判断语句的作用是限制Person.prototype属性(原型属性对象)只生成一次,要不然每次实例化一个Person对象都会去写一遍原型对象

            Student.prototype.word = function () {

                alert(this.name);

            }

        }

    }

    var student1 = new Student("xiaoming","male",["singing", "soccer", "game"]);

创建Student构造函数时,会创建一个prototype属性,该属性实际上就是Student.prototype的原型对象,prototype属性是一个指针,指向Person.prototype的原型对象,

当this指向的属性非方法(typeof this.word != "function"),则在当前对象的原型上创建一个新方法。避免了重复修改原型方法。

相关文章

  • 2020-12-15

    js对象的创建和函数 创建对象 工厂模式 构造函数 原型方式+构造函数

  • 【js基础】创建对象&函数的六种模式

    *为更加清晰的了解原生JavaScript中的创建对象&函数,本文均采用ES5的语法。 一、最简单的创建对象 1....

  • js 中的创建对象的几种方式

    JS中创建对象的主要模式有 工厂模式 工厂模式抽象了具体创建对象的过程例如 函数createPerson()能够根...

  • 2017-4-1 VUE

    JS的方法 1、类型判断的方法 2、创建对象构造函数 3、JS基础函数和语法

  • 发现•分享—2019-01-17

    文章 JS JS 异步编程六种方案 JS基础—原型对象的那些事(一) JS基础—原型对象的那些事(二) CSS 综...

  • Js创建对象的几种模式

    Js创建对象的几种模式 工厂模式 构造函数模式 原型模式 组合使用构造函数模式和原型模式 动态原型模式 稳妥构造函数模式

  • js进阶(二)

    第十二天 04-基础进阶-第02天{对象进阶、内置对象} 第十二天对象工厂模式创建对象构造函数模式创建对象原型模式...

  • JavaScript创建对象之原型模式

    一、原型基础 在之前的文章:《JavaScript创建对象之单例、工厂、构造函数模式》中详细介绍了构造函数模式创建...

  • 对象的创建与继承

    创建对象 工厂模式 => 构造函数模式 => 原型对象模式 => 构造函数模式+原型对象模式 工厂模式 构造函数模...

  • 6.JavaScript中

    JS对象创建: JS通过构造函数创建对象: JS内置对象window: 所有的全局变量都是window的属性 所有...

网友评论

      本文标题:【js基础】创建对象&函数的六种模式

      本文链接:https://www.haomeiwen.com/subject/busdoqtx.html