Javascript知识总结--ES6 类对象,闭包

来源博客:【Harryの心阁

ES6 类

  1. 创建类 class Star { constructor(uname){ this.uname = uname} }
  2. 利用类创建对象 var ldh = new Star('')
  3. constructor 函数只要new生成实例时,就会调用这个函数
  4. 类里面的所有函数不需要写function(),多个函数方法之间不需要添加

类的继承

  1. 语法 class father{ } class son extends father{}
  2. 继承父类的一些属性和方法
  3. super()关键字调用父类的构造函数
        class father{
            constructor(x,y){
                this.x = x;
                this.y = y;
            }
            sum(){
                console.log(this.x+this.y);
            }
        }
        class son extends father{
            constructor(x,y){
                super(x,y);
            }
        }
        var Son = new son(1,2)
        Son.sum();

super关键字

  1. 关键字调用父类的构造函数
  2. 关键字可以调用普通函数
  3. 继承属性或者方法查找原则就近原则
  4. 子类构造函数调用父类函数时,super关键词必须写到 字类this之前调用
        class father{
            say(){
                return 'didi'
            }
        }
        class son extends father{
            say(){
                console.log(super.say());
            }
        }
        var oo = new son()
        oo.say()

ES6类和对象要注意的问题

  1. 必须先定义类,才能通过类实例化对象
  2. 类里面共有的属性和方法一定要加this使用
  3. 注意this的指向问题,constructor里面的this 指向的时创建的实例化对象,方法种的this指向的调用这个方法的实例化对象 重点
class star{
    constructor(uname,age){
        this.name = uname
        this.age = age;
        // this.sing()  可以调用函数,但是必须加this
        // 如果添加一些事件后在执行要注意 this.sing; 函数后面不加小括号,如果加上小括号表示直接调用
    }
    sing(){
        console.log(this.name);
    }
}
var iu = new star('iu')

面向对象案例

  1. 使用es6新特性添加元素 insertAdjacentHTML(position,ele)
  2. e.stopPropagation() // 阻止冒泡事件
  3. 双击禁用选定文字 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
   *{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body{
    background-color: rgb(180, 175, 175);
}
h4{
    margin: 50px auto;
    width: 200px;
    height: 100px;
    font-weight: 600;
    line-height: 100px;
    text-align: center;
}
li{
    list-style: none;
}
.box{
    width: 800px;
    height: 400px;
    border: 2px solid #ccc;
    margin: 0 auto;
    border-radius: 10px;
    box-shadow: 0px -5px 10px #888;
}
#box ul .clickcss{
    border-bottom: none;
}
.nav{
    width: 100%;
    height: 50px;
}
.nav ul {
    height: 100%;
    float: left;
}
.nav .addTab{
    float: right;
}
.nav ul li{
    position: relative;
    width: 85px;
    float: left;
    border-bottom: 2px solid #ccc;
    border-right: 2px solid #ccc;
    height: 100%;
    padding-top: 18px;
    text-align: center;
}
.nav ul li p{
    position: absolute;
    right: 0;
    top: 2px;
    width: 15px;
    height: 15px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    background-color: bisque;
}
.addTab{
    height: 100%;
    width: 50px;
    font-size: 30px;
    font-weight: 600;
    line-height: 50px;
    text-align: center;
    border-left: 2px solid #ccc;
    border-bottom: 2px solid #ccc;
}
section{
    padding: 10px;
}
section p{
    display: none;
}
.blockcss{
    display: block;
}
span{
    width: 100%;
}
span input{
    width: 100%;
} 
</style>
<body>
    <h4>es6 js面向对象的动态</h4>
    <div class="box" id="box">
        <div class="nav">
            <ul>
                <li class="clickcss"><span>你好世界</span><p>x</p></li>
                <li><span>你好世界</span><p>x</p></li>
                <li><span>你好世界</span><p>x</p></li>
            </ul>
            <div class="addTab">+</div>
        </div>
        <section>
            <p class="blockcss">你好世界a</p>
            <p class="">你好世界b</p>
            <p class="">你好世界c</p>
        </section>
        
    </div>
    <script>
        window.addEventListener('DOMContentLoaded', function () {
    var that;
    class Tab{
        // 获取元素
        constructor(id){
            that = this;
            this.main = document.querySelector(id);
            this.add = this.main.querySelector('.addTab')
            this.fitem = this.main.querySelector('section')
            this.ul = this.main.querySelector('.nav ul:first-child')
            this.init();
        }
        // 获取所有的li 和 items
        updateTAb(){
            this.lis = this.main.querySelectorAll('li');
            this.remove = this.main.querySelectorAll('ul li p')
            this.items = this.main.querySelectorAll('section p');
            this.spans = this.main.querySelectorAll('ul li span')
        }
        init(){
            // 初始化
            this.updateTAb();
            this.add.onclick = this.addTab;
            for(var i = 0; i< this.lis.length;i++){
                this.lis[i].index = i;
                this.lis[i].onclick = this.toggleTab;
                this.remove[i].onclick = this.removeTab;
                this.spans[i].ondblclick = this.exit;
                this.items[i].ondblclick = this.exit;
            }
        }
        // 切换功能
        toggleTab(){
            // console.log(this.index);
            that.clearClass();
            this.className = 'clickcss'
            that.items[this.index].className = 'blockcss'
        }
        clearClass(){
            for(var i=0;i<this.lis.length;i++){
                this.lis[i].className = ''
                this.items[i].className = ''
            }
        }
        addTab(){   
            // 调用之前将之前的样式清除
            that.clearClass()
            // 创建元素 and 追加元素
            var random = Math.random()
            // 使用新的函数insertAdjacentHTML(position,ele)
            var li = '<li class="clickcss"><span>新标签</span><p>x</p></li>'
            var item1 = '<p class="blockcss">你好世界b'+random+'</p>'
            // 把元素追加到父元素内孩子的最后面
            that.ul.insertAdjacentHTML('beforeend',li)
            that.fitem.insertAdjacentHTML('beforeend',item1)
            that.init();
        }
        removeTab(e){
            e.stopPropagation()  // 阻止冒泡事件
            var index = this.parentNode.index
            console.log(index);
            // this.remove() 可以删除元素
            that.lis[index].remove();
            that.items[index].remove();
            that.init()
            // 当页面中有下面这个小li时,返回return,不执行下面的
            if(document.querySelector('.clickcss')) return;
            index--;
            // 自动调用鼠标点击事件
            that.lis[index] && that.lis[index].click();
        }
        exit(){
            var str = this.innerHTML;
            window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); 
            this.innerHTML = '<input type="text">'
            var input = this.children[0]
            input.value = str;
            input.select();
            input.onblur = function(){
                this.parentNode.innerHTML = this.value
            }
            input.onkeyup = function(e){
                if(e.keyCode === 13){
                    this.blur();
                }
            }
    }
}
    new Tab('#box')
})
    </script>
