JavaScript核心知识总结(二)

面向对象(OOP)和this的处理

* 面向对象

JS是一门编程语言(具有编程思想)
【面向对象】JS\JAVA\PHP\Ruby\Python
【面向过程】C\C++
【面向对象编程】 对象、类、实例

  • 对象:万物皆对象
  • 类:对象的具体细分(按照功能特点进行分类:大类、小类)
  • 实例: 类中具体的一个事物(拿出类中的具体一个实例进行研究,那么当前类下的其他实例也具备这些特点和特征)
    整个JS就是基于面向对象设计和开发出来的语言,我们学习和实战的时候也要按照面向对象的思想去体会和理解
    【JS中的内置类】
一 单例设计模式(Singleton Pattern)
  • 单例设计模式解决的问题
  1. 表现形式:
    var obj={
		   name:"dxy",
		    age:18	
			};
	//在单例设计模式中,obj不仅仅是对象名,**它被称为命名空间**把描述事物的属性存放到命名空间中,多个命名空间是独立分   //开的,互不冲突。
  1. 作用:把描述同一件事物的属性和特征进项 分组 、分类(存储在同一个堆内存空间中),因此避免了全局变量之间的冲突和污染。
var obj1={name:"xxx"}
var obj2={name:"xxx"}

obj1!=obj2

  1. 为什么叫做单例设计模式:
    每一个命名空间都是JS中Object这个内置基类的实例,而实例之间是相互独立互不干扰的,所以我们称之为单例,单独的实例。
  • 高级单例模式
  1. 在给命名空间赋值的时候,不是直接赋值一个对象,而先执行一个匿名函数,形成一个私有作用域AA(不销毁的栈内存),在AA中创建一个堆内存,把堆内存地址赋值给命名空间。
  2. 这种模式的好处:
    我们完全可以在AA中创造很多内容(变量或者函数),那些需要供外面调用,我们就暴露到返回对象中(模块化实现的一种思想)。
var nameSpace=(function(){
				var n=12;
				function fn(){
					//...
				}
				return {
					fn:fn  //创建堆内存
				}
			})();
  • 基于单例模式实现模块化开发
    1. 模块化开发
      1.1 团队协作开发的时候会把产品按照功能模块进行划分,每一个模块有专门人负责开发
      1.2 把各个板块之间公用的部分进行提取封装,后期想实现这些功能,直接调取应用即可(模块封装)
//模块封装
			var skipRender=(function(){
				var fn=function(){};
				return {
					init:function(){
					
					},
					fn:fn
				}
			})();
			skipRender.init();
			
			//天气模块
			var weather=(function(){
				var fn=function(){
					
				};
				return {
					init:function(){
						fn();//调取自己模块中的方法直接调用即可。
						skipRender.fn();
					}
				}
			})();
			weather.init();

【工厂模式(Factory Pattern)】

  1. 把实现相同功能的代码进行封装,以实现批量生产,后期我们想要实现这个功能,我们只需要执行函数即可。
  2. 低耦合高内聚:减少页面中的冗余代码,提高代码的重复使用率。
function createPerson(name,age){
				var obj={};
				obj.name=name;
				obj.age=age;
				return obj;
			}
			var p1=createPerson("hhh",10);
			var p1=createPerson("xxx",18);
二 类和实例
三 constructor 构造函数设计模式
  • 基于构造函数创建基本值
  1. 在普通函数执行的基础上new XXX(),这样就不是普通函数执行了,而是构造函数执行,当前函数名称之为“类名”,接收的返回结过为当前类的一个实例。
  2. 自己创建类名最好第一个单词首字母大写。
  3. 这种构造函数设计模式执行主要用于组件、类库、框架等的封装,平时编写业务逻辑一般不这样处理。
 function Fn(){
				
		}
 Fn();// 普通函数执行
 var f=new n();//Fn为类new-->构造函数 f为类的一个实例有值
 var f2=new n();//创建第二个实例,两个实例间互不影响
  • JS中创建值有两种方式,
  1. 字面量表达式
  2. 构造函数模式
var obj={};//zi字面量表达式
var obj=new Object();//构造函数模式   创建出来是个空对象
  1. 不管是哪种方式创造出来都是Object的实例,而实例间是独立分开的,所以var xxx={ }这种模式就是JS的单例模式
  2. 基本数据类型基于两种不同的模式创建出来的值是不一样的
var num1=12;  //number
var num2=new Number(12);//object
区别
4.1   基于字面量方式创建出来的是基本类型值,
4.2    基于构造函数创建出来的是引用类型
相同点
4.3  num2是数字类的实例;num1也是数字类的实例,它只是JS表达数字的特殊方式之一;都可以使用数字类提供的属性和方法。
  • 自定义类的创建
  • instanceof
    检测某一个实例是否隶属这个类
    缺 点:
    1 instanceof Number//false
       function Fn(){
				var n=0;
				this.m=n;
			}
			
			var f=new Fn();
			console.log(f instanceof Fn);//true
			console.log(f instanceof Array);//false
			console.log(f instanceof Object);//true  万物皆对象
			console.log('m' in f);//true
			console.log('n' in f);//false  n仅仅为私有变量和属性没有关系
			console.log('toString' in f);//true 共有属性
			console.log(f.hasOwnproperty('toString'));//false
			
  • in检测某个对象是否有某个属性
    不管当前这个属性是对象的私有属性还是共有属性,只要有结果就是true
  • hasOwnProperty:检测当前属性是否为对象的私有属性
    不仅要有这个属性还必须为私有属性
