day13 面向对象、ES6class关键字、Function闭包

51 阅读2分钟

面向对象:

    1、继承具有很多很多的面试和笔试题:
    	1、判断是自有还是共有:
            1、判断自有:obj.hasOwnProperty("属性名");
    		结果结果为true,说明是自由属性,如果结果为false,有两种可能,有可能是共有,也有可能是没有

            2、判断共有:
    		if(obj.hasOwnProperty("属性名")==false&&"属性名" in obj){//in关键字,会自动查找整条原型链上的属性,找到了结果为true,找不到结果为false
    			共有
    		}else{
    			没有
    		}

    		完整公式:
    		if(obj.hasOwnProperty("属性名")){
                    自有
    		}else{
    			if("属性名" in obj){
                            共有
    			}else{
                            没有
    			}
    		}

    	2、修改和删除:自有和共有
            自有:
    		修改:obj.属性名=新属性值;
    		删除:delete obj.属性名;
            共有:
    		修改:原型.属性名=新属性值;//千万不要觉得,自己能拿到,就能直接修改,这样很危险,并没有修改原型东西,而是再本地添加了一个同名属性
    		删除:delete 原型.属性名;//千万不要觉得,自己能拿到,就能直接删除,操作会无效

    	3、如何为老IE的数组添加indexOf方法 - 这道题不是固定的,可能问如何为一类人创建某个方法
    		if(Array.prototype.indexOf===undefined){//老IE
    			Array.prototype.indexOf=function(key,starti){
                            starti===undefined&&(starti=0);
                            for(var i=starti;i<this.length;i++){
    				if(this[i]==key){
                                    return i;
    				}
                            }
                            return -1;
    			}
    		}
    		var arr1=[1,2,3,4,5];
    		var arr2=[2,4,6,8,10];
    		console.log(arr1.indexOf(2));
    		console.log(arr2.indexOf(2));
                
    		4、如何判断x是不是一个数组:4种方式:千万别用typeof,只能检查原始类型, 不能检查引用类型,如果检查引用类型的得到的结果都是一个object
                    1、判断x是不是继承自Array.prototype
    			Array.prototype.isPrototypeOf(x);
    			结果为true,说明是数组,结果为false,说明不是数组
                    2、判断x是不是由Array这个构造函数创建
    			x instanceof Array;
    			结果为true,说明是数组,结果为false,说明不是数组

                    3Array.isArray(x) - ES5新增的方法,只有数组可以这么使用
    			结果为true,说明是数组,结果为false,说明不是数组

                    4、输出【对象的字符串】形式
    			在Object的原型上保存着最原始的toString()方法
    			原始的toString输出的形式:[object 构造函数名]
                        
    			多态:子对象觉得父对象的成员不好用,就在本地定义了一个同名函数,覆盖了父对象的成员,不严格定义:同一个函数,不同的人使用,表现出来得效果不一样,由多种形态
    			固定套路:
                            Object.prototype.toString.call/apply(x) === "[object Array]";

    		5、实现自定义继承:
    			1、两个对象之间设置继承:
    				子对象.__proto__=父对象

    			2、多个对象之间设置继承:
    				构造函数名.prototype=父对象;
    				时机:应该在开始创建对象之前就设置好继承关系

ES6 - class关键字

简化面向对象(封装、继承、多态)

class 类名 extends 老类名{
	constructor(name,speed,rl){//放在constructor里面得都是自有属性
        super(name,speed);//帮你调用你继承的老类得constructor函数
        this.rl=rl;
	}//放在constructor外面得都是共有方法
	//还会继承到老类所有的API,也可以在此处添加属于自己的新的API
}
var obj=new 类名(实参,...)

Function - 闭包

作用域:21、全局:随处可用,可以反复使用,缺点:容易被污染

	2、函数:只能在函数调用时内部可用,不会被污染,缺点:一次性的,使用完就会释放的。

	函数的执行原理:
		1、程序加载时:
			创建执行环境栈(ECS):保存函数调用顺序的数组
			首先压入全局执行环境(全局EC)
			全局EC引用着全局对象window	
			window种保存着我们的全局变量

		2、定义函数时
			创建函数对象:封装代码段
			在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
			全局函数的scope都是window

		3、调用前
			在执行环境栈(ECS)压入新的EC(函数的EC)
			创建出活动对象(AO):保存着本次函数调用时用到的局部变量
			在函数的EC中有一个scope chain(作用域链)属性引用着AO
			AO还有parent属性是函数的scope引用着的对象

		4、调用时:
			正是因为有了前面三步,才会带来变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错

		5、调用完:
			函数的EC会出栈,没人引用着AOAO自动释放,局部变量也就释放了

	闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实还是一个函数,只是写法比较特殊
		何时使用:希望保护一个可以【反复使用的局部变量】- 私有化变量
		如何使用:
			1、两个函数进行嵌套
			2、外层函数创建出受保护的变量
			3、外层函数return出内层函数
			4、内层函数在操作受保护的变量

		强调:
			1、判断是不是闭包:有没有两个函数嵌套,返回内层函数,内层函数再操作受保护的变量
			2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
			3、同义词外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

		缺点:受保护的变量,永远都不会被释放,使用过多,会导致内存泄漏 - 闪退,不可多用!
		问题:应该在哪里去使用呢?
			1、四个事件需要防抖节流 - 共同:触发的飞快,但是我们不需要飞快的修改DOM树!
				1、elem.onmousemove
				2、input.oninput 
				3window.onresize
				4window.onscroll

			防抖节流公式:
				function fdjl(){
					var timer=null;
					return function(){//反复的重开重开
						if(timer){clearTimeout(timer);timer=null;}
						timer=setTimeout(()=>{
							操作;
						},间隔毫秒数)
					}
				}
			
				var inner=fdjl()

	总结:
		两链一包:
		1、作用域链:以函数的EC的scope chain属性为起点,经过AO逐级引用,形成的一条链式结构
			作用:查找变量,来带了变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
		2、原型链:每个对象都有一个属性.__proto__,可以一层一层的找到每个人父亲,形成了一条链式结构
			作用:找共有属性和共有方法的,哪怕自己没有会悄悄的向上查找,如果最顶层也没有才会报错
			最顶层是Object的原型,甚至上面放着我们眼熟的API - toString,怪不得人人都可以使用
		3、闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实还是一个函数,只是写法比较特殊
			作用:专门用于防抖节流