</body>
</html>

构造函数的缺点

  1. 使用构造函数的方法时使用函数的方法 多个对象使用复杂数据类型会浪费内存
  2. 使用新特性prototype只能函数.prototype.方法共享方法,通过原型(对象)分配,公共的方法放到原型对象身上
  3. 静态成员在构造函数本身身上添加成员,函数.属性/方法,静态成员只能通过构造函数来访问
  4. __proto__指向我们构造函数的原型对象,和prototype是等价的,它是非标准属性,一条路线,都存在一个constructor函数

constructor 构造函数

  1. 在使用prototype对象时要注意.= 的区别,如果使用等号时会将原来的constructor覆盖无法指向原来的函数,必须使用constructor函数重新手动指向原来的函数
  2. .是添加一个属性或者方法, =是将原来的constructor覆盖,如果修改了原来的原型对象,给原型对象赋值的是对象必须使用constructor函数重新指向原来的原型对象
        function Star(name, age){
            this.uname = name;
            this.age = age;
        }
        var dd = new Star('你好')
        // Star.prototype.title = '世界'
        // console.log(dd.title);
        // 使用 = 将函数原来的constructor覆盖,必须使用construtor指向原来的函数
        Star.prototype = {
            constructor: Star,
            title: function(){
                console.log('世界');
            }
        }
        console.log(Star.prototype.constructor);
        console.log(dd.__proto__.constructor)
        //  = 和 . 有区别
  1. 记录引用了哪个函数
  2. 只要是对象就有__proto__
  3. object原型对象为null

原型链

  1. js的查找机制根据原型链查找
  2. 并且遵循就近原则
        // js查找机制就近原则,按照原型链的方法
        dd.sex = 'nv'
        Object.prototype.sex = 'bianxingren'
        Star.prototype.sex = 'nan'
        console.log(dd.sex)

构造函数与实例化对象还有原型对象的关系

        function Star(name, age) {
            this.uname = name;
            this.age = age;
        }
        var dd = new Star('ni',18)
        // Star.prototype.title = '世界'
        // console.log(dd.title);
        // 使用 = 将函数原来的prototype覆盖,必须使用construtor指向原来的函数
        Star.prototype = {
            constructor: Star,
            title: function () {
                console.log('世界');
            }
        }
        // 指向原型对象
        console.log("函数原型对象所使用的函数为:"+Star.prototype.constructor);
        // 指向原型对象
        console.log("Star函数的原型对象:"+Star.prototype); 
        console.log(Star);
        console.log(dd);
        console.log('判断函数的原型对象的与实例化对象指向所用的函数的关系'+Star.prototype.constructor === dd.__proto__.constructor);
        // 原型对象指向的是Object的原型
        console.log("判断函数原型对象的指向与对象的原型对象的关系:"+(Star.prototype.__proto__ === Object.prototype));
        // 指向原型对象 
        console.log("实例化对象的指向为"+dd.__proto__);
        // 指向Object
        console.log("函数原型对象的指向使用的函数为:"+Star.prototype.__proto__.constructor);
        console.log("Object的指向为:"+Object.__proto__);
        // Object原型对象的指向为null
        console.log("Object的原型对象的指向为:"+Object.prototype.__proto__);
        //  = 和 . 有区别

