JS面向对象篇三、创建对象的几种方法

先来说下最简单的两种创建对象的方式:通过Object构造函数创建以及对象字面量方式。

Object函数创建对象

var person = new Object()
person.name = 'youyang'
person.age = 18
person.sayName = function () {
    console.log(this.name)
}

对象字面量

var person = {
    name : 'youyang',
    age : 18,
    sayName : function () {
        console.log(this.name)
    }
}

以上两种方式在创建单个对象时没有问题,但如果创建多个类似对象的话,就会产生大量重复代码,为了解决这一问题,出现了工厂模式创建对象的方法。

工厂模式

工厂模式是软件工程领域一种广为人知的设计模式,用函数来封装创建一个具体对象的过程,然后就可以多次调用这个函数以创建相似的对象。

function createPerson (name, age) {
    var obj = new Object()
    obj.name = name
    obj.age = age
    obj.sayName = function () {
        console.log(this.name)
    }
    return obj
}
var p1 = createPerson('youyang', 18)
var p2 = createPerson('xiaoqu', 28)

这种方式虽然解决了创建多个相似对象的问题,但是这种方式创建的对象无法判断对象的类型。

构造函数模式

ECMAScript中的构造函数可用来创建特定类型的对象。因此自定义类型对象可以像下面这样创建:

function Person (name, age) {
    this.name = name
    this.age = age
    this.sayName = function () {
        console.log(this.name)
    }
}
var p1 = new Person('youyang', 18)
var p2 = new Person('youyang', 20)

为了区分构造函数和普通函数,构造函数的首字母要大写,不过构造函数本身也是一个函数,只不过是用来创建对象而已。同时使用构造函数创建实例对象,必须使用new操作符,以这种方式调用构造函数实际上会经历下面4个步骤:

  1. 创建一个新对象;
  2. 将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
  3. 执行构造函数的代码(为这个新对象添加属性);
  4. 将这个新对象返回(其实构造函数的最后有一条隐式代码return this);
    运用构造函数创建的对象,就可以用instance来检测对象类型了:
console.log(p1 instanceof Person) // true
console.log(p2 instanceof Person) // true

另外再次说明,构造函数也是函数,它和其他函数的不同仅仅在于可以用new来调用创建一个实例对象,当构造函数不用new来调用时那它就和普通函数就没有区别。

构造函数解决了对象的类型检测问题,但是它依然还是存在缺陷的,观察构造函数创建对象的代码,每创建一个对象,就会执行一次Person构造函数,而在函数内部有一个sayName方法,那么每执行一次Person,就会创建一个sayName方法,也就是p1实例的sayName方法和p2实例的sayName方法不是一个方法。

console.log(p1.sayName == p2.sayName) // false

那么当创建多个对象时就会相应的创建多个函数,而同样功能的方法,创建多个是没有必要的。

原型模式

每个函数都有一个prototype属性,同样每个构造函数都有一个prototype,这个属性是一个指针,它指向一个对象,这个对象就是原型对象。而原型对象上的属性是可以被所有由该构造函数创建的实例共享的。
理解原型模式的工作原理必须先理解原型对象,建议先看下上篇文章:理解原型对象
下面是原型模式创建对象的例子:

function Person () {}
Person.prototype = {
    constructor: Person,
    name : 'youyang',
    age : 18,
    colors : ['red', 'yellow', 'blue']
    sayName : function () {
        console.log(this.name)
    }
}
var p1 = new Person()
var p2 = new Person()

而原型模式的缺点一方面,它没办法像构造函数那样传参的方式动态获取不同的属性值,所有的对象实例共享了原型上的属性,它们默认取得的是相同的属性值,另一方面而=原型模式的共享本质导致了更加严重的问题,就是所有实例共享的引用类型属性会相互影响。

p1.colors.push('green')
console.log(p2.colors) // ['red', 'yellow', 'blue', 'green']

可见改变了p1实例的colors属性,然而p2实例受到了影响,这是我们不希望看到的。

组合使用构造函数模式和原型模式

创建自定义类型最常见的方式就是组合使用构造函数模式与原型模式,构造函数模式用于定义实例属性,而原型模式用于定义共享的方法和属性。

function Person (name, age) {
    this.name = name
    this.age = age
    this.colors = ['red', 'yellow', 'blue']
}
Person.prototype = {
    constructor: Person,
    sayName : function () {
        console.log(this.name)
    }
}
var p1 = new Person('youyang', 18)
var p2 = new Person('xiaoqu', 20)
p1.colors.push('green')
console.log(p1.colors) // ['red', 'yellow', 'blue', 'green']
console.log(p2.colors) // ['red', 'yellow', 'blue']
console.log(p1,sayName === p2.sayName) // true

