js 面向对象几种数据模式
一、单例模式:
把描述同一事物的属性和方法放在同一内存空间下,实现了分组的作用,防止同一属性或者方法冲突。我们把这种分组编写代码的模式叫做单例模式即普通的对象。
单例模式是项目开发中最常用的一种开发模式,可以使用单例模式实现模块开发
二、工厂模式
单例模式虽然实现了分组的作用,但是不能进行批量的生产,属于手工作业模式——》工厂模式
通俗的讲:为实现同一件事情,把相同的代码放到同一个函数,即函数的封装——》低耦合高内聚,减少代码冗余,提高代码重复使用率
三、构造函数模式
构造函数模式的目的:创建一个自定义类,并且创建这个类的一个实例
在构造函数模式中浏览器默认返回当前类的实例,如果我们手动返回一个基本数据类型的值,则当前的类还是浏览器默认返回的类的实例,如果手动返回一个引用数据类型的值则将浏览器默认返回的当前类的实例替换。
构造函数模式和工厂模式(普通函数)的区别:
1、执行的时候。工厂模式:普通函数执行。构造函数模式:var p1 = new Fn(),通过new执行之后,fn就是一个类。为了规范函数名字第一个单词大写,p1就是当前类的一个实例,不是变量。JS中的所有的类都是函数数据类型的,所有的实例都是对象数据类型的。如果Fn中不带参数则Fn后面的括号可以省略 var p1 = new Fn;
2、函数体中的代码执行的时候:
(1)相同点:都形成一个私有作用域:形参赋值—》域解释—》代码从上到下执行
(2)不同点:类在执行之前不用手动创建obj这个对象了,浏览器会默认的隐式创建一个对象数据类型的值,这个对象就是当前类的一个实例p1,接下来代码从上到下执行,以当前类的实例为主题,而this指得就是当前类的一个实例p1,然后分别给当前类赋值属性名和属性值。浏览器默认的会把创建的实例返回
instanceof:如何检测某个实例是否属于这个类?
var f1 = new Fn()
console.log(f1 instanceof Fn) // true
console.log(f1 instanceof Array) //false
对象数据类型检测方面:typeof有自己到局限性,无法检测引用数据类型的值,不能细分object下的数组、对象、正则。。。
in:检测某个属性是否属于这个对象。不管当前属性是私有属性还是共有属性,都返回true。
· attr in object
console.log("name" in f1) //true
hasOwnproperty:检测某个属性是否属于这个对象的私有属性,只能检测是不是私有属性,如果不是私有属性则返回false
function Fn(){
this.name:"sssss";
this.getX:function(){
console.log("this.name")
}
}
var f1 = new Fn()
console.log(f1.hasOwnProperty("getX")) //true
检测某一个属性为该对象的共有属性?首先保证是一个属性,并且该属性不是私有的。
console.log("name" in f1 && !f1.hasOwnProperty("name"))
isPrototypeOf:
用于检测对象是否存在于另一个对象的原型链中。如果存在,返回true
,否则返回false
。
prototypeObject.isPrototypeOf( object )
// isPrototypeOf()
函数的返回值为Boolean类型。如果object
当前的原型链中存在prototypeObject
对象,则isPrototypeOf()
方法返回true
。原型链用于在同一个对象类型的不同实例之间共享功能。如果object
不是对象,或者prototypeObject
对象不出现在object
的原型链中,则该方法返回false
。
四、原型模式
构造函数模式中虽然拥有了类和实例的概念,并且实例和实例之间是独立的 —》js中称实例识别,生活中称品牌区分。
function CreatJsPerson(name,age){
this.name:name;
this.age:age;
this.writeJs:function(){
console.log("my name is " +this.name+" i can write JS");
}
}
var p1 = new CreatJsPerson("xiaowang",26);
var p2 = new CreatJsPerson("xiaoma",18);
console.log(p1.writeJs === p2.writeJs) // false 说名writeJs 是彼此私有的,所有不相等
给予构造函数模式的原型模式解决了方法或者属性共有的问题—》把相同的属性或者方法提取成共有的属性或者方法,想让谁共有,就把谁放在当前类的原型上即可,如:
function CreatJsPerson(name,age){
this.name:name;
this.age:age;
}
creatJsPerson.prototype.writeJs = function(){
console.log("my name is " +this.name+" i can write JS");
}
var p1 = new CreatJsPerson("xiaowang",26);
var p2 = new CreatJsPerson("xiaoma",18);
console.log(p1.writeJs === p2.writeJs) // true
1、每一个函数数据类型(普通的函数和类)都天生自带一个属性:prototype(原型),并且这个属性是一个对象数据类型的值,并且在prototype上浏览器天生给它加了一个属性constructor(构造函数),constructor的属性值是当前函数或者类本身
2、每一个对象数据类型(普通的对象,实例,prototype...)也天生再带一个属性:__proto__,属性值是当前实例所属类的原型(prototype);
function Fn(){
this.x = 100;
}
Fn.prototype.getX = function(){
console.log(this.x)
}
var f1 = new Fn;
var f2 = new Fn;
console.log(Fn.prototype.constructor === Fn) // true
原型模式扩展:
批量设置原型上的共有属性和方法,常见方式有两种
1、别名法: var pro = Fn.prototype; // 把原来原型指向的地址复制给变量pro; 现在他们操作的同一个作用空间。列:
pro.getX = function(){};
pro.getY = function(){};
.....
2、重构原型对象的方式:
原理:自己开辟一个新的堆内存空间,存储我们共有的属性和方法,把浏览器原来自动开辟的空间替换掉,浏览器在空闲时将自动开辟的空间释放
function Fn(){
this.x = 100;
}
Fn.prototype = {
construct:Fn, //为了和原来的保持一致,我们需要手动增加一个construct:Fn;
a:function(){
},
b:function(){
}
}
var f = new FN;
(1)、自定义类:console.log(f.construct) 注意点: // Object 原因:因为浏览器开辟的空间被释放了,只有浏览器自动开辟的空间中才有constructor属性,我们手动开辟的空间中没有construct属性,通过__proto__找到Object上的原型中的construct属性,所有属性值为Object。为了和原来的保持一致,我们需要手动增加一个construct:Fn;
(2)、内置类:如果用这种方式给内置类增加共有的属性和方法:
Array.prototype = {
constructor:Array,
unique:function(){
console.log("sa");
}
}
会导致一下问题:
1、之前在Array类的原型上有很多方法,我们之中方式会把之前已经存在原型上的属性和方法替换了,如果我们用这种方式修改的话,浏览器会自动屏蔽我们的方法;
2、但是我们可以一个个的修改内置类中的方法,当我们以以下方式在数组的原型上增加sort方法,如果方法名字一致,则会把之前内置类上的sort方法替换了,所有我们在数组的原型上增加方法我们加一个特殊的前缀,以防止修改内置类中的属性及方法
Array.prototype.sort = function(){
console.log("OK"); //会执行OK 不会进行排序
}
var arr = [1,2,3,4,5,3,2,7]
arr.sort() ; //
五、原型链模式:
f1.hasOwnPrototype("x") x是不是f1的私有属性
在当前f1这个实例的类上并没有hasOwnPrototype()这个方法,那是如何处理的呢?
当通过对象名.属性名的方式获取属性值得时候,首先会在对象的私有方法中找该属性,如果找到了该属性则用当前的属性值;
如果找不到则通过__proto__找到当前所属类的原型(在类的原型上定义的属性和方法是当前实例共有的),如果原型上存在的话,则获取的为共有的属性值;
如果原型上也没有,则通过原型上的属性__proto__ 继续向上查找,一直找到Object.prototy为止
这种查找的机制称之为原型链模式。
f1.hasOwnPrototype —》 f1.__proto__.__proto__.hasOwnPrototype
在IE浏览器中原型链模式也是同样的原理,但是IE浏览器中为防止通过__proto__修改公有的属性或者方法,禁止使用__proto__。为了兼容所有浏览器我们可以使用Fn.prototype.属性名进行修改。
链式写法:执行完数组的方法可以接着执行另外的一个方法。
可枚举属性和不可枚举属性:prototypeIsEnumerable
for...in... 循环在遍历的时候会默认的把私有的属性和在他内置类原型上定义的共有属性和方法遍历到,但是我们一般情况下只遍历私有的属性即可:
Object.prototype.fn = function(){console.log("ok");}
var obj = {name:"ywx354980",age:25};
for(var key in obj){
// 用以下的方式判断是否可枚举,或者是不是私有的属性
if(obj.protopertyIsEnumerable(key)){console.log(key)} 或者 if(obj.hasOwnPrototype(key){console.log(key)})
}
js 面向对象几种数据模式的更多相关文章
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂 ...
- js面向对象小结(工厂模式,构造函数,原型方法,继承)
最近过了一遍尼古拉斯泽卡斯的高级程序设计第三版(红皮书)第六章:面向对象程序设计,现在把总结出来的东西和大家分享一下. 主要内容如下: 1.工厂模式 2.构造函数模式 3.原型模式 4.继承 一.工厂 ...
- js面向对象编程 ---- 系列教程
原 js面向对象编程:数据的缓存 原 js面向对象编程:如何检测对象类型 原 js面向对象编程:if中可以使用那些作为判断条件呢? 原 js面向对象编程:this到底代表什么?第二篇 原 js面向对象 ...
- JS面向对象函数的四种调用模式
函数的四种调用模式 概念 在 js 中,无论是函数, 还是方法, 还是事件, 还是构造器,...这些东西的本质都是函数 函数, 方法, 事件, 构造器,...只是所处的位置不同 这四种模式分别是 函数 ...
- 【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )
参考书籍 <JavaScript高级语言程序设计>—— Nicholas C.Zakas <你不知道的JavaScript> —— KYLE SIMPSON 在JS的面向 ...
- js面向对象(对象/类/工厂模式/构造函数/公有和原型)
https://www.cnblogs.com/sandraryan/ 什么是对象 js中一切都是对象(有行为和特征).js允许自定义对象,也提供了内建对象(string date math等) 对象 ...
- JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- js架构设计模式——你对MVC、MVP、MVVM 三种组合模式分别有什么样的理解?
你对MVC.MVP.MVVM 三种组合模式分别有什么样的理解? MVC(Model-View-Controller)MVP(Model-View-Presenter)MVVM(Model-View-V ...
- JS面向对象之工厂模式
js面向对象 什么是对象 "无序属性的集合,其属性可以包括基本值.对象或者函数",对象是一组没有特定顺序的的值.对象的没个属性或方法都有一个俄名字,每个名字都映射到一个值. 简单来 ...
随机推荐
- 20140312 Excel表格画折现图次坐标轴
1.struct 是8字节对齐 2.char * a, sizeof(a)=4; char a[]="abcdefg";sizeof(a)=8; 3.内存对其齐
- 《转》python数据类型
转自 http://www.cnblogs.com/BeginMan/archive/2013/06/08/3125876.html 一.标准类型函数 cmp():比较大小 str():转换为字符串 ...
- Docker学习のC/S模式
我们操作docker是通过命令行客户端,然后和守护进程通信 以前的是通过命令行 我们还可以通过RemoApI的形式,通过自己的程序访问docker 和守护进程链接方式
- Jmeter压测快速体验
前言 最近在看neo4j相关的官网文档以及一些调优参数,同时也学了下Jmeter,为了测试下neo4j服务的性能,虽然不是专业搞测试的,但是我觉得每个优秀的开发者都应该学会主动压测自己服务和代码的性能 ...
- input输入内容成可点击状态
<!DOCTYPE html> <html> <head> <script src="//code.jquery.com/jquery-1.9.1. ...
- [转]关于Repository模式
原文链接:关于Repository模式 定义(来自Martin Fowler的<企业应用架构模式>): Mediates between the domain and data mappi ...
- FTP、SFTP、SCP、SSH、OpenSSH关系解密
FTP(File Transfer Protocol):是TCP/IP网络上两台计算机传送文件的协议,FTP是在TCP/IP网络和INTERNET上最早使用的协议之一,它属于网络协议组的应用层.FTP ...
- offset系列属性
offset系列:获取元素的相关的样式属性的值 offsetwidth:获取元素的宽 offsetheight:获取元素的高 offsetleft:获取元素距离左边位置的值 offsettop;获取元 ...
- duilib教程之duilib入门简明教程6.XML配置界面
前面那些教程都是为了让小伙伴们从win32.MFC过渡到duilib,让大家觉得duilib不是那么陌生,如果大家现在还对duilib非常陌生的话,那就说明前面的教程做得不好,请大家在下面留言,我会一 ...
- BZOJ 1398: Vijos1382寻找主人 Necklace(最小表示法)
传送门 解题思路 最小表示法.首先对于判断是不是循环同构的串,直接扫一遍用哈希判即可.然后要输出字典序最小的就要用到最小表示法,首先可以把串复制一遍,这样的话就可以把串变成静态操作.如果对于两个位置\ ...