this指向

  1. 在构造函数中里面的this指向的是对象实例
  2. 原型对象函数里面的this指向的是实例对象

扩展内置对象

  1. 数组和字符串内置对象不能给原型对象覆盖操作Array.prototype = {} ,只能是Array.prototype.xxx = function(){}的方式
  2. 可以使用原型对象里面的扩展对象,页可以自定义扩展方法
        console.log(Array.prototype);
        Array.prototype.sum = function(){
            // console.log(this.length);
            // console.log(this);
            var sum  = 0;
            for(var i= 0;i<this.length;i++){  
                sum += this[i];
                // console.log(this[i]);
            }
            return sum
        }
        var arr = new Array(1,2,3,4)
        console.log(arr.length);
        console.log(arr.sum());

call()

  1. 作用:调用这个函数,可以修改调用函数的this的指向
  2. 格式: 函数.call() 函数不加括号 fn.call()
  3. call(实例化对象) 可以改变函数的this指向,并且不传递
        function sun(x,y){
            console.log(this);
            console.log(x+y);
        }
        sun()
        var no = {
            name: 'jjj'
        }
        sun.call(no,1,2)

借用构造函数继承父类属性

        function Father(uname,age){
            this.uname = uname;
            this.age = age
        }
        function Son(uname,age){
            Father.call(this,uname,age)
        }
        var dd = new Son('dd',18)
        console.log(dd);

借用构造函数继承父类方法

  1. 在使用对象的形式修改了原型对象时,使用constructor来指向原来的构造函数
function Father(uname,age){
    this.uname =uname
    this.age = age
}
function Son(uname,age){
    Father.call(this,uname,age)
}
Son.prototype.exam = function(){
    console.log(10);
}
// Father.prototype = Son.prototype
// 利用对象的形式修改了原型对象,记得使用constructor来指向原来的构造函数
Son.prototype = new Father()  
// 构造函数的原型对象始终都是指向本身
Son.prototype.constructor = Son
Father.prototype.money = function(){
    console.log(11);
}
var son =new Son('dd',17)
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);

ES5新增方法

  1. 数组方法 map() every()
  • forEach() 遍历方法,有一个回调函数里面有3个参数 value,index,array,分别表示每个元素的值,每个元素的索引号,元素本身
  • 迭代 filter() 筛选的作用 ,返回一个新的数组 return 迭代遍历
  • some() 查找元素中是否有满足条件的元素, 返回的是布尔值,找到第一个满足条件的元素终止循环
  • every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
  • map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
  1. forEachfilter里面遇到return true 不会终止迭代 ,在some里面遇到return true 停止迭代
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        table {
            border: 1px solid #ccc;
            border-bottom: 0;
            border-right: 0;
            margin: 50px auto;
            width: 450px;
        }

        tbody {
            text-align: center;
        }

        thead {
            border-bottom: 1px solid #ccc;
        }

        td,
        th {
            border-right: 1px solid #ccc;
            border-bottom: 1px solid #ccc;
        }

        h4 {
            display: inline-block;
            margin-right: 5px;
        }

        .search {
            text-align: center;
            margin: 10px auto;
        }

        input {
            width: 40px;
        }

        input,
        button {
            outline-style: none;
        }

        button {
            margin-left: 5px;
        }
    </style>
    <div class="search">
        <h4>按照价格查询</h4><input class="start" type="text">-<input class="end" type="text"><button
            class="search-price">搜索</button>
        <h4>按照产品名称查询</h4><input class="chanp" type="text"><button class="search-name">搜索</button>
    </div>


    <table cellspacing='0'>
        <thead>
            <tr>
                <th>id</th>
                <th>产品名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>
        var data = [{
            id: 1,
            pname: '小米',
            price: 999
        },
        {
            id: 2,
            pname: '华为',
            price: 1933
        },
        {
            id: 3,
            pname: 'iPhone',
            price: 2999
        },
        {
            id: 4,
            pname: 'oppo',
            price: 3999
        }]
        var tbody = document.querySelector('tbody')
        // 首先通过遍历数组获取数组中的元素,然后创建新的元素,将获取到的值添加到元素的中
        setData(data)
        // 封装一个函数使得搜索的时候能重复调用
        function setData(mydata) {
            tbody.innerHTML = ''
            mydata.forEach(function (value) {
                var tr = document.createElement('tr')
                tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>'
                tbody.appendChild(tr)
            })
        }
        // 使用filter()方法 遍历迭代数组,找出满足条件的,返回一个新的数组
        var searchPrice = document.querySelector('.search-price')
        var start = document.querySelector('.start')
        var end = document.querySelector('.end')
        searchPrice.addEventListener('click', function () {
            var newData = data.filter(function (value) {
                return value.price >= start.value && value.price <= end.value
            })
            console.log(newData);
            setData(newData)
        })
        // // 通过产品的名称搜索 使用filter方法
        var chanp = document.querySelector('.chanp')
        var searchName = document.querySelector('.search-name')
        // searchName.addEventListener('click',function(){
        //     var newdata1 = data.filter(function(value){
        //         return value.pname == chanp.value
        //     })
        //     setData(newdata1)
        // })

        // 通过some来遍历 效率更高
            searchName = document.addEventListener('click',function(){
                var arr  = []
                data.some(function(value){
                    if(value.pname == chanp.value){
                        arr.push(value)
                        return true;  
                    }
                })
                setData(arr)
            })

    </script>
