jQuery2

作者: fastwe | 来源:发表于2018-11-28 21:22 被阅读0次

    第三章*****************************************************************************************

    1.ES5:

    ECMAScript: ECMA组织制定的JavaScript语言的国际标准,规定了JS语言的核心语法

    ES5是ECMAScript的第五个版本(第四版过于复杂废弃了),IE8部分此版本

    保护对象:

    什么是:① 保护对象的属性和属性值始终有意义

           ② 防止篡改对象的结构

    为什么:① 对象的属性,默认可随意赋值

           ② 对象可随意添加、删除属性

    何时: 严格来说,今后所有对象,都要有自我保护的抵抗力

    如何: 分为保护属性和防篡改

    保护属性: 保护对属性值的修改

    对象属性分为:

    命名属性: 可通过.直接访问的属性

        分为: 数据属性: 直接保存属性值的属性

              访问器属性: 不直接存储属性值,仅提供对其他数据属性的保护

    内部属性: 无法通过.直接访问的属性

    数据属性的四大特性:

    value:实际存储属性值

    writable:true/false控制属性是否可修改属性值

    enumerable:true/false控制属性是否可被for in遍历(false会跳过),仅控制遍历,无法控制用.访问

    configurable:true/false控制是否可删除该属性,控制是否可修改其它两个特性

    强调: configurable经常作为前两个属性的双保险,且一旦设为false,不可逆

    获取四大特性:

    Object.getOwnPropertyDescriptor(obj,"属性名")

    设置1个属性的四大特性:

    Object.defineProperty(obj,"属性名",{

      要修改的特性:特性值,

      要修改的特性:特性值,

      ... ...

    })

    问题: defineProperty一次只能修改一个属性

    解决: 同时修改多个属性的特性:

    Object.defineProperties(obj,{

      属性名:{ 要修改的特性 },

      属性名:{ 要修改的特性 },

      ... : ...

    })

    添加属性: 可用defineProperty添加新属性

              只要defineProperty要修改的属性不存在,就会自动添加

    强调: 用defineProperty添加的新属性,四大特性默认值都为false

    而用.添加的新属性,四大特性默认值都为true

    问题: 无法使用自定义逻辑保护属性

    解决: 访问器属性

    _______________________________________________________________________________________________

    访问器属性: 不直接存储属性值,仅提供对其他数据属性的保护

    何时: 只要使用自定义的规则保护属性值

    为什么: 数据属性的四大特性,保护规则是固定的,无法自定义

    如何定义: 2步:

    ①定义一个隐藏的数据属性,用于实际存储属性值

    ②再定义一个访问器属性,保护隐藏的数据属性:

    Object.defineProperty(obj,"属性名",{/*或用defineProperties,不能通过直接量或.创建*/

     get(){                                  /*在试图获取属性值时自动调用*/    

        return this.隐藏的数据属性;           /*返回受保护的数据属性值*/

     },

     set(val){          /*在试图修改属性值时自动调用,参数val会自动获得要修改的新值*/

        if(...)                /*验证val是否符合规则*/

          ...                  /*将val赋值给受保护的属性*/

        else ...               /*否则*/

          throw new Error      /*主动抛出错误*/

     },

    enumerable:true,          /*设置四大属性*/

    configurable:false

    })

    如何使用: 只要定义了访问器属性,就优先使用访问器属性,而不用受保护的数据属性

              访问器属性的用法和普通属性用法完全一样

              但是: 在取值时,自动调用get()

                    在赋值时,自动调用set(),val会自动获得要赋的新值

    内部属性: 无法通过.直接访问的隐藏属性

              比如: __proto__

    _______________________________________________________________________________________________

    防篡改: 阻止对对象结构的修改

    3个级别:

    ①防扩展: 禁止添加新属性

    Object.preventExtensions(obj)

      原理: 每个obj内部都有一个隐藏属性: Extensible,默认为true

            preventExtensions将obj的Extensible改为false

    ②密封: 在防扩展的基础上,进一步禁止删除现有属性(两个不要一起用)

    Object.seal(obj)

      原理: 将obj的Extensible改为false

            将所有属性的configurable都自动改为false

    ③ 冻结: 在密封基础上禁止修改一切属性值(过于严格)

    Object.freeze(obj)

      原理: 修改obj的Extensible为false

            将所有属性的configurable都改为false

            还将所有属性的writable都改为false

    _______________________________________________________________________________________________

    Object.create(): 本质上是创建一个新的子对象

    什么是: 基于一个现有父对象,创建一个新的子对象继承当前父对象,并扩展新属性

    何时: 今后如果没有构造函数的情况下,也想创建子对象

    如何:

    var child=Object.create(father,{      /*若不用扩展自有属性,father后的内容不必写*/

      自有属性:{

        value:值,

        writable:true,

        enumerable:true,

        configurable:true,

      },

      ... : {

        ...

      }

    });

    强调: 只要添加到对象中的属性,四大特性默认为false,必须显式写为true

    原理:① 创建一个空对象

         ② 让新对象自动继承father

         ③ 为新对象扩展新的自有属性

    _______________________________________________________________________________________________

    call/apply/bind:

    共同:为了替换函数中不想要的this

    何时: 只要函数中的this不是想要的 (函数不加括号,只在call/apply/bind右边加括号)

    call和apply:

    什么是:强行调用一个函数并临时替换函数中的this为指定的新对象

    call:  要求传入函数的参数必须单独传入,逗号分隔

    第1个参数是要指定的this,第2,3...个是要替换的参数

    apply: 要求传入函数的参数,必须放入数组中整体传入

           apply可自动打散数组类型的参数,单个传入

    第1个参数是要指定的this,第2个参数是一个数组

    bind:  基于一个现有函数创建一个功能完全相同的新函数,并永久绑定this为指定对象

           还可永久绑定部分固定的参数值

    替换回调函数中的this时,都用bind

    比如: var newFun=fun.bind(obj)    //接收新参数,函数后添加

                 newFun(参数1,...);          //调用函数

    强调: 被bind永久绑定的this,不能再被call/apply临时替换

    _______________________________________________________________________________________________

    数组API:

    判断: 判断数组中的元素是否符合要求

    返回值:bool(可判断是否满足条件)

    ①every: 判断数组中所有元素是否都满足要求

    var bool = arr.every(function(val,i,arr){  //回调函数: 当前元素值:val;当前元素位置:i;arr:当前数组

      return 判断条件

    });

    ②some: 判断数组中是否包含满足条件的元素

    var bool = arr.some(function(val,i,arr){

      return 判断条件

    });

    强调:数组API的回调函数中this默认->window,所以,不能用this指代当前元素值,但可用如arr[i]或val

    遍历: 对数组中每个元素执行相同的操作:

    ①forEach: 对原数组中每个元素执行相同的操作

    arr.forEach(function(val,i,arr){    //没有返回值

      arr[i]=新值;                      //对当前元素执行的操作,直接修改原数组,只能使用arr[i]

    })

    ②map: 取出原数组中每个元素,执行相同操作后,再放入新数组返回

    var arr2 = arr1.map(function(val,i,arr){        //返回一个新数组

      return 对当前元素操作后的新值(放入新数组中)        //不修改原数组,使用arr[i]=..可修改原数组

    })

    过滤和汇总:

    过滤: filter: 复制原数组中符合条件的元素,组成新数组

    var subArr=arr.filter(function(val,i,arr){

      return 判断条件        //筛选出arr中符合判断条件(为true)的元素值,放入新数组返回

    })

    汇总: reduce: 将数组中所有元素,统计出一个汇总结果

    var r=arr.reduce(function(prev,val,i,arr){       //prev: 截止目前的临时汇总值

      return prev+val

    },startVal);                           //startVal: 表示汇总开始的基数,可不写(默认为0)

    将arr数组中每个值累加后,求和

    强调: reduce不一定非要从0开始累加,可从任意startVal(也可以是其它数组)开始累加

    _______________________________________________________________________________________________

    严格模式:

    什么是: 比普通js运行模式要求更严格的运行机制

    为什么: 解决普通js运行模式中广受诟病的缺陷

    何时: 今后都要在严格模式下开发

    ① 新项目, 必须全部启用严格模式

    ② 旧项目, 逐个函数向严格模式迁移

    如何: 2种:

    ① 整个代码段启用严格模式:

    在<script>标签或js文件的开头加入:"use strict";

    ② 仅对单个函数启用严格模式

    仅在function内,函数体的顶部加入:"use strict";

    要求:

    1. 不允许对未声明的变量赋值

    2. 静默失败升级为错误

    3. 不推荐使用arguments.callee来实现递归

    _______________________________________________________________________________________________

    2.ES6(框架广泛采用,又称为ECMAScript 2015):

    模板字符串: 对字符串拼接的简化(2015年首次发布,IE Edge不支持)

    何时: 如果字符串中包含需要动态执行的表达式或回车换行时

    如何:3件事

    ① 用``反引号(ESC键的正下方)包裹字符串

    ② 字符串中的变量和表达式都要放在${...}中

    ③ 模板字符串中支持:  换行,变量,表达式(),注释也会被解析

    let:

    1. 专门声明仅在当前块中有效的局部变量

      块: js中只要一个{}就是一个代码块

          let声明的变量,仅在{}内有效,不会被提前到{}外

    2. 防止声明提前现象

    声明提前: 在开始执行程序前,引擎会将var声明的变量和function声明的函数,提前到"当前作用域"顶部集中优先创建,再开始执行程序            /*但是赋值留在原地*/

    何时:今后强烈建议用let代替var

    强调:let必须配套严格模式使用

    _______________________________________________________________________________________________

    箭头函数: 对所有回调函数的终极简写

    何时: 今后,几乎所有的回调函数,都要用箭头函数简化

    如何:

    1.所有回调函数都可:去 function(参数) 改为 (参数)=>

    2.如果函数体只有一句话: 可省略{}

    如果这一句话还是return,可省略return

    3.如果只有一个参数:可省略()

    但是,如果没有参数,必须保留空()

    特点:箭头函数可让内外this共用同一个对象————不再需要bind替换

    特殊: 如果不希望内外共用this,就不能用箭头函数(或者用e.target -> 当前单击的元素对象)

    比如事件处理函数:

      elem.addEventListener("click",function(){ this -> 当前单击的元素对象,不共用 })

      elem.addEventListener("click",()=>{ 致使this -> 不是elem })

    变通解决:

    elem.addEventListener("click",e=>{ e.target->elem })    /*利用冒泡*/

    特点:

    ① 箭头函数没有this

    ② 箭头函数没有arguments

    ③ 不能通过 new 关键字调用

    ④ 没有 new.target

    ⑤ 没有原型

    ⑥ 没有 super

    _______________________________________________________________________________________________

    for of: 简化for循环遍历:

    何时: 直接获得每个元素值时

    如何:

    for(var i=0;i<arr.length;i++){ arr[i] }       /*arr[i]: 当前元素*/

    简写为:

    for(var val of arr){ val }            /*val: of会依次取出arr中每个元素的值,保存到val*/

    局限:

    ①只能遍历索引数组和类数组对象,不能遍历关联数组和对象(只能用for in循环遍历)

    ② 无法获得下标

    ③ 只能逐个遍历所有,不能控制循环的开始和结束以及步调

    ④按值传递: 如果数组中保存的是原始类型的值,修改val,不会影响数组元素(val是数组元素值的副本)

    何时:仅遍历元素值,不关心下标时,才可用for of简写

    _______________________________________________________________________________________________

    class: 对 面向对象 的简化

    如何定义类型:

    ①用一个 class 类型名{}结构包裹原来的 构造函数和原型对象方法

    ②修改构造函数的'function'为'constructor',其余保持不变

    ③可省略开头的'类型.prototype'与方法名后的'=function'

    直接定义在class中的函数直接量,会自动保存在当前类型的原型对象中

    定义父类:

    class Flyer{

      constructor(fname,speed){

        this.fname=fname;

        this.speed=speed;

      }

      fly(){ }        //fly <=> Flyer.prototype.fly

      get 访问器属性名(){ return this.受保护的其他属性 }    //添加访问器属性,在构造函数的平级

      set 访问器属性名(val){

        if(条件) this.受保护的属性=val

        else 报错

      }

    }

    继承: 不再设置Object.setPrototypeOf

    ①在'class 类型名'后添加'extends 父类型'名

    ② 在子类型构造函数中不允许直接用call调用父类型构造函数,可使用super(属性参数值列表),不加this

    子类:

    class Plane extends Flyer{             //让Plane继承Flyer

      constructor(fname,speed,score){

        super(fname,speed);  //super:关键字,指父类型的构造函数,自动将子类型的this传入父类构造函数中,不允许用call

        this.score=score;

      }

      getScore(){ }

    }

    使用:

    var obj = new Plane('fname',10,30)    //也可以new父类: var obj = new Flyer('fname',10)

    obj.getScore()        //子类的方法

    obj.fly()             //父类的方法

    相关文章

      网友评论

          本文标题:jQuery2

          本文链接:https://www.haomeiwen.com/subject/qdpbqqtx.html