1.singleton pattern(单例模式)
表现形式:
var obj={
xxx:xxx
}
单例设计模式中,obj不仅仅是对象名,它被称为
命名空间[nameSpace]
,把描述事物的属性存放到命名空间中,多个命名空间是独立开来的,互不冲突
作用:
把描述同一件事物的属性和特征进行
分组,归类
(存储在同一个堆内存空间中),因此避免了全局变量之间的冲突和污染
var p1={name:'zs',age:18}
var p2={name:'ls',age:20}
由来:
每一个nameSpace都是JS中Object这个内置基类的实例,而实例之间是相互独立互不干扰的,所有我们称它为
单例:单独的实例
高级单例模式:
在给namespace赋值的时候,不是直接赋值一个对象,而是先执行匿名函数,形成一个私有作用域(不销毁的栈内存),把栈内存地址赋值给namespace
这种模式的好处,我们完全可以在这个栈内存中创造很多内容(变量OR函数),哪些需要提供外面调用的,我们暴露到返回对象中(模块化实现的一个种思想)
var person=(function(){
var name='张三',
function getName() {
return name
}
function setName(val) {
name=val
}
return {
getName,
setName
}
})()
2.this
给当前元素的某个时间绑定方法,当事件触发方法执行的时候,方法中的this是当前操作的元素对象
body.onClick=function(){
//=>this:body
}
普通函数执行,函数中的this取决于执行主体,谁执行的,this就是谁(执行主体:方法执行,看方法名前面是否都
点
,有的话,点前面是谁,this就是谁,没有this就是window)自执行函数执行是,方法中的this是window
function fn(){
console.log(1)
}
var obj={
fn:fn
}
obj.fn()//=>this:obj
fn()//this:window
~function(){
//=>this:window
}()
案例:
var n = 2;
var obj={
n:3,
fn:(function (n) {
n*=2;
this.n+=2;
var n=5;
return function (m) {
this.n*=2;
console.log(m + (++n));
}
})(n)//=>obj.n会报错
};
var fn = obj.fn;
fn(3);
obj.fn(3);
console.log(n, obj.n);
3.Factory Pattern工厂模式
-
把实现相同功能的代码进行
封装
,以此来实现批量生产
(后期想要实现这个功能,我们只需要执行函数即可) -
低耦合高内聚
,减少页面中冗余代码,提高代码重复使用率
function Person(name,age) {
var obj={}
obj.name=name
obj.age=age
return obj
}
var p=new Person('张三',19)
var p=new Person('李四',20)
4.OOP(面向对象)
JS是一门面向对象编程语言
对象:万物皆对象
类:对象的具体细分(按照功能特点进行分类:大类,小类)
实例:类中具体的一个事物(拿出类别中的具体一个实例进行研究,那么当前类别下的其它实例也具备这些特点和特征)
我们可以把人看成一个对象,其中男人是一个类,张三就是一个实例
5.constructor
基于构造函数创建自定义类(constructor)
在普通函数执行的基础上加上new,如new Fun(),这样就是构造函数执行,当前的函数名称成为
类名
,接受的返回结果是当前类的一个实例自己创建的类名,最好首字母大写
这种构造函数设计模式执行,主要用于组件,类库,插件,框架等的封装
function Fn() {
}
Fn()//普通函数的执行
var fn=new Fn()//Fn为一个类,fn为类的实例对象
JS中创建值有两种方式:
-
字面量表达式
-
构造函数模式
var obj={}//字面量表达式
var obj=new Object()//构造函数模式
基本数据类型基于两种不同的模式创建出来的值不一样
-
基于字面量方式创建出来的值是基本类性值
-
基于构造函数创建出来的值是引用类型
//num1是数字类的实例,num2也是数字类的实例,它只是JS表达式数字的方式之一,都可以使用数字提供的属性和方法
var num1=1
var num2=new Number(1)
console.log(typeof num1);//=>number
console.log(typeof num2);//=>object
普通函数执行&构造函数执行对比:
function Fn(name,age){
var n=10
this.name=name
this.age=age+n
}
普通函数执行
Fn()
-
形成私有作用域
-
形参赋值
-
变量提升
-
代码自上而下执行
-
栈内存释放问题
构造函数执行
var f1=new Fn('zhangsan',18)
var f2=new Fn('lisi',20)
console.log(f1===f2)//=>false,两个不同的实例,不同的内存地址
console.log(f1.n)//=>undefined,只有this.xxx=xxx的才和实例有关系,n是私有作用域中的一个私有变量而已(this是当前类的实例)
构造函数执行机制
function Person(name,age){
var n=10
this.name=name
this.age=age+n
}
var p=new Person('zhangsan',10)
构造函数return的问题
-
不写return,浏览器会默认返回创建的实例
-
return的是一个基本类型,返回结果依然是类的实例,没有受到影响
-
return的是一个引用类型,则会把默认返回的实例覆盖,此时接收的结果就不在是当前类的实例了
-
构造函数执行时,尽量减少return的使用,放置覆盖实例
function Fn(name,age){
this.name=name
this.age=age
return name//返回的基本数据类型
}
var fn=new Fn('张三',18)
console.log(fn);//=>Fn {name: "张三", age: 18}
function Fn2(name,age){
this.name=name
this.age=age
return {//返回的引用数据类型
name
}
}
var fn2=new Fn2('张三',18)
console.log(fn2);//=>{name: "张三"}
省略小括号
在构造函数执行的时候,如果Fn不需要传递实参,我们可以省略小括号
function Fn(){}
var f=new Fn//=>等价于new Fn()
6.instanceof&in&hasOwnProperty
6.1.instanceof
检测某个实例是否隶属于这个类
function Fn(){}
var f=new Fn
console.log(f instanceof Fn);//=>true
console.log(f instanceof Array);//=>false
console.log(f instanceof Object);//=>true
6.2.in
检测当前对象是否存在某个属性(不管当前这个属性是对象的
私有属性
还是公有属性
,只要有结果就是true)
function Person(name,age){
var n=10
this.name=name
this.age=age+n
}
var p=new Person('zhangsan',10)
console.log('name' in Person );//=>true,私有属性
console.log('n' in Person);//=>false
console.log('toString' in Person);//=>true,公有属性
6.3.hasOwnProperty
检测当前属性是否为对象的私有属性(不仅要有这个属性,而且必须还是
私有
的属性)
function Person(name,age){
var n=10
this.name=name
this.age=age+n
}
console.log(p.hasOwnProperty('name'));//=>true
console.log(p.hasOwnProperty('n'));//=>false
console.log(p.hasOwnProperty('toString'));//=>false
7.原型&原型链
函数:普通函数,类(所有的类:内置类,自己创建的类)
对象:
-
普通对象,数组,正则,Math,arguments...
-
实例是对象类型的(除了基本类型的字面量创建的值)
-
prototype的值也是对象类型的
-
函数也是对象类型的
所有的函数数据类型都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存
在浏览器个prototype开辟的内存中有一个天生自带的属性:constructor,这个属性存储的值是当前函数本身
每个对象都有一个
__proto__
的属性,这个属性指向当前实例所属类的prototype(如果不能确定它是谁的实例,都是Object的实例)
function Fn() {
var n = 100;
this.AA = function () {
console.log(`AA[私]`);
};
this.BB = function () {
console.log(`BB[私]`);
};
}
Fn.prototype.AA = function () {
console.log(`AA[公]`);
};
var f1 = new Fn;
var f2 = new Fn;
f1.AA()
f2.BB()
console.log(f1.hasOwnProperty===Fn.prototype.hasOwnProperty);
7.ES6
7.1.解构赋值
/** * 数组 */ let arr=['zhangsan',18,'男'] let [name,age,sex]=arr console.log(name,age,sex);//=>zhangsan 18 男 let [name]=arr console.log(name); let [a,...b]=arr console.log(a,b); let [,,a]=arr console.log(a); let [,,,,a=0]=arr console.log(a);//=>0 赋值默认值 /** * 对象 */ let obj={name:'zhangsan',age:27} let {name,age}=obj console.log(name,age); let {age:ageA}=obj//设置别名 console.log(ageA); let {age=18}=obj console.log(age);//=>设置默认值 let data={ name:'zhangsan', age:18, score:[ 100, 89, 79 ] } let {name,age,score:[chinese,english,math]}=data /** * 案例 */ //交换两个变量的值 let a=1, b=2 [b,a]=[a,b]
/** * 1.扩展运算符 * 2.剩余运算符 * 3.展开运算符 */ //=>对象克隆[展开运算符] let obj={name:'zhangsan',age:18} let newObj={...obj} console.log(newObj);
7.2.箭头函数:
/** * 箭头函数 * 1.箭头函数没有arguments * 2.箭头函数中没有自己的执行主体(this),它的this都是继承上下文中的this */ let fn=(x,y,z)=>{} fn(1,2,3) //只传递一个参数 let fn=x=>{} //带返回值 let fn=(x,y)=>x+y
文章笔录之珠峰视频