JS中的面向对象编程详解

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

文章笔录之珠峰视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值