</body>

</html>

字符串方法

trim() 方法 去除字符串的两侧的空格

对象方法

  1. 用于获取对象自身所有的属性 Object.keys(obj)
  2. Object.defineProperty(对象,属性,descriptor 对象的格式{ value: ''})定义对象中的属性或者修改原有的属性
  • descriptor中的属性值:value表示所修改或者新增的值,默认为undefined,writable:false 不允许修改属性值
  • enumerable;表示目标属性是否可以被遍历,默认值为false
  • configurable:表示目标属性是否可以被修改或者删除,或者再次修改新特性 默认为false

函数的定义方法

  1. 命名函数,匿名函数
  2. 利用var fn = new function(‘参数’,’参数‘,’函数体‘)必须以字符串的格式编写
  3. 所有的函数都是Function的实例对象,函数也属于对象

函数的调用方式

  1. 普通函数的调用
function fn(){
    console.log(11);
}
fn(); fn.call()
  1. 对象的方法调用
var o = {
    fn:function(){
        console.log(11);
    }
}
o.fn();
  1. 构造函数的调用方法
function Fn(){
    console.log(11);
}
new Fn();
  1. 绑定事件函数
obj.onclick = function(){
    console.log(11);
}
  1. 定时器函数的调用
setInterval(function(){
    console.log(11)
},1000)
  1. 立即执行函数
(function(){
    console.log('立即执行函数'+11);
})()
//第二种
(function(){
    console.log('立即执行函数'+11);
}())

改变函数内部的this的指向

  1. call(arr,'','')arr为对象,后面可以传递参数;调用函数;改变函数内的this指向;主要作用可以实现继承
  2. apply(thisarr,[''])方法 也是调用函数可以改变函数内部的this指向,但是传递参数时必须以数组的形式传递(伪数组)
  • 调用数学内置对象 比如:Math.max.apply(Math,arr),arr必须为数组的形式
  1. bind(thisarr,’’,’’)方法 不会调用函数,也能改变指向, 但是返回的是原函数改变this之后产生的函数
// 使用bind方法来改变函数内部的this指向
var btn = document.querySelector('button')
btn.onclick = function(){
this.disabled = 1
setTimeout(function(){
this.disabled = 0
}.bind(this),3000)
}

严格模式

  1. 'use strict';为整个脚本开启严格模式
  2. 可以为某个函数开启严格模式
  3. 不能随意删除已经定义好的变量
  4. 严格模式下的全局变量的this是undefined
  5. 严格模式下调用构造函数必须加new
  6. 函数名不允许有重名的情况
  7. 不允许在非函数里声明函数

高阶函数

  1. 对其他函数进行操作的函数,接受函数作为参数或者将函数作为返回值输出
  2. 函数也是一种数据类型
  3. 回调函数–高阶函数

闭包(Closure)

  1. 函数,有权访问另一个函数作用域中变量的函数,被访问函数变量
(function(){
'use strict';
function fn(){
var num = 10
// function fun(){
//     console.log(num);
// } 
// 使用return 高级函数 可以从一个作用域访问另一个函数的局部变量,相当于继承
return function(){
console.log(num);
}
}
// fn.apply()   执行后return 一个函数
console.log(fn.apply());
// 定义函数后在调用,可以实现全局调用
var f = fn()
f();
}())
  1. 主要作用:延伸了变量的作用范围

案例获取元素索引号,打印元素的内容类似

// 第一种使用动态添加属性来获取某个索引号
var lis = document.querySelectorAll('ul li') 
// console.log(lis);
for(var i =0;i<lis.length;i++){
    lis[i].index = i
    lis[i].onclick =function(){
        console.log(this.index);
    }
}
// 第二种使用闭包的方法获取某个点击元素的索引号
for(var i = 0;i<lis.length;i++){
    (function(i){
        lis[i].onclick = function(){
            console.log(i);
        }
    })(i)
}

案例打车价格

    // <!-- 使用闭包来实现 打车的收费,定义起步价;10  超过3公里 按/公里 5 ,如果有拥堵的情况多收10 -->
    var car = (function(){
        var start = 10
        var total = 0
        return {
            price:function(n){
                n<=3 ? total = start : total = start + (n-3)*5
                return total
            },
            yd:function(flag){
                return flag ? total+10 :total
            }
        }
    })()
    console.log(car.price(parseFloat(prompt('请输入公里数:'))));
    console.log(car.yd(1));