由此可见,原型模式与构造函数模式组合使用,既能动态的定义每个实例对象自己的属性,而且引用类型属性互不影响,同时还共享了原型上的方法。
这种构造函数与原型混合的模式是javascript中使用最广泛认同度最高的一种创建自定义类型的方法。

除了上面介绍的集中创建对象的方式,还有动态原型模式,寄生构造函数模式和稳妥构造函数模式,其中动态原型模式是在组合模式(构造函数模式和原型模式组合使用)的基础上再进一步修改得来,将原型的初始化操作也一同封装进构造函数中。寄生构造函数模式和稳妥构造函数模式也都有相应的应用场景,但是很少使用到,就不一一介绍了。

原文地址:https://www.cnblogs.com/youyang-2018/p/11772696.html

时间: 2025-01-09 15:14:44

JS面向对象篇三、创建对象的几种方法的相关文章

js 面向对象的基本概念和基本使用方法

js 面向对象的基本概念和基本使用方法 -> js 是不是一个面向对象的语言? 不是:与传统面向对象的理论语言有矛盾.C#,Java. 是:js里面到处都是对象,数组,时间,正则- 和 DOM.也可以像传统面向对象的语言那样用 new 的方式创建对象 -> js是一个基于对象的多范式编程语言. 面向过程的方式 面向对象的方式 函数式 递归与链式 例: Jquery 链式编程 面向对象的概念 对象的定义:无序属性的集合,其属性可以包含基本值,对象或是函数 1. 面向:将脸朝向- -> 关注

js 动态加载事件的几种方法总结

本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添加事件,这就涉及到浏览器兼容性问题了,以下谈及的几种方法,我们也常常混合使用. 方法一.setAttributevar obj = document.getElementById("obj");obj.setAttribute("onclick", "javasc

1.1 js 面向对象的基本概念和基本使用方法

js 面向对象的基本概念和基本使用方法 -> js 是不是一个面向对象的语言? 说不是:因为与传统面向对象的理论语言有矛盾.C#,Java. 说是:因为js里面到处都是对象,数组,时间,正则- 和 DOM.也可以像传统面向对象的语言那样用 new 的方式创建对象 -> 其实js是一个基于对象的多范式编程语言.  面向过程的方式 面向对象的方式 函数式 递归与链式 例: Jquery 链式编程 面向对象的概念 对象的定义:无序属性的集合,其属性可以包含基本值,对象或是函数 1. 面向:将脸朝向-

Jsp页面跳转和js控制页面跳转的几种方法

Jsp 页面跳转的几种方法 1. RequestDispatcher.forward() 在服务器端起作用,当使用forward()时,Servlet engine传递HTTP请求从当前的Servlet或者是JSP到另外的一个Servlet.JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在 b.jsp都可以获得,参数自动传递. 但forward()无法重定向至有frame的jsp文件,可以重定向至有

js去掉字符串前后空格的五种方法(转)

出处:http://www.2cto.com/kf/201204/125943.html 第一种:循环检查替换[javascript]//供使用者调用  function trim(s){  return trimRight(trimLeft(s));  }  //去掉左边的空白  function trimLeft(s){  if(s == null) {  return "";  }  var whitespace = new String(" \t\n\r")

JS中date日期初始化的5种方法

原文:JS中date日期初始化的5种方法 创建一个日期对象: 代码如下: var objDate=new Date([arguments list]); 参数形式有以下5种: 1)new Date("month dd,yyyy hh:mm:ss"); 2)new Date("month dd,yyyy"); 3)new Date(yyyy,mth,dd,hh,mm,ss); 在程序中我使用的第三种初始化方法,总是显示格式化的参数不正确,仔细看了一下一定要是整型的才可

js中常用追加元素的几种方法:append,appendTo,after,before,insertAfter,insertBefore,appendChild

js中常用追加元素的几种方法,点击下面每个按钮,即可查看效果 我是第一个子元素 我是第二个子元素 append appendTo prepend prependTo after before appendChild insertAfter insertBefore

js面向对象之:创建对象

最近在学习<js高级程序设计>,之前所接触的很多的js类库和jQuery插件都会用面向对象的方式来设计,而自己却还是停留在面向方法的阶段,所以今天好好记录一下学习的js创建对象. 第一种方式:工厂模式 function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; ret

js面向对象程序设置——创建对象

<script type="text/javascript">            //工厂方式        //1.原始方式        /* var objCar=new Object();        objCar.name="劳斯莱斯";        objCar.color="blue";        objCar.showColor = function() {          alert(this.colo