四 new运算符的实现机制
  • 普通函数执行
    1. 形成一个私有作用域
    2. 形参赋值
    3. 变量提升
    4. 代码执行
    5. 栈内存释放问题
  • 构造函数执行
           function Fn(){
				
			}
			Fn();
			function Fn(name ,age){
				var n=10;
				this.name=name;
				this.age=age+n;
			}
		var f1=Fn('dxy',12);
  • 图解普通函数执行和构造函数执行

构造函数执行机制
注意:f1.n 为undefined ,只有this.xxx=xxx才和实例有关系,n是私有作用域中的一个私有变量而已(this是当前类的实例)

  • 若构造函数中有return
    不写return浏览器会默认返回创建的实例;
    写了return
  1. 如果return 是一个基本值 ,返回依然是类的实例;
  2. 如果返回的是引用值,则会把默认返回的值覆盖,此时接收到的结果不是当前实例。
  3. 注意:构造函数执行的时候,尽量减少return的使用,防止覆盖实例
  4. return; 是代码结束的作用,不会覆盖返回的实例。
    function Fn(){
				var n=0;
				this.m=n;
				//return 'hh';
				return {name:'hh'};
			}
			
			var f=new Fn();
			console.log(f);//{name:"hh"}  被覆盖
  • new Fnnew Fn()
    在构造函数执行的时候,如果Fn 不需要传参,我们可以省略小括号,也是创建实例,两者没有区别。
五 原型和原型链

原型链设计模式
原型(prototype)、原型链(proto
[函数]
普通函数,类(所有的类:内置类,自己创建的类)new xxx(),Date
[对象]
普通对象,数组,正则,Math ,实例是对象类型(除了基本类型的字面量创建的值),arguments…
prototype的值也是对象类型,
函数也是对象类型
。。。。

  1. 所有的函数类型天生都自带一个属性:prototype(原型),这个属性的值是一个对象 ,浏览器默认会给它开辟一个堆内存;
  2. 在浏览器给prototype开辟的堆内存中有一个天生自带的属性:constructor,这个属性存储的值是当前的函数本身。
  3. 每一个对象都有一个__proto__的属性,这个属性指向当前实例所属类的prototype。如果不确定它是谁的实例,那么都为Object的实例。
  • 原型链机制
    通过__proto__隐式原型链向上查找的机制;
    当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性和方法;
    + 若找到,结束查找,使用自己私有的即可
    + 若没找到,则基于__proto__找所属类的prototype,如果找到就用共有的,如果没找到,基于原型上的__proto__进行查找,一直找到Object.prototype的原型为止,如果还是没有,操作的属性或者方法不存在。
    图解如下:
    原型链查找机制
    原型链试炼:
     function Fn(){
			var n=100;
			this.AA=function(){
				console.log("A【私有属性】");	
			};
			
			this.BB=function(){
					console.log("B【私有属性】");
			};
		}
		Fn.prototype.AA=function(){
			console.log("A【公有属性】");	
		}
		
		var f1=new Fn;  //无参可以省略小括号
		var f2=new Fn;
		
		 f1.n;    //  undedined
		 console.log(f1.n);
		 f1.AA===f2.AA; //false
		 f1.__proto__.AA===f2.__proto__.AA;//true
		 f1.__proto__.AA=Fn.prototype.AA; //true
		 f1.hasOwnProperty===Fn.prototype.hasOwnProperty;//true
		 f1.name=XX;//给自己设置私有属性
		 f1.__proto__.name=XXX;//给原型设置共有属性
		 Fn.prototype=XXX;  // 给原型设置共有属性
		 

题目图解分析:
题目分析

  • hasOwnProperty
  • 原型链中的this问题
  • 基于内置类原型扩展方法
六 JS 中五种 this 情况综合梳理
  1. 给当前元素的某个事件绑定方法,当某个事件触发执行的时候,方法中的this是当前操作的元素对象
    oBox.onClick=function(){
    //=>this: oBox
    }
  1. 普通函数执行,函数中的this取决于执行主体,谁调用this就是谁(执行主体,方法名前是否有”点“,有的话,点前边是谁,this就是谁,没有的话,this就是window)
function fn(){  //=>AAAFFF000
console.log(1);
};
var obj={fn:fn};
obj.fn();  //  this:obj
fn();     //  this:window
~function(){
}();    //this:window 自执行函数执行方法中的this是window

习题练习

            var n=2;
			var obj={
				n:3,
				fn:(function(n){
					n*=2;
					var n=5;
					this.n+=2;
					return function(m){  //产生闭包
						this.n*=2;
						console.log(m+(++n));
					}
				})(n)   //obj.n会报错
			};
			var fn=obj.fn;
			fn(3);     //9
			obj.fn(3);//10
			console.log(n,obj.n);//8  6

图解上题

  1. 构造函数指行
  2. 箭头函数this指向
  3. call/apply/bind

JS中5中this的指向可参考这篇博文

七 call/apply/bind
八 JS中四大继承方案

继承方案请参考

九 深拷贝and浅拷贝

请参考
https://blog.csdn.net/baidu_36065997/article/details/80309991

学习中的知识总结,会持续更新哦,有什么问题,欢迎大家指正

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值