闭包思考重点

  1. 匿名函数中的this指向为window,立即执行函数封装功能不污染全局变量
  2. 判断this的指向 这里的this指向的是函数的调用者,对象,使用了局部变量 闭包使用
// 匿名函数中的this指向为window,立即执行函数封装功能不污染全局变量
var name = 'the window'
var obj = {
    name: 'world',
    sun: function(){
        return function(){
            return this.name
        }
    }
}
console.log(obj.sun()());
// 判断this的指向  这里的this指向的是函数的调用者,对象,使用了局部变量 闭包使用
var uname = 'tt'
var objs = {
    uname:'kk',
    ff:function(){
        var that = this
        return function(){
            return that.uname;
        }
    }
}
// 立即执行函数
console.log(objs.ff()());  

递归函数

  1. 在函数的内部自己调用自己
  2. 递归函数中必须加退出语句
// var num = 1;
// function fn() {
//     console.log(6);
//     if (num == 6) {
//         return;
//     } num++; 
//     fn();
// }
// fn();
// 使用递归函数求阶乘
function sun(n){
    if(n==1){
        return 1;
    }
    return n * sun(n-1)
}
sun(3);
console.log(sun(3));
        // 使用递归函数求斐波那契数列(兔子序列)
        function fb(n){
            if(n==1 || n==2){
                return 1;
            }
            return fb(n-1) +fb(n-2)
        }
        console.log(fb(6));
// 使用递归查找对象属性值,深度查找 
var obj = [{
    id: 1,
    name: 'd',
    foods: [{
        id: 11,
        name: 'w'
    }, {
        id: 12,
        name: 'u'
    }]
},
{
    id: 2,
    name: 's'
}]
// 开始遍历
function getId(json, id) {
    json.forEach(function (item) {
        if (item.id == id) {
            console.log(item);
        } else if (item.foods && item.foods.length != 0) {
            getId(item.foods, id)
        }
    })
}
getId(obj, 1)
getId(obj, 11)
getId(obj, 2)

浅拷贝和深拷贝

  1. assign(目标对象,源对象),浅拷贝
  2. 深拷贝 使用递归函数
        // 浅拷贝只拷贝地址,会影响原来的数据,不会新建一个对象
        var obj ={
            id:1,
            name:'s',
            msg:{
                sex:'nan',
                age:18
            },
            color:['red','green']
        }
        var o = []
        // for (var k in obj){
        //     o[k] = obj[k]
        // }
        // console.log(o);
        // o.msg.sex = 2
        // console.log(o);
        // console.log(obj);
        // 使用assign方法,类似与浅拷贝
        // Object.assign(o,obj)
        // o.msg.sex = 17
        // console.log(o);
        // console.log(obj);


        // 深拷贝
        function Deepcopy(newobj,oldobj){
            for(var k in oldobj){
                // 判断属性值属于哪种数据类型
                var item = oldobj[k]
                // 判断属性值是否为数组,数组也属于对象,注意顺序
                if(item instanceof Array){
                    newobj[k] = []
                    Deepcopy(newobj[k],item)
                }else if(item instanceof Object){
                    newobj[k] = {}
                    Deepcopy(newobj[k],item)
                }
                else{
                    newobj[k] = item;
                }
                // 判断属性值是否为对象
                // 判断属性值是否为简单数据类型
            }
        }
        Deepcopy(o,obj)
        // 深拷贝对源对象无影响
        o.msg.sex = '1'
        console.log(o);
        console.log(obj);

正则表达式

  1. 对象 用于匹配字符串中字符组合的模式
  2. 匹配,替换,提取
  3. 不需要加引号

创建正则表达式

  1. 使用RegExp对象来创建 格式var 变量名 = new RegExp(/ /)
  2. 利用字面量创建 格式 var rg = /123/

测试是否符合规范

  1. test() 正则对象方法 表达式.test(str) 返回true/false

特殊字符

  1. 元字符 ^ + - / * 等等
  2. 边界符 ^ $ 开头或者结尾
  3. 字符类:[] 表示有一系列字符可供选择,匹配一个即可 -表示范围
  4. 如果中括号里面有^表示取反
  5. 量词符 设置模式出现的次数
  6. 量词,中间不要有空格 ,注意如果是 /^abc{3}$/ 表示的是将c重复三次 ,如果加了小括号(abc)按前面的三个重复执行三次
