javaScript设计模式核心原理学习记录(二)
单例模式
概念:保证一个类仅有一个实例,并提供一个访问它的全局节点。
一般情况我们通过new构造函数,可创建任意实例。
(1)静态方法:
es6语法:类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上
static
关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
//静态方法
class Storage {
static getInstance(){
//判断是否已经new过实例
if(!Storage.instance){
Storage.instance = new Storage()
}
return Storage.instance
}
getStorage(key){
return localStorage.getItem(key)
}
setStorage(key,value){
return localStorage.setItem(key,value)
}
}
const storagfe1 = Storage.getInstance()
const storagfe2 = Storage.getInstance()
storagfe1.setStorage('name', '张三')
storagfe1.getStorage('name') //张三
storagfe2 == storagfe1 //true
//闭包方法
function StorageBase(){
StorageBase.prototype.setItem = function (key,value) {
return location.setItem(key,value)
}
StorageBase.prototype.getItem = function (key) {
return location.getItem(key)
}
}
const Storage = (function(){
let instance = null;
return function () {
if(!instance){
instance = new StorageBase()
}
return instance
}
})()
const storagfe1 = new Storage()
const storagfe2 = new Storage()
storagfe1.setItem('name','张三')
storagfe2.getItem('name')
(2)闭包版:
// 先实现一个基础的StorageBase类,把getItem和setItem方法放在它的原型链上
function StorageBase () {}
StorageBase.prototype.getItem = function (key){
return localStorage.getItem(key)
}
StorageBase.prototype.setItem = function (key, value) {
return localStorage.setItem(key, value)
}
// 以闭包的形式创建一个引用自由变量的构造函数
const Storage = (function(){
let instance = null
return function(){
// 判断自由变量是否为null
if(!instance) {
// 如果为null则new出唯一实例
instance = new StorageBase()
}
return instance
}
})()
// 这里其实不用 new Storage 的形式调用,直接 Storage() 也会有一样的效果
const storage1 = new Storage()
const storage2 = new Storage()
storage1.setItem('name', '李雷')
// 李雷
storage1.getItem('name')
// 也是李雷
storage2.getItem('name')
// 返回true
storage1 === storage2
原型模式
原型模式不仅是一种设计模式,它还是一种编程范式(programming paradigm),是 JavaScript 面向对象系统实现的根基。
概念:在原型模式下,当我们想要创建一个对象时,会先找到一个对象作为原型,然后通过克隆原型的方式来创建出一个与原型一样(共享一套数据/方法)的对象。在 JavaScript 里,Object.create
方法就是原型模式的天然实现——准确地说,只要我们还在借助Prototype
来实现对象的创建和原型的继承,那么我们就是在应用原型模式。
ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为 JavaScript 引入新的面向对象的继承模型。 ——MDN
原型编程范式的核心思想就是利用实例来描述对象,用实例作为定义对象和继承的基础。在 JavaScript 中,原型编程范式的体现就是基于原型链的继承。这其中,对原型、原型链的理解是关键。
原型:
在 JavaScript 中,每个构造函数都拥有一个prototype
属性,它指向构造函数的原型对象,这个原型对象中有一个 constructor 属性指回构造函数;每个实例都有一个__proto__
属性,当我们使用构造函数去创建实例时,实例的__proto__
属性就会指向构造函数的原型对象。
// 创建一个Dog构造函数
function Dog(name, age) {
this.name = name
this.age = age
}
Dog.prototype.eat = function() {
console.log('肉骨头真好吃')
}
// 使用Dog构造函数创建dog实例
const dog = new Dog('旺财', 3)
原型链:
// 输出"肉骨头真好吃"
dog.eat()
// 输出"[object Object]"
dog.toString()
明明没有在 dog 实例里手动定义 eat 方法和 toString 方法,它们还是被成功地调用了。这是因为当我试图访问一个 JavaScript 实例的属性/方法时,它首先搜索这个实例本身;当发现实例没有定义对应的属性/方法时,它会转而去搜索实例的原型对象;如果原型对象中也搜索不到,它就去搜索原型对象的原型对象,这个搜索的轨迹,就叫做原型链。
深拷贝和浅拷贝?
js变量类型分为值类型(基本类型)和引用类型 值类型:Number,Undifine,String,Boolend,Null 深拷贝和浅拷贝针对的都是引用类型 对值类型复制操作,会拷贝一份值,而对引用类型复制,则会复制地址
//值类型(基本类型)复制
var a = 1;
var b = a;
a = 2 ;
console.log(a,b) //2,1
//引用类型
var a = {c:1}var b = a;a.c = 2;
console.log(a.c,b.c) //2,2
浅拷贝(实际上遍历对象属性)
function shallowClone(source){
if(typeof source != 'object' || source == null){
return source
}
let copy = {}
if(Object.prototype.toString.call(source) == '[object Array]'){
copy = []
}
for(let key in source){
copy[key] = source[key]
}
return copy
}
深拷贝(浅拷贝加递归)
function deepCopy (obj) {
if(typeof obj != 'object' || obj == null){
return obj
}
let copy = {};
if(Object.prototype.toString.call(obj) == '[object Array]'){
copy = []
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
copy[key] = deepCopy(obj[key])
}
}
return copy;
}
deepCopy([{id:1,name:'萨达萨达'}])
//值类型(基本类型)复制
var a = 1;
var b = a;
a = 2 ;
console.log(a,b) //2,1
//引用类型
var a = {c:1}
var b = a;
a.c = 2;
console.log(a.c,b.c) //2,2
工具深拷贝(json.stringfy)
const liLei = {
name: 'lilei',
age: 28,
habits: ['coding', 'hiking', 'running']
}
const liLeiStr = JSON.stringify(liLei)
const liLeiCopy = JSON.parse(liLeiStr)
liLeiCopy.habits.splice(0, 1)
console.log('李雷副本的habits数组是', liLeiCopy.habits)
console.log('李雷的habits数组是', liLei.habits)
转载自:https://juejin.cn/post/6903449047496376327