JS 面向对象 ~ 创建对象的 9 种方式
一、创建对象的几种方式
1、通过字面量创建
var obj = {}; 这种写法相当于: var obj = new Object();
缺点:使用同一个接口创建很多单个对象,会产生大量重复代码
2、通过 工厂模式 创建对象
function createPerson(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = createPerson('gaosirs', 'teacher')
var person2 = createPerson('X', 'Doctor')
缺点:工厂模式虽然解决了创建多个相似对象的问题,但没解决对象识别的问题(即怎样知道一个对象的类型)。
3、通过 构造函数 创建对象
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
};
} var person1=new Person(...);
var person2=new Person(...);
缺点:使用构造函数,每个方法都要在每个实例上重新创建一遍。
4、通过 原型模式 创建对象
function Person() {
}
Person.prototype.name = 'Gaosirs'
Person.prototype.job = 'teacher'
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person();
person1.sayName(); //Gaosirs
更简单的写法:
function Person() {
}
Person.prototype = {
name: 'Gaosirs',
job: 'teacher',
sayName: function() {
console.log(this.name)
}
}
var person1 = new Person()
person1.sayName() // Gaosirs
缺点:
使用原型,所有的属性都将被共享,这是个很大的优点,同样会带来一些缺点
原型中所有属性实例是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性也勉强可以,毕竟实例属性可以屏蔽原型属性。但是引用类型值,就会出现问题了
function Person() {
}
Person.prototype = {
name: 'jiang',
friends: ['Shelby', 'Court']
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) //["Shelby", "Court", "Van"]
console.log(person1.friends === person2.friends) // true
5、组合使用构造函数模式和原型模式 创建对象
这是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点
使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用
这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了
function Person(name) {
this.name = name
this.friends = ['Shelby', 'Court']
}
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) // ["Shelby", "Court"]
console.log(person1.friends === person2.friends) //false
6、使用 动态原型模式 创建对象
动态原型模式将所有信息都封装在了构造函数中,初始化的时候,通过检测某个应该存在的方法时候有效,来决定是否需要初始化原型
function Person(name, job) {
// 属性
this.name = name
this.job = job
// 方法
if(typeof this.sayName !== 'function') {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
var person1 = new Person('Gaosirs', 'Teacher')
person1.sayName()
只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。
此后原型已经完成初始化,不需要在做什么修改了
这里对原型所做的修改,能够立即在所有实例中得到反映
其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行
7、使用 寄生构造函数模式 创建对象
这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象
function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = new Person('Gaosirs', 'student')
person1.sayName()
这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样
构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值
8、使用 稳妥构造函数模式 创建对象
首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。
稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用
稳妥构造函数模式和寄生模式类似,有两点不同:一是创建对象的实例方法不引用this,而是不使用new操作符调用构造函数
function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(name)
}
return o
}
var person1 = Person('Gaosirs', 'student')
person1.sayName()
变量 person1 中保存的是一个稳妥对象,而除了调用 sayName() 方法外,没有别的办法访问其数据成员。
和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义
9、使用 Object.create() 方法创建对象
Object.create() 方法使用现有的对象来提供新创建的对象的__proto__。
const person = {
isHuman: false,
printIntroduction: function () {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
}; const me = Object.create(person); me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten me.printIntroduction();
详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
随笔整理自
https://www.jb51.net/article/117164.htm
《JavaScript 高级程序设计 第三版 》138页 第六章 面向对象的程序设计
感谢博主分享!
JS 面向对象 ~ 创建对象的 9 种方式的更多相关文章
- js中面向对象(创建对象的几种方式)
1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象 ...
- js中创建对象的几种方式
创建对象指创建一个object并给这个对象添加属性和方法,有以下几个方式: 最基本的: var Person={}; Person.name='tom'; Person.age='20'; Perso ...
- js中创建对象的三种方式
1. 对象字面量 var obj={ name:"小小", age:3, car:{ brand:"baoma", } }; } 2.使用内置构造函数 var ...
- JS 面向对象 ~ 继承的7种方式
前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...
- 【Js】创建对象的6种方式总结、(底部包含属性名为动态的形式)
一.new 操作符 + Object 创建对象 1 var person = new Object(); 2 person.name = "lisi"; 3 person.age ...
- 比较js中创建对象的几种方式
1.工厂模式 function createObj(name, sex){ var obj = new Object(); obj.name = name; obj.sex = sex; obj.sa ...
- js中面向对象(创建对象的几种方式)
1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 注:本文引用于 http://www.cnblogs. ...
- 第184天:js创建对象的几种方式总结
面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象简单 ...
- js创建对象的三种方式和js工厂模式创建对象
文章地址: https://www.cnblogs.com/sandraryan/ 创建对象 创建对象的三种方式 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象 1. 调用系统的构造函数 ...
随机推荐
- c/c++ 标准顺序容器 容器的访问,删除 操作
c/c++ 标准顺序容器 容器的访问,删除 操作 pop_front:vector,string不支持 pop_back:forward_list不支持 知识点 1,front, back, at 成 ...
- Windows Server 2016-系统安装软硬件要求
本章为大家补充介绍安装 Windows Server 2016的最低系统要求. 如果安装时选择通过"服务器核心"选项进行安装,则应注意,没有安装任何 GUI 组件,并且将不能使用服 ...
- MySql基本使用方法
一,基本概念 1, 常用的两种引擎: (1) InnoDB a,支持ACID,简单地说就是支持事务完整性.一致性: b,支持行锁,以及类似ORACLE的一 ...
- 【算法】LeetCode算法题-Roman To Integer
这是悦乐书的第145次更新,第147篇原创 今天这道题和罗马数字有关,罗马数字也是可以表示整数的,如"I"表示数字1,"IV"表示数字4,下面这道题目就和罗马数 ...
- Python中进程线程协程小结
进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...
- js模块化规范—CMD规范
CMD规范说明 专门用于浏览器端, 模块的加载是异步的 ,模块使用时才会加载执行,github地址 CMD基本语法 定义暴露模块 //定义有依赖的模块 define(function(require, ...
- centos7下安装docker(16.docker跨主机存储)
从业务数据的角度看,容器可以分为两类:无状态(stateless)容器和有状态(stateful)容器. 无状态:是指容器在运行的过程中不需要保存数据,每次访问的结果不依赖上一次的访问,比如提供静态页 ...
- 想要快速上手 Spring Boot?看这些教程就足够了!
1.项目名称:分布式敏捷开发系统架构 项目简介:基于 Spring + SpringMVC + Mybatis 分布式敏捷开发系统架构,提供整套公共微服务服务模块:集中权限管理(单点登录).内容管理. ...
- 转://Oracle中User和Schema的区别和联系
今天在阅读Oracle官方文档的时候,读到schema的基本概念,这就让我产生了一个疑问:user和schema两者之间到底有什么区别?为了更深层次的理解二者之间的区别和联系,以下是官方文档中关于us ...
- Redis主从数据库同步
Redis主从同步原理-SYNC和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采 ...