var ld = /111/
//(1) /11/ 表示只要字符串中含有这些相连字符,都满足条件
console.log(ld.test(11)); //false
// 开头
var ldd = /^11/ 
console.log(ldd.test(111)); //true
// 满足结尾条件
var ldd = /11$/
console.log(ldd.test(11)); //true
// 满足指定条件
var ldd = /^11$/
console.log(ldd.test(11)); //true
console.log('我是分割线----------------------');
// (2) 字符类 []  表示只要有满足条件的即可,无序
var ld1 = /[abc]/
console.log(ld1.test('ansc')); // true
console.log(ld1.test('cse')); // true
// 表示所匹配的字符必须为 a/b/c 才行
var ld2 = /^[abc]$/ 
console.log(ld2.test('cba')); //false
// a-z 表示 26个英文字母 - 表示范围 ,表示从以下条件中任意一个字符如果满足为true/false 中括号内的^表示的是取反 ^[]$ 表示任意一个字符
var ld3 = /^[^a-zA-Z0-9_-]$/
console.log(ld3.test('zzz')); //false
console.log(ld3.test('=')); //true
console.log('------------------------');
// (3) 量词符 重复次数 * 表示0||n ; + 表示>=0; ? 表示 1||0; {3,} 表示>=3;{4,16} >=4 <=16
var reg = /^a*$/
console.log(reg.test(''));  // true
console.log(reg.test('a')); // true
console.log(reg.test('aa'));// true
var reg1 = /^a+$/
console.log(reg1.test('')); // false
console.log(reg1.test('a'));//true
var reg2 = /^a?$/
console.log(reg2.test('')); // true
console.log(reg2.test('a')); // true
console.log(reg2.test('aa')); // false
var reg3 = /^a{4,}$/
console.log(reg3.test('aaaa')); //true
var reg4 = /^a{4,16}$/
console.log(reg4.test('aaaaaaaaa'));  //true

表单验证案例

    <style>
        .right{
            color:#064406
        }
        .error{
            color: #580808;
        }
    </style>
    <input type="text" name="" id=""> <span>请输入6-16位的字符</span>
    <script>
        var reg = /^[a-zA-Z0-9]{3,16}$/
        var input = document.querySelector('input')
        var span  = document.querySelector('span')
        input.onblur = function(){
            if(reg.test(this.value)){
                console.log('输入正确!!');
                span.className = 'right'
                span.innerHTML = '您输入的格式正确'
            }else{
                console.log('输入错误');
                span.className = 'error'
                span.innerHTML = '您输入的格式有误'
            }
        }
    </script>

预定义类

  1. \d \D 分别匹配所有数字和匹配所有的非数字
  2. \w 匹配任意的字母,数字和下划线,相当于 [^a-zA-Z0-9_] 大写W表示非数字非字母,非下划线
  3. \ s 匹配空格 大写表示非
  4. 正则里面的或者用符号 | 表示
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <title>Document</title>
</head>

