JavaScript第20天

面向对象

1、继承

        1、判断自有还是共有

                1、判断自有:obj.hasownProperty("属性名");

                        //结果为true,说明是自有属性,如果为false,有两种可能,说明可能是共有,也可能没有

                2、判断共有

<script>
    if(obj.hasownproperty("属性名")===false&&"属性名" in obj){
        //in 关键字,会自动查找原型链上的属性,找到结果为true,找不到结果为false
        共有 
    }else{
        没有
    }
</script>

                完整公式

<script>
    if(obj.hasownproperty("属性名"){
        自有
    }else{
        if("属性名" in obj){
            共有
        }else{
            没有
        }
    }
</script>

        2、修改和删除:自有和共有

                自有:

                        修改:obj.属性名=新属性值;

                        删除:delete obj.属性名;

               共有:

                        修改:原型对象.属性名=新属性值;

                                //千万不要觉得自己能拿到,就直接修改,这样并没有修改原型的东西,而是在本地添加了一个同名属性

                        删除:delete 原型对象.属性名;

                                //如果对着本地直接删除,那么操作直接无效

        3、问题:如何为老IE的数组添加indexof方法/如何为一类人创建某个方法

<script>
    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];
</script>

        4、如何判断x是不是一个数组:4种方法,千万别用typeof(),只能检查原始类型,不能检查引用类型

                1、判断x是否继承Array.prototype:

                        Array.prototype.isPrototypeOf(x);

                        //结果为true,说明是数组,结果为false,说明不是数组

                2、判断x是不是由Array这个构造函数创建的

                        x instanceof Array;

                        //结果为true,说明是数组,结果为false,说明不是数组

                3、Array.isArray(x); -—ES5新增的方法,只有数组可以这么使用

                        结果为true,说明是数组,结果为false,说明不是数组

                4、输出【对象的字符串】形式

                       1、 在Object的原型上保存着最原始的toString方法

                       2、原始的toString输出形式:[object 构造函数名]

               多态:子对象觉得父对象的成员不好用,就在本地定义了同名函数,覆盖了父对象的成员,不严格定义:同一个方法,不同的人使用,效果不同,有多种形态

                固定套路:

                        Object.prototype.toString.call(x)==="[object Array]"

        5、多个对象之间设置继承

                1、两个对象之间设置继承

                        子对象.__proto__=父对象

                2、多个对象之间设置继承

                        1、 构造函数名.prototype=父对象;

                        2、时机:应该在开始创建对象之前就设置好继承关系

2、class关键字:简化面向对象(封装、继承、多态)

<script>
    class 类名 extends 老类{
        constructor(name,age,hobby,...){
        //放在constructor里面的都是自有属性
            super(name,age);
            this.hobby=hobby;
        }//放在constructor外面的都是共有方法
    //还会继承到老类所有的API,也可以添加新的
    }
</script>

3、Function:闭包

        1、作用域

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

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

        2、函数执行原理

                1、程序加载时

                        1、创建执行环境栈(ECS):保存函数调用顺序的数组

                        2、首先压入全局执行环境(全局EC)

                        3、全局EC引用着全局对象window

                        4、window中保存着我们全局变量

                2、定义函数时

                        1、创建函数对象:封装代码段

                        2、在函数对象之中有一个scope(作用域)属性:记录着函数来自己的作用域是哪里

                        3、全局函数的scope都是window

                3、调用前

                        1、在执行环境栈(ECS)压入新的EC(函数的EC)

                        2、创建出活动对象(AO):保存着本次函数调用时用到的局部变量

                        3、在函数的EC中有一个scope chain(作用域链)属性引用着AO

                        4、AO有一个parent属性是函数的scope引用着的对象

                4、调用时

                        正是因为有前面三步,才来带变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错

                5、调用完

                        函数的EC会出栈,没人引用AO,AO自动释放,局部变量也就释放了

        3、闭包

                1、希望保护一个可以【反复使用的局部变量】的一种词法结构,其实还是一个函数,只是写法比较特殊

                2、何时使用:希望保护一个可以【反复使用的局部变量】的时候

                3、如何使用:

                        1、两个函数进行嵌套

                        2、外层函数创建出受保护的变量

                        3、外层函数return出内层函数

                        4、内层函数再操作受保护的变量

                4、强调:

                        1、判断是不是闭包:有没有两个函数嵌套,返回了内层函数,内层函数再操作受保护的变量

                        2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本

                        3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

                5、缺点:受保护的变量,永远都不会被释放,使用过多,会导致内存泄漏 - 不可多用

                6、问题:应该在哪里去使用呢?

                        1、三个事件需要防抖节流 - 共同点:触发的速度飞快

                                1、elem.onmousemove - 鼠标移动事件

                                2、input.oninput - 每次输入/改变都会触发

                                3、onresize - 每次窗口改变大小都会触发

                7、防抖节流的公式:

<script>
    function fdjl(){
        var timer=null;
        return function(){
            if(timer!==null){
                clearTimeout(timer);
                timer=null;
            }
            timer=setTimeout(()=>{
                操作
            },500)
        }
    }
    var inner=fdjl();
    elem.on事件名=function(){
        inner();
    }
</script>

4、总结:

        两链一包:

                1、作用域链:以函数的EC的scope chain属性为起点,经过AO,逐级引用,形成的一条链式结构,我们就称之为叫做作用域链

                        作用:查找变量,带来了变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错

                2、原型链:每个对象都有一个属性叫做.__proto__,可以一层一层的找到每个对象的原型对象,最顶层的就是Object的原型,形成的一条链式结构,我们就称之为叫做原型链

                        作用:查找属性和方法,哪怕自己没有也会顺着原型链向上找,怪不得人人都能用toString(),因为他在最顶层

                3、闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实还是一个函数,只是写法比较特殊

                        作用:专门用于防抖节流

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值