<body>
    <style>
        body {
            background-color: #ccc;
        }

        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        input {
            width: 170px;
            padding: 5px;
            border-radius: 5px;
            outline: none;
            border: 1px solid #888;
            margin-left: 10px;
        }


        .fa-exclamation-circle {
            color: #0099ff;
            font-size: 12px;
        }

        .fa-times-circle {
            color: red;
            font-size: 12px;
        }

        .fa-check-circle {
            color: green;
            font-size: 12px;
        }

        .box {
            width: 600px;
            height: 300px;
            margin: 50px auto;
            border: 2px solid #888;
            border-radius: 10px;
            padding: 10px;
        }

        .w {
            margin: 10px;
        }
    </style>
    <div class="box">
        <div class="w">手机号<input type="text" placeholder="请输入手机号码" class="phone">
            <i class="fa"></i>
        </div>
        <div class="w">QQ<input type="text" placeholder="请输入QQ号码" class="qq">
            <i class="fa"></i>
        </div>
        <div class="w">用户名<input type="text" name="" id="" placeholder="请输入密码" value="" class="user">
            <i class="fa"></i>
        </div>
        <div class="w">密码<input type="password" name="" id="" placeholder="请输入密码" value="" class="secret">
            <i class="fa"></i>
        </div>
        <div class="w">确认密码<input type="password" name="" id="" placeholder="请输入密码" value="" class="suresecret">
            <i class="fa"></i>
        </div>
    </div>

    <!-- <span class="fa fa-times-circle">fa fa-check-circle密码较短</span></div> -->
    <script>
        // 第一种不使用正则使用if判断条件
        // 知识回顾 兄弟节点  nextSibling属性与nextElementSibling属性的差别:
        // nextSibling属性返回元素节点之后的兄弟节点(包括文本节点、注释节点即回车、换行、空格、文本等等);
        // nextElementSibling属性只返回元素节点之后的兄弟元素节点(不包括文本节点、注释节点);
        var secret = document.querySelector('.secret');
        var is = document.querySelectorAll('i');
        // 密码的设置  使用普通方法
        secret.onfocus = function () {
            this.nextElementSibling.className = 'fa fa-exclamation-circle';
            this.nextElementSibling.innerHTML = '请输入6-16位字符的密码';
        }
        secret.onblur = function () {
            var inputli = this.nextElementSibling
            var inputli = this.nextElementSibling
            if (this.value == '') {
                inputli.innerHTML = ''
                inputli.className = '';
            } else if (secret.value.length < 6 || secret.value.length > 16) {
                inputli.className = 'fa fa-times-circle';
                inputli.nextElementSibling.innerHTML = '您输入的密码不符合要求,请输入6-16位字符'
            }
            else {
                inputli.className = 'fa fa-check-circle';
                inputli.innerHTML = '您输入的格式正确!!'
            }
        }
        // 第二种使用正则判断, 首先获取元素,手机号案例
        var phone = document.querySelector('.phone')
        var pnum = /^1[3|4|5|8|9]\d{9}$/
        // 然后是给元素添加事件,获取焦点和失去焦点
        phone.onfocus = function () {
            this.nextElementSibling.className = 'fa fa-exclamation-circle';
            this.nextElementSibling.innerHTML = '请输入1-11位字符的手机号码';
        }
        phone.onblur = function () {
            var inputli = this.nextElementSibling
            if (this.value == '') {
                inputli.innerHTML = ''
                inputli.className = '';
            } else if (pnum.test(this.value)) {
                inputli.className = 'fa fa-check-circle';
                inputli.innerHTML = '您输入的格式正确!!'
            } else {
                inputli.className = 'fa fa-times-circle';
                inputli.innerHTML = '您输入的手机号格式有误,请输入1-11位的手机号码'
            }
        }
        // 第三种 封装一个函数,如果需要判断的表单过多
        var qq = document.querySelector('.qq')
        var qqreg = /^[1-9]\d{4,9}$/
        // 函数格式  input表示所要判断嗯等元素对象,i表示获得焦点时所呈现的条件,reg为每个表单的正则判断,errorend表示失去焦点后如果不满足正则条件所返回的内容  这里还用到了闭包
        function Judge(input, i, reg, errorend) {
            input.onfocus = function () {
                this.nextElementSibling.className = 'fa fa-exclamation-circle';
                this.nextElementSibling.innerHTML = i
            }
            input.onblur = function () {
                var inputli = this.nextElementSibling
                if (this.value == '') {
                    inputli.innerHTML = ''
                    inputli.className = '';
                } else if (reg.test(this.value)) {
                    inputli.className = 'fa fa-check-circle';
                    inputli.innerHTML = '您输入的格式正确!!'
                } else {
                    inputli.className = 'fa fa-times-circle';
                    inputli.innerHTML = errorend
                }
            }
        }
        var qq = Judge(qq, '请输入5-10位的号码', qqreg, '您输入的格式错误,请输入5-10位的号码')
        // 编写昵称的正则表达式,获取元素,格式要求为中文字符
        var user = document.querySelector('.user')
        var userreg = /^[\u4e00-\u9fa5]{3,5}$/
        Judge(user, '请输入3-5位的中文字符', userreg, '你输入的格式有误,请重新输入3-5位的中文字符')
        // 获取确认密码 
        var suresecret = document.querySelector('.suresecret')
        suresecret.onfocus = function () {
            if (this.value == '') {
                this.nextElementSibling.className = ''
                this.nextElementSibling.innerHTML = ''
            }
        }
        suresecret.onblur = function () {
            var inputli = this.nextElementSibling
            if (this.value == secret.value && this.value != '') {
                inputli.className = 'fa fa-check-circle';
                inputli.innerHTML = '两次密码一致!!'
            } else {
                inputli.className = 'fa fa-times-circle';
                inputli.innerHTML = '两次密码不一致请重新输入!!!'
            }
        }
    </script>
</body>

</html>

正则表达式替换

  1. stringObject.repalce('被替换的字符/正则表达式',' 要替换的字符') 使用repalce来实现字符串的替换
  2. /表达式/[switch] swith参数 也称为i修饰符
  • g 全局匹配 //g
  • i 忽略大小写

ES6声明变量的关键字

ECMAScript 脚本语言

let关键字

  1. let 声明变量
  • 块级作用域 {}
  • 块级作用域 在大括号中使用let关键词才具有块级作用域
  • 防止循环变量变成全局变量
  • 使用let关键字的变量没有变量提升 先声明在提升
  • 使用let关键词声明的变量具有暂时性死区 与所在的{}绑定
// 经典面试题 使用var 定义变量  这里时执行完for循环才会执行函数,所以获取到的数据始终都是全局变量下的数
            var arr = []
            for(var i = 0;i<2;i++){
                arr[i] = function() {
                    console.log(i);
                }
            }
            arr[0]()
            arr[1]()
            console.log('----------------------');
            // 使用let关键字 使用块级作用域效果 
            let arr1 = []
            for(let i = 0;i<2;i++){
                arr1[i] = function(){
                    console.log(i);
                }
            }
            arr1[0]()
            arr1[1]()

const关键字

  1. 声明常量,不能变化的量,变量无法提升
  2. const常量的初始值必须赋值
  3. 常量声明后值不可更改,复杂数据类型中的值可以更改,直接赋值不允许

解构赋值

  1. 允许从数组中按照一一对应的关系提取值,并将值赋给变量
  2. 格式 let [a,b,c] = [1,2,3] 变量与值相对,如果不对应 输出的值为undefined
  3. 对象解构,与数组类似let {},允许使用变量的名字匹配对象的属性
// 第一种获取属性值的方法 对象解构
let per = {name:'ww',sex:'nan'}
let {name,sex} = per
console.log(name);
console.log(sex);
// const 对象解构第二种获取属性值的方法/
let perpon = {name:'mm',age:18} 
let {name:myname,age:ages} = perpon
console.log(myname);
console.log(ages);
// 数组解构
let re =  [1,2,3]
let [a,c,b] = re
console.log(b);

箭头函数

  1. 简化函数定义语法 格式: () => {}
  2. 形参只有一个可以省略外侧的小括号
  3. 箭头函数不绑定this关键字
  4. say方法的箭头函数中的this指向的是定义这个方法的,对象是无法产生作用域的,所以这里的say中的this指向的是window,所以返回的值是undefined
var age = 100
var obj = {
name: 'mm',
age:15,
say:() =>{
console.log(this.name);
}
}

剩余参数

  1. 将不定量的参数表示一个数组
        // 剩余参数 ...args
        const sum = (...args) => {
            // 这里只能使用let,和var 定义变量  不能使用const, 为定值无法改变
            let total = 0;
            // 遍历传入数组的值
            args.forEach(items => total += items)
            return total
        } 
        console.log(sum(1,2,3))
        console.log(sum(1,2))

扩展运算符

  1. 可以将数组拆分成以分隔的参数序列 在控制器中为空格分隔符
  2. 可以合并数组
  3. 将伪数组转换为真正的数组 [...ary] ary为获取元素所定义的属性
// 方法一
let arr = [1, 2, 3]
let a = [4, 5, 6]
let c = [...a, ...arr]
console.log(c);
// 方法二使用push方法
arr.push(...a)
console.log(arr);
  1. array.from() 也可以将伪数组转换为真正的数组
    // 使用from的方法将伪数组转换为数组
    let obj = {
        '0':'a',
        '1':'b',
        '2':'c',
        length:3
    }
    console.log(obj);
    console.log(Array.from(obj));

find()和findIndex()方法 includes(),startsWith,endsWith()

  1. 找出第一个符合条件的成员 find((,) => {})
  2. findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引
  3. includes() 判断数组中是否包含某个值 括号内为判断的数组内容 返回值为true或者false
  4. 将某个字符串重复输出n次 repeat(n)

模板字符串

  1. ${变量名}, 注意必须加 ``反引号
  2. 可以调用函数
  3. 模板字符串可以换行

Set数据结构

  1. 类似于数组,成员的值都是唯一的,没有重复的值
  2. 本身是一个构造函数
  3. 可以使用set()方法来实现数组去重
  4. 使用add方法向set()中添加值
// 伪数组
let obj = {
    '0': 1,
    '1': 2,
    '2': 'a',
    length: 3
}
console.log(obj);
// 使用Array.from()的方法将伪数组转化为真正的数组
console.log(Array.from(obj));

// 使用find()方法  判断数组中是否存在某个元素并返回满足条件的第一个值,如果没有满足条件的则返回的值为undefined
// let a = [1,2,3]
let a = [{
    id: 1,
    name: 'm'
},
{
    id: 2,
    name: 'a'
}]
console.log(a.find(item => item.id == 3));

// 使用findIndex()方法来判断数组或者对象中的值是否存在,如果存在则返回的值为该元素的索引号,不存在则返回-1
console.log(a.findIndex(item => item.id == 3));

// 使用includes() 方法用于判断字符串或者数组是否包含指定的子字符串,返回布尔值
let b = [1, 2, 3]
console.log(b.includes(1))

// 模板字符串  使用格式 `${变量名}`  必须加``反引号 符号,模板字符串可以换行
let name = 'world'
let uname = `hello ${name} wo`
console.log(uname);
console.log('startsWith()'+uname.startsWith('hello'));
console.log('endsWith()'+uname.endsWith('wo'));
console.log(`你好世界 ${name}`);
console.log(uname.repeat(4))  // 使用repeat()方法 将字符串重复n次
// 模板字符串可以调用函数   `$(fn())`

// Set() 方法

const ol = new Set(['a','b','c' ,'a']) // 将重复的值过滤掉
console.log(ol);
console.log(ol.size);
// 利用set()方法 实现数组去重
console.log([...ol]);

// 使用add方法
let n = new Set()
n.add('a').add('b')  // 向set结构中添加值
n.delete('a')
console.log([...n]);  //将set结构中的值删除
console.log(n.has('a'));  // 使用has方法来判断set结构中是否存在某个值
n.clear() // 可以将set结构中的值清除
console.log([...n]);  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Harry-iu

顺手给小编加个鸡腿????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值