尧子陌

尧子陌 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织 segmentfault.com/u/yaozimo 编辑
编辑

保持呼吸 坚持学习

前端爱好者。

个人动态

尧子陌 收藏了文章 · 9月20日

javascript高级(5)

ES6

ES:全称ECMAScript,它是由ECMA国际标准化组织制定的一项脚本语言的标准化规范。

image.png

所谓的ES6,指的是2015年以后的版本

let关键字

ES6中新增声明变量的关键字
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>let关键字声明变量</title>
</head>
<body>

</body>
<script>
    let num = 20;
    console.log(num) //20
</script>
</html>

image.png

具有的特点

  • 具有块级作用域

所谓的块级作用域,简单而言 就是{}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>块级作用域</title>
    </head>
    <body>

    </body>
    <script>
        if (true) {
            let a = 20;
            console.log(a);
            if (true) {
                let b = 50;
                console.log(b) //50
            }
            console.log(b) //b is not define
        }
    </script>
</html>

image.png

  • 不存在变量提升
  • 具有暂时性死区
查看原文

尧子陌 发布了文章 · 9月20日

javascript高级(5)

ES6

ES:全称ECMAScript,它是由ECMA国际标准化组织制定的一项脚本语言的标准化规范。

image.png

所谓的ES6,指的是2015年以后的版本

let关键字

ES6中新增声明变量的关键字
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>let关键字声明变量</title>
</head>
<body>

</body>
<script>
    let num = 20;
    console.log(num) //20
</script>
</html>

image.png

具有的特点

  • 具有块级作用域

所谓的块级作用域,简单而言 就是{}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>块级作用域</title>
    </head>
    <body>

    </body>
    <script>
        if (true) {
            let a = 20;
            console.log(a);
            if (true) {
                let b = 50;
                console.log(b) //50
            }
            console.log(b) //b is not define
        }
    </script>
</html>

image.png

  • 不存在变量提升
  • 具有暂时性死区
查看原文

赞 2 收藏 2 评论 0

尧子陌 收藏了文章 · 9月19日

javascript高级(4)

正则表达式

正则表达式是一个对象,主要是用于匹配字符串中字符组合的模式。

特点

  • 可过滤页面内容的一些敏感词
  • 从字符串获取我们想要的特定部分。

创建正则表达式

在javascript中,可以通过两种方式创建正则表达式
test()是正则表达式对象的方法,用来检验字符串是否符合该规则,返回值为true或者false.

注意:正则表达式不需要加引号,不管是字符串或值型

1.通过RegExp对象的方式创建正则表达式

var 变量名 = new RegExp(/表达式/)

2.通过字面量创建

var 变量名 = /表达式/

注释中间放表达式就是正则表达式字面量


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>正则表达式</title>
</head>
<body>

</body>
<script>
  //1.利用RegExp对象来创建正则表达式
  let regexp = new  RegExp(/123/);
  console.log(regexp)


  //2.利用字面量的方式来创建
  let regexp2 = /123/;
  console.log(regexp2)

  //test()方法用来检验字符串参数是否符合正则表达式的规则
  console.log(regexp.test(123));
  console.log(regexp2.test(123));
</script>
</html>

image.png

正则表达式组成

一个正则表达式可以由简单的字符组成,比如/abc/,也可以是简单与特殊字符的组合,如 ^ 、$ 、+ 等。

特殊字符非常多,可以参考:

边界符

正则表达式中的边界符(位置符)用来提示字符所在的位置,主要有两个字符

image.png

如果^与$同时存在,则代表精准匹配

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之边界符</title>
</head>
<body>

</body>
<script>
    let regexp = /abc/;
    //test()方法里面的参数只要包含abc字符,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('abcd'))//true
    console.log(regexp.test('abcde'))//true

    let regexp2 = /^abc/
    //test()方法里面的参数必须以abc开头,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('bacd'))//false
    console.log(regexp.test('abcde'))//true

    let regexp3 = /^abc$/
    //test()方法里面的参数必须是abc,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('bacd'))//false

</script>
</html>

image.png

字符类

[]:表示有一系列的字符可以选择,只要匹配其中一个便可以了


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之字符类</title>
</head>
<body>

</body>
<script>
    let regexp = /[abc]/ //只需包含a或b或c的字符 返回值即可true
    console.log(regexp.test('name'));
    console.log(regexp.test('body'));
    console.log(regexp.test('chinese'));
    console.log('-----------------------------------')
    
    
    
    let regexp2 = /^[abc]$/ //三选一,只能是a或b或c中的任意字符,返回值为true.
    console.log(regexp2.test('a'));
    console.log(regexp2.test('b'));
    console.log(regexp2.test('c'));
    console.log(regexp2.test('d'));//false
    console.log('-----------------------------------')
    
    
    

    let regexp3 = /^[a-z]$/ //多选一,只能是26个小写字母中任意一个字符,返回值为true.
    console.log(regexp3.test('a'));
    console.log(regexp3.test('b'));
    console.log(regexp3.test('c'));
    console.log(regexp3.test('d'));
    console.log('-----------------------------------')
    
    
    

    let regexp4 = /^[a-zA-Z0-9_-]$/ //多选一,只要是26个小写字母或26个大写字母或0-9和_-中任意一个字符,返回值为true.
    console.log(regexp4.test('A'));
    console.log(regexp4.test('b'));
    console.log(regexp4.test('0'));
    console.log(regexp4.test('!')); //false
    console.log('-----------------------------------')
    
    
    


    let regexp5 = /^[^a-zA-Z0-9_-]$/ //多选一,[]里面的^是取反的意思,只要不是[]里面的字符 都为true
    console.log(regexp5.test('A'));
    console.log(regexp5.test('b'));
    console.log(regexp5.test('0'));
    console.log(regexp5.test('!')); //true
    console.log('-----------------------------------')
    

</script>
</html>

image.png

量词

量词是用来设定某个模式出现的次数
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式之量词</title>
    </head>
    <body>

    </body>
    <!--量词符用来设定某个模式出现的次数-->
    <script>
        let regexp = /^a$/
        console.log(regexp.test('a'))
        console.log(regexp.test('aa')) //false
        console.log('----------------------------------------------')



        let regexp1 = /^a*$/ // *相当>=0,,可以出现0次或多次
        console.log(regexp1.test('a'))
        console.log(regexp1.test('aa'))
        console.log('----------------------------------------------')


        let regexp2 = /^a+$/ // +相当>=1,,可以出现1次或多次
        console.log(regexp2.test('')) //false
        console.log(regexp2.test('a'))
        console.log(regexp2.test('aa'))
        console.log('----------------------------------------------')



        let regexp3 = /^a?$/ // ?相当0|| 1次,
        console.log(regexp3.test(''))
        console.log(regexp3.test('a'))
        console.log(regexp3.test('aa')) //false
        console.log('----------------------------------------------')


        let regexp4 = /^a{3}$/ // {3}可以出现3次
        console.log(regexp4.test('')) //false
        console.log(regexp4.test('a')) //false
        console.log(regexp4.test('aaa'))
        console.log('----------------------------------------------')



        let regexp5 = /^a{3,}$/ // {3,}可以出现3次或大于3次
        console.log(regexp5.test('')) //false
        console.log(regexp5.test('aaa'))
        console.log(regexp5.test('aaaaaa'))
        console.log('----------------------------------------------')


        let regexp6 = /^a{3,16}$/ // {3,16}可以出现3到16次
        console.log(regexp6.test('')) //false
        console.log(regexp6.test('aaa'))
        console.log(regexp6.test('aaaaaaaaaaaaaa'))
        console.log('----------------------------------------------')
    </script>
</html>

image.png

量词的延伸


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>正则表达式之量词</title>
    </head>
    <body>

    </body>
    <script>
        let regrxp = /^[a-zA-Z0-9_-]{6,16}$/; //输入的自述为6~16位之间 且正则表达式里面的匹配字符要完全符合
        console.log(regrxp.test('a'))//false
        console.log(regrxp.test('andy2020'))
        console.log(regrxp.test('andy202020'))
        console.log(regrxp.test('YaoZiMo'))
    </script>
</html>

image.png

表单验证

核心思路

1.用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为 6~16位.

2.首先准备好这种正则表达式模式 /$[a-zA-Z0-9-_]{6,16}^/

3.当表单失去焦点就开始验证.

4.如果符合正则规范, 则让后面的span标签添加 right 类.

5.如果不符合正则规范, 则让后面的span标签添加 wrong 类.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式之表单验证</title>
        <style>
            * {
            margin: 0;
            padding: 0;
        }
        span {
            color: #aaa;
            font-size: 14px;
        }
        .right {
            color:green;
        }
        .wrong {
            color: red;
        }
    </style>
    <body>
        <input type="text" class="ipt"> <span>请输入用户名</span>

    </body>
    <script>
        //1.获取元素
        var ipt = document.querySelector('.ipt')
        var span = document.querySelector('span')

        //2.正则表达式的匹配规则
        let regrxp = /^[a-zA-Z0-9_-]{6,16}$/;
        //3.设置鼠标失去焦点事件
        ipt.onblur = function() {
            if (regrxp.test(ipt.value)) {
                span.className = 'right'
                span.innerHTML = '用户输入的用户名格式正确'
            } else {
                span.className = 'wrong'
                span.innerHTML = '用户输入的用户名的格式不正确'
            }

        }
    </script>
</html>

image

括号总结

大括号:量词符,里面表示匹配次数

中括号:字符集合。匹配方括号里面的任意字符

小括号:表示优先级

在线测试:https://c.runoob.com/

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>正则表达式之括号总结</title>
</head>

<body>

</body>
<script>
    // 中括号:字符集合,匹配方括号里面的任意字符
    var ragExp = /^[abc]$/
    console.log(ragExp.test('a'));
    console.log(ragExp.test('b'));
    console.log(ragExp.test('c'));

    // 大括号 设定模式的匹配次数
    var ragExp1 = /^abc{3}$/
    console.log(ragExp1.test('a')); //false
    console.log(ragExp1.test('b')); //false
    console.log(ragExp1.test('abccc'));

    // 小括号 表示优先级
    var ragExp2 = /^(abc){3}$/
    console.log(ragExp2.test('a')); //false
    console.log(ragExp2.test('b')); //false
    console.log(ragExp2.test('abcabcabc'));
</script>

</html>

image.png

预定义类

预定义类指的是某些常见模式的简写方式

image.png

座机号码验证

座机号码验证: 全国座机号码 两种格式: 010-12345678 或者 0530-1234567

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之座机号码验证</title>
</head>
<body>
</body>
<script>
    // 座机号码验证: 全国座机号码  两种格式:   010-12345678 或者 0530-1234567
 var regExp = /^d{3,4}-d{7,8}$/
</script>
</html>

表单

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>正则表达式之表单验证</title>
    <style>
        body {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .nav {
            list-style: none;
            width: 600px;
            padding: 20px;
            margin: 200px auto;
            border: 1px solid black;

        }

        .nav li {
            margin-bottom: 20px;
        }

        lable {
            display: inline-block;
            width: 80px;
        }
        span {
            margin-left:20px;
        }
        input[type='submit'] {
            margin-left: 96px;
            margin-right: 50px;
        }
        .right {
            color: green;
        }
        .wrong {
            color: red;
        }
    </style>
</head>
<body>
<form action="Yao.php"></form>
<ul class="nav">

    <li>
        <lable for="">用户名:</lable>
        <input type="text" class="user"><span></span>
    </li>

    <li>
        <lable for="">密 码:</lable>
        <input type="password" class="password"><span></span>
    </li>
    <li>
        <input type="submit" value="登陆"> <input type="reset" value="提交">
    </li>
</ul>

</body>
<script>
    var user = document.querySelector('.user')
    console.log(user)
    var password = document.querySelector('.password');
    console.log(password)
    var regexp = /^[a-zA-Z0-9_-]{6,16}$/;
    var regexp2 = /\w{3,20}$/;
    user.onblur = function() {
        if(regexp.test(user.value)){
            console.log(11);
            this.nextElementSibling.className='right'
            this.nextElementSibling.innerHTML='通过'
        }else {
            this.nextElementSibling.className='wrong'
            this.nextElementSibling.innerHTML='不通过'
        }
    }
    password.onblur = function() {
        if(regexp.test(password.value)){

            this.nextElementSibling.className='right'
            this.nextElementSibling.innerHTML='通过'
        }else {
            this.nextElementSibling.className='wrong'
            this.nextElementSibling.innerHTML='不通过'
        }
    }
</script>
</html>

image

正则表达式中的替换

replace 替换

stringObject.replace(regexp/substr,replacement)

第一个参数: 被替换的字符串 或者 正则表达式

第二个参数: 替换为的字符串

返回值是一个替换完毕的新字符串

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式中的替换</title>
    </head>
    <body>
        <textarea name="" id="" cols="30" rows="10"></textarea>
        <button>提交</button>
        <div></div>
    </body>
    <script>
        var text= document.querySelector('textarea')
        var bth = document.querySelector('button');
        var div = document.querySelector('div')
        bth.onclick = function(){
            div.innerHTML =text.value.replace(/大傻瓜|铁憨憨/g,'**')
        }
    </script>
</html>

image.png

修饰符

/表达式/[switch]

switch(也称为修饰符) 按照什么样的模式来匹配. 有三种值:

  • g:全局匹配
  • i:忽略大小写
  • gi:全局匹配 + 忽略大小写
查看原文

尧子陌 发布了文章 · 9月19日

javascript高级(4)

正则表达式

正则表达式是一个对象,主要是用于匹配字符串中字符组合的模式。

特点

  • 可过滤页面内容的一些敏感词
  • 从字符串获取我们想要的特定部分。

创建正则表达式

在javascript中,可以通过两种方式创建正则表达式
test()是正则表达式对象的方法,用来检验字符串是否符合该规则,返回值为true或者false.

注意:正则表达式不需要加引号,不管是字符串或值型

1.通过RegExp对象的方式创建正则表达式

var 变量名 = new RegExp(/表达式/)

2.通过字面量创建

var 变量名 = /表达式/

注释中间放表达式就是正则表达式字面量


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>正则表达式</title>
</head>
<body>

</body>
<script>
  //1.利用RegExp对象来创建正则表达式
  let regexp = new  RegExp(/123/);
  console.log(regexp)


  //2.利用字面量的方式来创建
  let regexp2 = /123/;
  console.log(regexp2)

  //test()方法用来检验字符串参数是否符合正则表达式的规则
  console.log(regexp.test(123));
  console.log(regexp2.test(123));
</script>
</html>

image.png

正则表达式组成

一个正则表达式可以由简单的字符组成,比如/abc/,也可以是简单与特殊字符的组合,如 ^ 、$ 、+ 等。

特殊字符非常多,可以参考:

边界符

正则表达式中的边界符(位置符)用来提示字符所在的位置,主要有两个字符

image.png

如果^与$同时存在,则代表精准匹配

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之边界符</title>
</head>
<body>

</body>
<script>
    let regexp = /abc/;
    //test()方法里面的参数只要包含abc字符,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('abcd'))//true
    console.log(regexp.test('abcde'))//true

    let regexp2 = /^abc/
    //test()方法里面的参数必须以abc开头,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('bacd'))//false
    console.log(regexp.test('abcde'))//true

    let regexp3 = /^abc$/
    //test()方法里面的参数必须是abc,即为true
    console.log(regexp.test('abc'))//true
    console.log(regexp.test('bacd'))//false

</script>
</html>

image.png

字符类

[]:表示有一系列的字符可以选择,只要匹配其中一个便可以了


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之字符类</title>
</head>
<body>

</body>
<script>
    let regexp = /[abc]/ //只需包含a或b或c的字符 返回值即可true
    console.log(regexp.test('name'));
    console.log(regexp.test('body'));
    console.log(regexp.test('chinese'));
    console.log('-----------------------------------')
    
    
    
    let regexp2 = /^[abc]$/ //三选一,只能是a或b或c中的任意字符,返回值为true.
    console.log(regexp2.test('a'));
    console.log(regexp2.test('b'));
    console.log(regexp2.test('c'));
    console.log(regexp2.test('d'));//false
    console.log('-----------------------------------')
    
    
    

    let regexp3 = /^[a-z]$/ //多选一,只能是26个小写字母中任意一个字符,返回值为true.
    console.log(regexp3.test('a'));
    console.log(regexp3.test('b'));
    console.log(regexp3.test('c'));
    console.log(regexp3.test('d'));
    console.log('-----------------------------------')
    
    
    

    let regexp4 = /^[a-zA-Z0-9_-]$/ //多选一,只要是26个小写字母或26个大写字母或0-9和_-中任意一个字符,返回值为true.
    console.log(regexp4.test('A'));
    console.log(regexp4.test('b'));
    console.log(regexp4.test('0'));
    console.log(regexp4.test('!')); //false
    console.log('-----------------------------------')
    
    
    


    let regexp5 = /^[^a-zA-Z0-9_-]$/ //多选一,[]里面的^是取反的意思,只要不是[]里面的字符 都为true
    console.log(regexp5.test('A'));
    console.log(regexp5.test('b'));
    console.log(regexp5.test('0'));
    console.log(regexp5.test('!')); //true
    console.log('-----------------------------------')
    

</script>
</html>

image.png

量词

量词是用来设定某个模式出现的次数
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式之量词</title>
    </head>
    <body>

    </body>
    <!--量词符用来设定某个模式出现的次数-->
    <script>
        let regexp = /^a$/
        console.log(regexp.test('a'))
        console.log(regexp.test('aa')) //false
        console.log('----------------------------------------------')



        let regexp1 = /^a*$/ // *相当>=0,,可以出现0次或多次
        console.log(regexp1.test('a'))
        console.log(regexp1.test('aa'))
        console.log('----------------------------------------------')


        let regexp2 = /^a+$/ // +相当>=1,,可以出现1次或多次
        console.log(regexp2.test('')) //false
        console.log(regexp2.test('a'))
        console.log(regexp2.test('aa'))
        console.log('----------------------------------------------')



        let regexp3 = /^a?$/ // ?相当0|| 1次,
        console.log(regexp3.test(''))
        console.log(regexp3.test('a'))
        console.log(regexp3.test('aa')) //false
        console.log('----------------------------------------------')


        let regexp4 = /^a{3}$/ // {3}可以出现3次
        console.log(regexp4.test('')) //false
        console.log(regexp4.test('a')) //false
        console.log(regexp4.test('aaa'))
        console.log('----------------------------------------------')



        let regexp5 = /^a{3,}$/ // {3,}可以出现3次或大于3次
        console.log(regexp5.test('')) //false
        console.log(regexp5.test('aaa'))
        console.log(regexp5.test('aaaaaa'))
        console.log('----------------------------------------------')


        let regexp6 = /^a{3,16}$/ // {3,16}可以出现3到16次
        console.log(regexp6.test('')) //false
        console.log(regexp6.test('aaa'))
        console.log(regexp6.test('aaaaaaaaaaaaaa'))
        console.log('----------------------------------------------')
    </script>
</html>

image.png

量词的延伸


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>正则表达式之量词</title>
    </head>
    <body>

    </body>
    <script>
        let regrxp = /^[a-zA-Z0-9_-]{6,16}$/; //输入的自述为6~16位之间 且正则表达式里面的匹配字符要完全符合
        console.log(regrxp.test('a'))//false
        console.log(regrxp.test('andy2020'))
        console.log(regrxp.test('andy202020'))
        console.log(regrxp.test('YaoZiMo'))
    </script>
</html>

image.png

表单验证

核心思路

1.用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为 6~16位.

2.首先准备好这种正则表达式模式 /$[a-zA-Z0-9-_]{6,16}^/

3.当表单失去焦点就开始验证.

4.如果符合正则规范, 则让后面的span标签添加 right 类.

5.如果不符合正则规范, 则让后面的span标签添加 wrong 类.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式之表单验证</title>
        <style>
            * {
            margin: 0;
            padding: 0;
        }
        span {
            color: #aaa;
            font-size: 14px;
        }
        .right {
            color:green;
        }
        .wrong {
            color: red;
        }
    </style>
    <body>
        <input type="text" class="ipt"> <span>请输入用户名</span>

    </body>
    <script>
        //1.获取元素
        var ipt = document.querySelector('.ipt')
        var span = document.querySelector('span')

        //2.正则表达式的匹配规则
        let regrxp = /^[a-zA-Z0-9_-]{6,16}$/;
        //3.设置鼠标失去焦点事件
        ipt.onblur = function() {
            if (regrxp.test(ipt.value)) {
                span.className = 'right'
                span.innerHTML = '用户输入的用户名格式正确'
            } else {
                span.className = 'wrong'
                span.innerHTML = '用户输入的用户名的格式不正确'
            }

        }
    </script>
</html>

image

括号总结

大括号:量词符,里面表示匹配次数

中括号:字符集合。匹配方括号里面的任意字符

小括号:表示优先级

在线测试:https://c.runoob.com/

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>正则表达式之括号总结</title>
</head>

<body>

</body>
<script>
    // 中括号:字符集合,匹配方括号里面的任意字符
    var ragExp = /^[abc]$/
    console.log(ragExp.test('a'));
    console.log(ragExp.test('b'));
    console.log(ragExp.test('c'));

    // 大括号 设定模式的匹配次数
    var ragExp1 = /^abc{3}$/
    console.log(ragExp1.test('a')); //false
    console.log(ragExp1.test('b')); //false
    console.log(ragExp1.test('abccc'));

    // 小括号 表示优先级
    var ragExp2 = /^(abc){3}$/
    console.log(ragExp2.test('a')); //false
    console.log(ragExp2.test('b')); //false
    console.log(ragExp2.test('abcabcabc'));
</script>

</html>

image.png

预定义类

预定义类指的是某些常见模式的简写方式

image.png

座机号码验证

座机号码验证: 全国座机号码 两种格式: 010-12345678 或者 0530-1234567

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式之座机号码验证</title>
</head>
<body>
</body>
<script>
    // 座机号码验证: 全国座机号码  两种格式:   010-12345678 或者 0530-1234567
 var regExp = /^d{3,4}-d{7,8}$/
</script>
</html>

表单

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>正则表达式之表单验证</title>
    <style>
        body {
            background-color: rgba(0, 0, 0, 0.5);
        }

        .nav {
            list-style: none;
            width: 600px;
            padding: 20px;
            margin: 200px auto;
            border: 1px solid black;

        }

        .nav li {
            margin-bottom: 20px;
        }

        lable {
            display: inline-block;
            width: 80px;
        }
        span {
            margin-left:20px;
        }
        input[type='submit'] {
            margin-left: 96px;
            margin-right: 50px;
        }
        .right {
            color: green;
        }
        .wrong {
            color: red;
        }
    </style>
</head>
<body>
<form action="Yao.php"></form>
<ul class="nav">

    <li>
        <lable for="">用户名:</lable>
        <input type="text" class="user"><span></span>
    </li>

    <li>
        <lable for="">密 码:</lable>
        <input type="password" class="password"><span></span>
    </li>
    <li>
        <input type="submit" value="登陆"> <input type="reset" value="提交">
    </li>
</ul>

</body>
<script>
    var user = document.querySelector('.user')
    console.log(user)
    var password = document.querySelector('.password');
    console.log(password)
    var regexp = /^[a-zA-Z0-9_-]{6,16}$/;
    var regexp2 = /\w{3,20}$/;
    user.onblur = function() {
        if(regexp.test(user.value)){
            console.log(11);
            this.nextElementSibling.className='right'
            this.nextElementSibling.innerHTML='通过'
        }else {
            this.nextElementSibling.className='wrong'
            this.nextElementSibling.innerHTML='不通过'
        }
    }
    password.onblur = function() {
        if(regexp.test(password.value)){

            this.nextElementSibling.className='right'
            this.nextElementSibling.innerHTML='通过'
        }else {
            this.nextElementSibling.className='wrong'
            this.nextElementSibling.innerHTML='不通过'
        }
    }
</script>
</html>

image

正则表达式中的替换

replace 替换

stringObject.replace(regexp/substr,replacement)

第一个参数: 被替换的字符串 或者 正则表达式

第二个参数: 替换为的字符串

返回值是一个替换完毕的新字符串

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>正则表达式中的替换</title>
    </head>
    <body>
        <textarea name="" id="" cols="30" rows="10"></textarea>
        <button>提交</button>
        <div></div>
    </body>
    <script>
        var text= document.querySelector('textarea')
        var bth = document.querySelector('button');
        var div = document.querySelector('div')
        bth.onclick = function(){
            div.innerHTML =text.value.replace(/大傻瓜|铁憨憨/g,'**')
        }
    </script>
</html>

image.png

修饰符

/表达式/[switch]

switch(也称为修饰符) 按照什么样的模式来匹配. 有三种值:

  • g:全局匹配
  • i:忽略大小写
  • gi:全局匹配 + 忽略大小写
查看原文

赞 2 收藏 2 评论 0

尧子陌 收藏了文章 · 9月17日

javascript高级(3)

创建函数的三种样式

1.function声明的普通函数(命名函数)
2.函数表达式(匿名函数)
3.new Function()

var fn =new Function('参数1','参数2',...,'函数体);

  • Function()里面的参数都是字符串格式
  • 第三种方式执行效率比较低,也不方便书写,因此较少使用
  • 所有的函数都是Fnction的实例对象
  • 函数也属于对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数的定义和调用方式</title>
</head>
<body>
<script>
    // 自定义方式
 function fn() {
    }
    // 函数表达式
 var fn = function() {
    }
    // 利用new Function('参数1','参数2','函数体')
 var f = new Function('a','b','return a+b')
    console.log(f(1,2));
    console.dir(f);
    //用来判断f是否是一个对象
 console.log(f instanceof Object)
</script>
</body>
</html>

image.png

不同函数的调用方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>按钮</button>
</body>
<script>
    // 函数的调用方式
 // 1.普通函数的调用
 function fn() {
        console.log('hello word')
    }
    fn()
    // 2.对象类的函数调用
 var obj = {
        say: function () {
            return 'hello word'
 }
    }
    console.log(obj.say())
    // 3.构造函数的调用
 function Star(name, age) {
        this.name = name;
        this.age = age;
    }
    var star1 = new Star('尧子陌', '18');
    console.log(star1.name)
    //4.事件函数的调用
 var bth = document.querySelector('button');
    bth.addEventListener('click', function () {
        console.log('事件函数')
    })
    // 5.定时器函数
 setInterval(function () {
        console.log('定时器函数')
    }, 5000)
</script>
</html>

image

自执行函数

顾名思义:自己调用的函数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自执行函数</title>
</head>
<body>
<script>
    (function () {
        alert('hello word')
    })()
</script>
</body>
</html>

image

this的指向问题

函数内部的this指向,当我们调用的时候才确定

注意:自执行的函数中this指向的是window
image.png

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>函数的this指向</title>
    </head>
    <body>
        <button>按钮</button>
    </body>
    <script>
        // 函数的调用方式

        // 1.普通函数的调用
        function fn() {
            console.log(this) //windows

        }

        fn()
        // 2.对象类的函数调用
        var obj = {
            say: function() {
                console.log(this) //指向o这个对象
            }
        }
        obj.say()

        // 3.构造函数的调用
        function Star(name, age) {
            console.log(this) //构造函数中的this指向的是它的实例化 star
            this.name = name;
            this.age = age;

        }

        var star1 = new Star('尧子陌', '18');
        //4.事件函数的调用
        var bth = document.querySelector('button');
        bth.addEventListener('click', function() {
            console.log(this) //事件函数中的this 指向的是它的调用者bth按钮
        })

        // 5.定时器函数
        setInterval(function() {
            console.log(this) //定时器中的this 指向的是windows
        }, 5000)
    </script>
</html>

image.png

call()方法

call() 方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。

fun.call(thisArg, arg1, arg2, ...)

  • thisArg:在 fun 函数运行时指定的 this 值
  • arg1,arg2:传递的其他参数
  • 返回值就是函数的返回值,因为它就是调用函数
  • 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承


<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>call()</title>
    </head>

    <body>

    </body>
    <script>
        // 改变函数内部的this指向之call()方法
        var o = {
            name: "andy"
        };

        function fn(a, b) {
            console.log(this); //o
            console.log(a + b); //3
        }

        fn.call(o, 1, 2) //call方法不仅可以改变函数内部的this指向,还可以传递参数


        //call()方法主要是为了实现继承


        function Father(name, age, sex) {
            console.log(this)
            this.name = name;
            this.age = age;
            this.sex = sex;

        }

        function Son(name, age, sex) {
            Father.call(this, name, age, sex)
        }

        var son = new Son('刘德华', '18', '男');
        console.log(son)
    </script>

</html>

 

image.png

### apply()方法

apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。

fun.apply(thisArg, [argsArray])

  • thisArg:在fun函数运行时指定的 this 值
  • argsArray:传递的值,必须包含在数组里面
  • 返回值就是函数的返回值,因为它就是调用函数
  • 因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>改变函数内部的this指向之apply()</title>
</head>

<body>

</body>
<script>
    var o = {
        name: 'andy'

    }

    function fn(arr) {
        console.log(this); //此时的this指向的是0;
        console.log(arr)

    }

    fn.apply(o, ['pink']); //注意:第二个参数必须为数组

    // 可以用数组方法实现求数组的最大值
    var arr2 = [1, 66, 22, 55, 108];
    var max = Math.max.apply(Math, arr2);
    var min = Math.min.apply(Math, arr2);
    console.log(max, min)
</script>

</html>

image.png

bind()

bind() 方法不会调用函数。但是能改变函数内部this 指向

fun.bind(thisArg, arg1, arg2, ...)

  • thisArg:在 fun 函数运行时指定的 this 值
  • arg1,arg2:传递的其他参数
  • 返回由指定的 this 值和初始化参数改造的原函数拷贝
  • 因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind()
  
  <!DOCTYPE html>
  <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>改变函数的内部的this指向之bind()方法</title>

    <body>
        <button>按钮</button>
        <button>按钮</button>
        <button>按钮</button>
    </body>
    <script>
        // bind()方法是绑定 捆绑的意思
        var o = {
            name: "andy"
        }

        function fn(a, b) {
            console.log(this)
            console.log(a + b)
        }

        // 注意:bind()方法会改变函数内部的this,但不会调用原来的函数
        var f = fn.bind(o, 1, 2);
        f()

        //案例:当我们点击按钮之后,就禁用这个按钮,三秒之后再次开启这个按钮
        var bths = document.querySelectorAll('button');
        for (var i = 0; i < bths.length; i++) {
            bths[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false
                    // 这里的this指的是bth这个按钮
                }.bind(this), 2000)
            }
        }
    </script>
</html>

  

image

call() apply() bind()之间的区别

区别点:

  1. call 和 apply 会调用函数, 并且改变函数内部this指向.
  2. call 和 apply 传递的参数不一样, call 传递参数 aru1, aru2..形式 apply 必须数组形式[arg]
  3. bind 不会调用函数, 可以改变函数内部this指向.

主要应用场景:

  1. call 经常做继承.
  2. apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
  3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.

严格模式

严格模式的出现,是为了限制非标准严格模式下不标准的语法,并且为ES6做好铺垫
严格模式对正常的 JavaScript 语义做了一些更改:
  1. 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
  2. 消除代码运行的一些不安全之处,保证代码运行的安全。
  3. 提高编译器效率,增加运行速度。
  4. 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比

如一些保留字如:class, enum, export, extends, import, super 不能做变量名

开启严格模式

'use strict' 在script的脚本内放入或在函数内部放入,便等同于开启严格模式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
      // 为脚本开启严格模式
        'use strict'
  </script>
  
  <script type="text/javascript">
        function fn(){
            // 为函数开启严格模式
            'use strict'
        }
  </script>
</body>
</html>


严格模式的变化

  • 严格模式下变量必须先声明才能使用
  • 严格模式下普通函数中的this指向undefined
  • 严格模式下构造函数不加new调用,this指的是undefined
  • 严格模式下定时器中的this指向window
<!DOCTYPE html>
<html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <meta http-equiv="X-UA-Compatible" content="ie=edge">
       <title>严格模式的变化</title>
   </head>
   <body>
       <script type="text/javascript">
           'use strict'
           // 1.变量必须先声明再使用
           var num = 10;
           console.log(10);
           // delete  num; 严格模式下禁用删除变量

           // 2.严格模式下的this指向undefined
           function fn() {
               console.log(this) //严格模式下this指的是undefined
           }
           fn()
           // 3.严格模式下构造函数不加new调用,this指的是undefined
           function Star() {
               console.log(this)
           }
           Star()

           //4.严格模式下定时器的this指向window
           setTimeout(function() {
               console.log(this)
           }, 2000)
       </script>
   </body>
</html>


image.png

高阶函数

高阶函数是对其它函数进行操作的函数,它接受函数作为参数或者将函数作为返回值输出


<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
   </head>
   <body>

   </body>
   <script>
       // 将函数作为参数
       function fn(callback) {
           callback && callback()
       }
       fn(function() {
           alert('hello word')
       })


       //将函数作为返回值输出
       function fn2() {
           return function() {}
       }
       console.log(fn2())
   </script>
</html>

image
此时的fn()及fn2便是高价函数

函数也是一种数据类型,可作为参数传递给另外一个函数作为参数使用,最典型的便是回调函数

 
<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
       <style>
           * {
               margin: 0;
               padding: 0;
           }
           .box {
               position: absolute;
               top:0;
               left: 0;
               width: 200px;
               height: 200px;
               background-color: blueviolet
           }
       </style>
   </head>
   <script data-original="jquery.min.js"></script>
   <body>
       <div class="box"></div>
       
   </body>
   <script>
       $('.box').animate({
           left:200,
           top:200
       },function(){
           $(this).css('background','red')
       })
   </script>
</html>

image

闭包

指有权访问另外一个函数作用域里面的变量的函数

作用:延伸变量的作用范围

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>闭包</title>
    </head>
    <body>
        <div></div>
    </body>
    <script>
        // 所谓的闭包 简单理解:就是有权访问另一个函数的局部变量
        function fn() {
            let num = 10;

            function fun() {
                console.log(num) //10
            }

            fun()
        }

        fn()
    </script>
</html>

image.png

image.png

chrome中调试闭包

  1. 打开浏览器,按 F12 键启动 chrome 调试工具。
  2. 设置断点。
  3. 找到 Scope 选项(Scope 作用域的意思)。
  4. 当我们重新刷新页面,会进入断点调试,Scope 里面会有两个参数(global 全局作用域、local 局部作用域)。
  5. Closure 参数代表闭包函数

闭包函数的作用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包的作用</title>
    </head>
    <body>

    </body>
    <script>
        // 有权访问另一个函数的局部变量的函数 便叫做局部变量
        function fn() {
            var num = 10;
            return function() {
                console.log(num) //10
            }

        }

        var f = fn(); //fn()
        f(); //调用return后面的函数
    </script>
</html>

image.png

闭包之输出li当前所造的索引号

核心思路:利用立刻执行函数便可

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之点击i输出索引号</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        // 第一种方法:点击i输出当前i的索引号
        var lis = document.querySelector('.nav').querySelectorAll('li');

        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i; //为每次循环的li设置索引号

            lis[i].addEventListener('click', function() {
                console.log(this.index)
            })
        }

        // 第二种方法:利用闭包输出当前的索引号

        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建四个立刻执行函数,因为立刻执行函数里面的原函数可以使用它的变量

            (function(i) {
                lis[i].addEventListener('click', function() {
                    console.log(i)
                })
            }(i))

        }
    </script>
</html>

image

闭包之定时器

要求:三秒之后自动显示li里面的内容

核心思路:利用for循环的每次循环生成的闭包函数即可


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之定时器</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {

            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML)
                }, 5000)
            }(i))
        }
    </script>


</html>


image

闭包之打车价格

打车起步价13(3公里内), 之后每多一公里增加 5块钱. 用户输入公里数就可以计算打车价格

如果有拥堵情况,总价格多收取10块钱拥堵费

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之打车价格</title>
    </head>
    <body>
    </body>
    <script>
        let car = (function() {
            let star = 13; //打车起步价
            let total = 0; //总价 局部变量
            return {
                price: function(n) {
                    if (n <= 3) {
                        total = star
                    } else {
                        total = star + (n - 3) * 5
                    }
                    return total //注意:不要忘记将值返回
                },
                // 拥堵之后的费用
                yd: function(flag) {
                    return flag ? total + 10 : total;
                }

            }

        })();
        console.log(car.price(5));
        console.log(car.yd(true)) //参数为true 则说明堵塞加10元


        console.log(car.price(6));
        console.log(car.yd(false))
    </script>
</html>
                                                    

image.png

测试题

<!DOCTYPE html>
<html lang="en">

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

<body>
<script>
    // 思考题 1:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            return function () {
                return this.name;
            };
        }
    };

    console.log(object.getNameFunc()())
    var f = object.getNameFunc();

    var f = function () {
        return this.name;
    }
    f();


    // 思考题 2:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            var that = this;
            return function () {
                return that.name;
            };
        }
    };
    console.log(object.getNameFunc()())
</script>
</body>

</html>

image.png

递归函数

如果一个函数在内部可以调用其本身,这个函数就是递归函数

简单理解:函数内部自己调用自己

递归函数的作用和循环效果一样,很容易发生‘栈溢出’,所以必须要加退出条件return

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    var num = 1;

    function fn() {
        console.log('hello word')
        if (num == 6) {
            return //递归函数必须要有退出条件
        }
        num++
        fn()
    }

    fn()
</script>
</html>

image.png

利用递归求1~n的阶乘

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>利用递归求1-n的阶乘</title>
</head>
<body>

</body>
<script>
    function fn(n) {
        if(n==1){
            return 1
        }
        return  n *fn(n-1)

    }

    console.log(fn(3));
    // 假入用户输入的是3
   /* return 3*fn(2)
    return 3*fn(2*fn(1))
    return 3*(2*1)
    return 3*2
    return 6 */
</script>
</html>

image.png

利用递归函数求斐波那契数列(兔子序列) 1、1、2、3、5、8、13、21...


<!DOCTYPE html>
<html lang="en">

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

<body>
<script>
    // 利用递归函数求斐波那契数列(兔子序列)  1、1、2、3、5、8、13、21...
    // 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
    // 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
    function fb(n) {
        if (n === 1 || n === 2) {
            return 1;
        }
        return fb(n - 1) + fb(n - 2);
    }
    console.log(fb(3));
    console.log(fb(6));

  
</script>
</body>

</html>

image.png

查看原文

尧子陌 发布了文章 · 9月16日

javascript高级(3)

创建函数的三种样式

1.function声明的普通函数(命名函数)
2.函数表达式(匿名函数)
3.new Function()

var fn =new Function('参数1','参数2',...,'函数体);

  • Function()里面的参数都是字符串格式
  • 第三种方式执行效率比较低,也不方便书写,因此较少使用
  • 所有的函数都是Fnction的实例对象
  • 函数也属于对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数的定义和调用方式</title>
</head>
<body>
<script>
    // 自定义方式
 function fn() {
    }
    // 函数表达式
 var fn = function() {
    }
    // 利用new Function('参数1','参数2','函数体')
 var f = new Function('a','b','return a+b')
    console.log(f(1,2));
    console.dir(f);
    //用来判断f是否是一个对象
 console.log(f instanceof Object)
</script>
</body>
</html>

image.png

不同函数的调用方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>按钮</button>
</body>
<script>
    // 函数的调用方式
 // 1.普通函数的调用
 function fn() {
        console.log('hello word')
    }
    fn()
    // 2.对象类的函数调用
 var obj = {
        say: function () {
            return 'hello word'
 }
    }
    console.log(obj.say())
    // 3.构造函数的调用
 function Star(name, age) {
        this.name = name;
        this.age = age;
    }
    var star1 = new Star('尧子陌', '18');
    console.log(star1.name)
    //4.事件函数的调用
 var bth = document.querySelector('button');
    bth.addEventListener('click', function () {
        console.log('事件函数')
    })
    // 5.定时器函数
 setInterval(function () {
        console.log('定时器函数')
    }, 5000)
</script>
</html>

image

自执行函数

顾名思义:自己调用的函数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自执行函数</title>
</head>
<body>
<script>
    (function () {
        alert('hello word')
    })()
</script>
</body>
</html>

image

this的指向问题

函数内部的this指向,当我们调用的时候才确定

注意:自执行的函数中this指向的是window
image.png

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>函数的this指向</title>
    </head>
    <body>
        <button>按钮</button>
    </body>
    <script>
        // 函数的调用方式

        // 1.普通函数的调用
        function fn() {
            console.log(this) //windows

        }

        fn()
        // 2.对象类的函数调用
        var obj = {
            say: function() {
                console.log(this) //指向o这个对象
            }
        }
        obj.say()

        // 3.构造函数的调用
        function Star(name, age) {
            console.log(this) //构造函数中的this指向的是它的实例化 star
            this.name = name;
            this.age = age;

        }

        var star1 = new Star('尧子陌', '18');
        //4.事件函数的调用
        var bth = document.querySelector('button');
        bth.addEventListener('click', function() {
            console.log(this) //事件函数中的this 指向的是它的调用者bth按钮
        })

        // 5.定时器函数
        setInterval(function() {
            console.log(this) //定时器中的this 指向的是windows
        }, 5000)
    </script>
</html>

image.png

call()方法

call() 方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。

fun.call(thisArg, arg1, arg2, ...)

  • thisArg:在 fun 函数运行时指定的 this 值
  • arg1,arg2:传递的其他参数
  • 返回值就是函数的返回值,因为它就是调用函数
  • 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承


<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>call()</title>
    </head>

    <body>

    </body>
    <script>
        // 改变函数内部的this指向之call()方法
        var o = {
            name: "andy"
        };

        function fn(a, b) {
            console.log(this); //o
            console.log(a + b); //3
        }

        fn.call(o, 1, 2) //call方法不仅可以改变函数内部的this指向,还可以传递参数


        //call()方法主要是为了实现继承


        function Father(name, age, sex) {
            console.log(this)
            this.name = name;
            this.age = age;
            this.sex = sex;

        }

        function Son(name, age, sex) {
            Father.call(this, name, age, sex)
        }

        var son = new Son('刘德华', '18', '男');
        console.log(son)
    </script>

</html>

 

image.png

### apply()方法

apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。

fun.apply(thisArg, [argsArray])

  • thisArg:在fun函数运行时指定的 this 值
  • argsArray:传递的值,必须包含在数组里面
  • 返回值就是函数的返回值,因为它就是调用函数
  • 因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>改变函数内部的this指向之apply()</title>
</head>

<body>

</body>
<script>
    var o = {
        name: 'andy'

    }

    function fn(arr) {
        console.log(this); //此时的this指向的是0;
        console.log(arr)

    }

    fn.apply(o, ['pink']); //注意:第二个参数必须为数组

    // 可以用数组方法实现求数组的最大值
    var arr2 = [1, 66, 22, 55, 108];
    var max = Math.max.apply(Math, arr2);
    var min = Math.min.apply(Math, arr2);
    console.log(max, min)
</script>

</html>

image.png

bind()

bind() 方法不会调用函数。但是能改变函数内部this 指向

fun.bind(thisArg, arg1, arg2, ...)

  • thisArg:在 fun 函数运行时指定的 this 值
  • arg1,arg2:传递的其他参数
  • 返回由指定的 this 值和初始化参数改造的原函数拷贝
  • 因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind()
  
  <!DOCTYPE html>
  <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>改变函数的内部的this指向之bind()方法</title>

    <body>
        <button>按钮</button>
        <button>按钮</button>
        <button>按钮</button>
    </body>
    <script>
        // bind()方法是绑定 捆绑的意思
        var o = {
            name: "andy"
        }

        function fn(a, b) {
            console.log(this)
            console.log(a + b)
        }

        // 注意:bind()方法会改变函数内部的this,但不会调用原来的函数
        var f = fn.bind(o, 1, 2);
        f()

        //案例:当我们点击按钮之后,就禁用这个按钮,三秒之后再次开启这个按钮
        var bths = document.querySelectorAll('button');
        for (var i = 0; i < bths.length; i++) {
            bths[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false
                    // 这里的this指的是bth这个按钮
                }.bind(this), 2000)
            }
        }
    </script>
</html>

  

image

call() apply() bind()之间的区别

区别点:

  1. call 和 apply 会调用函数, 并且改变函数内部this指向.
  2. call 和 apply 传递的参数不一样, call 传递参数 aru1, aru2..形式 apply 必须数组形式[arg]
  3. bind 不会调用函数, 可以改变函数内部this指向.

主要应用场景:

  1. call 经常做继承.
  2. apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
  3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.

严格模式

严格模式的出现,是为了限制非标准严格模式下不标准的语法,并且为ES6做好铺垫
严格模式对正常的 JavaScript 语义做了一些更改:
  1. 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
  2. 消除代码运行的一些不安全之处,保证代码运行的安全。
  3. 提高编译器效率,增加运行速度。
  4. 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比

如一些保留字如:class, enum, export, extends, import, super 不能做变量名

开启严格模式

'use strict' 在script的脚本内放入或在函数内部放入,便等同于开启严格模式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
      // 为脚本开启严格模式
        'use strict'
  </script>
  
  <script type="text/javascript">
        function fn(){
            // 为函数开启严格模式
            'use strict'
        }
  </script>
</body>
</html>


严格模式的变化

  • 严格模式下变量必须先声明才能使用
  • 严格模式下普通函数中的this指向undefined
  • 严格模式下构造函数不加new调用,this指的是undefined
  • 严格模式下定时器中的this指向window
<!DOCTYPE html>
<html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <meta http-equiv="X-UA-Compatible" content="ie=edge">
       <title>严格模式的变化</title>
   </head>
   <body>
       <script type="text/javascript">
           'use strict'
           // 1.变量必须先声明再使用
           var num = 10;
           console.log(10);
           // delete  num; 严格模式下禁用删除变量

           // 2.严格模式下的this指向undefined
           function fn() {
               console.log(this) //严格模式下this指的是undefined
           }
           fn()
           // 3.严格模式下构造函数不加new调用,this指的是undefined
           function Star() {
               console.log(this)
           }
           Star()

           //4.严格模式下定时器的this指向window
           setTimeout(function() {
               console.log(this)
           }, 2000)
       </script>
   </body>
</html>


image.png

高阶函数

高阶函数是对其它函数进行操作的函数,它接受函数作为参数或者将函数作为返回值输出


<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
   </head>
   <body>

   </body>
   <script>
       // 将函数作为参数
       function fn(callback) {
           callback && callback()
       }
       fn(function() {
           alert('hello word')
       })


       //将函数作为返回值输出
       function fn2() {
           return function() {}
       }
       console.log(fn2())
   </script>
</html>

image
此时的fn()及fn2便是高价函数

函数也是一种数据类型,可作为参数传递给另外一个函数作为参数使用,最典型的便是回调函数

 
<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>高阶函数</title>
       <style>
           * {
               margin: 0;
               padding: 0;
           }
           .box {
               position: absolute;
               top:0;
               left: 0;
               width: 200px;
               height: 200px;
               background-color: blueviolet
           }
       </style>
   </head>
   <script data-original="jquery.min.js"></script>
   <body>
       <div class="box"></div>
       
   </body>
   <script>
       $('.box').animate({
           left:200,
           top:200
       },function(){
           $(this).css('background','red')
       })
   </script>
</html>

image

闭包

指有权访问另外一个函数作用域里面的变量的函数

作用:延伸变量的作用范围

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>闭包</title>
    </head>
    <body>
        <div></div>
    </body>
    <script>
        // 所谓的闭包 简单理解:就是有权访问另一个函数的局部变量
        function fn() {
            let num = 10;

            function fun() {
                console.log(num) //10
            }

            fun()
        }

        fn()
    </script>
</html>

image.png

image.png

chrome中调试闭包

  1. 打开浏览器,按 F12 键启动 chrome 调试工具。
  2. 设置断点。
  3. 找到 Scope 选项(Scope 作用域的意思)。
  4. 当我们重新刷新页面,会进入断点调试,Scope 里面会有两个参数(global 全局作用域、local 局部作用域)。
  5. Closure 参数代表闭包函数

闭包函数的作用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包的作用</title>
    </head>
    <body>

    </body>
    <script>
        // 有权访问另一个函数的局部变量的函数 便叫做局部变量
        function fn() {
            var num = 10;
            return function() {
                console.log(num) //10
            }

        }

        var f = fn(); //fn()
        f(); //调用return后面的函数
    </script>
</html>

image.png

闭包之输出li当前所造的索引号

核心思路:利用立刻执行函数便可

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之点击i输出索引号</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        // 第一种方法:点击i输出当前i的索引号
        var lis = document.querySelector('.nav').querySelectorAll('li');

        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i; //为每次循环的li设置索引号

            lis[i].addEventListener('click', function() {
                console.log(this.index)
            })
        }

        // 第二种方法:利用闭包输出当前的索引号

        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建四个立刻执行函数,因为立刻执行函数里面的原函数可以使用它的变量

            (function(i) {
                lis[i].addEventListener('click', function() {
                    console.log(i)
                })
            }(i))

        }
    </script>
</html>

image

闭包之定时器

要求:三秒之后自动显示li里面的内容

核心思路:利用for循环的每次循环生成的闭包函数即可


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之定时器</title>
    </head>
    <body>
        <ul class="nav">
            <li>one</li>
            <li>two</li>
            <li>three</li>
            <li>four</li>
        </ul>
    </body>
    <script>
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {

            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML)
                }, 5000)
            }(i))
        }
    </script>


</html>


image

闭包之打车价格

打车起步价13(3公里内), 之后每多一公里增加 5块钱. 用户输入公里数就可以计算打车价格

如果有拥堵情况,总价格多收取10块钱拥堵费

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包之打车价格</title>
    </head>
    <body>
    </body>
    <script>
        let car = (function() {
            let star = 13; //打车起步价
            let total = 0; //总价 局部变量
            return {
                price: function(n) {
                    if (n <= 3) {
                        total = star
                    } else {
                        total = star + (n - 3) * 5
                    }
                    return total //注意:不要忘记将值返回
                },
                // 拥堵之后的费用
                yd: function(flag) {
                    return flag ? total + 10 : total;
                }

            }

        })();
        console.log(car.price(5));
        console.log(car.yd(true)) //参数为true 则说明堵塞加10元


        console.log(car.price(6));
        console.log(car.yd(false))
    </script>
</html>
                                                    

image.png

测试题

<!DOCTYPE html>
<html lang="en">

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

<body>
<script>
    // 思考题 1:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            return function () {
                return this.name;
            };
        }
    };

    console.log(object.getNameFunc()())
    var f = object.getNameFunc();

    var f = function () {
        return this.name;
    }
    f();


    // 思考题 2:

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            var that = this;
            return function () {
                return that.name;
            };
        }
    };
    console.log(object.getNameFunc()())
</script>
</body>

</html>

image.png

递归函数

如果一个函数在内部可以调用其本身,这个函数就是递归函数

简单理解:函数内部自己调用自己

递归函数的作用和循环效果一样,很容易发生‘栈溢出’,所以必须要加退出条件return

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    var num = 1;

    function fn() {
        console.log('hello word')
        if (num == 6) {
            return //递归函数必须要有退出条件
        }
        num++
        fn()
    }

    fn()
</script>
</html>

image.png

利用递归求1~n的阶乘

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>利用递归求1-n的阶乘</title>
</head>
<body>

</body>
<script>
    function fn(n) {
        if(n==1){
            return 1
        }
        return  n *fn(n-1)

    }

    console.log(fn(3));
    // 假入用户输入的是3
   /* return 3*fn(2)
    return 3*fn(2*fn(1))
    return 3*(2*1)
    return 3*2
    return 6 */
</script>
</html>

image.png

利用递归函数求斐波那契数列(兔子序列) 1、1、2、3、5、8、13、21...


<!DOCTYPE html>
<html lang="en">

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

<body>
<script>
    // 利用递归函数求斐波那契数列(兔子序列)  1、1、2、3、5、8、13、21...
    // 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
    // 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
    function fb(n) {
        if (n === 1 || n === 2) {
            return 1;
        }
        return fb(n - 1) + fb(n - 2);
    }
    console.log(fb(3));
    console.log(fb(6));

  
</script>
</body>

</html>

image.png

查看原文

赞 2 收藏 2 评论 0

尧子陌 收藏了文章 · 9月16日

javscript高级(2)

创建对象的三种方式

  • 通过new关键字创建对象
  • 通过字面量创建对象
  • 通过构造函数创建对象
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>

    <body>

    </body>
    <script>
        // 利用new关键字创建对象
        var obj1 = new Object();
        // 利用字面量创建对象
        var obj2 = {};
        // 利用构造函数创建对象
        function People(name, age) {
            this.name = name;
            this.age = age;
            this.say = function() {
                console.log('hello word')
            }

        }

        // 利用构造函数创建实例化对象
        var People1 = new People('尧子陌', "24");
        console.log(People1); //打印这个对象
        console.log(People1.name);
        People1.say()
    </script>

</html>

构造函数

    构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值。总之把对象中的公共属性与方法抽取出来,然后封装袋这个函数里面
    

注意事项
1.构造函数用于创建某一类对象,其首字母要大写。
2.构造函数要与new在一起使用才有意义。

new关键字

1.在内存中创建一个新对象
2.让this指向这个新对象
3.执行构造函数的代码,给这个新对象添加属性与方法
4.返回这个新对象(构造函数不需要retern)

静态成员和实例成员

  • 静态成员:在构造函数本体上添加的成员被称为静态成员,只能由构造函数调用
  • 实例成员:在构造函数内部创建的对象成员被称为实例成员,只能由实例化的对象来访问。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>静态成员及实例成员</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

            this.say = function() {
                return 'hello 尧子陌'
            }

        }

        var People1 = new People('尧子陌', "23");
        // 实例化成员只能通过实例化对象调用
        console.log(People1.say())

        // 在构造函数本体上添加的成员属于静态成员,只能构造函数调用
        People.sex = '男';
        console.log(People.sex)
    </script>
</html>

image.png

原型

构造函数很好用 但很浪费内存
javascript规定,每一个构造函数都有一个prototype属性,指向一个对象,我们可以把这些不变的方法定义在prototype上,这样所有的实例化对象都能共享这些方法
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
            
        People.prototype.say =function(){
            return "hello woord"
        }
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        var People2 = new People('惊鸿一面','28');
        console.log(People2.say());
        
        console.log(People1.say === People2.say);
    </script>
</html>

image.png

对象的原型 proto

每个对象向都会有一个_proto_属性,指向构造函数中的prototype对象,且与之全等的关系

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }

        People.prototype.say = function() {
            return "hello woord"
        }
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        console.log(People1.__proto__);//指向构造函数的原型
        console.log(People1.__proto__===People.prototype) //true
    </script>
</html>

image.png

constructor构造函数

constructor:指向的是引用的构造函数,可以让原型对象重新指向构造函数。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
        
        People.prototype = {
            // 将原型对象采用对象赋值的情况下,constructor的指向会变,手动将constructor的指向改回来
            constructor:People,
            say:function(){
                return "hello"
            },
            eat:function(){
                return "banner"
            }
            
        }
        
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        console.log(People1.__proto__);//指向构造函数的原型
        console.log(People1.__proto__===People.prototype) //true
        console.log(People.prototype.constructor);
        console.log(People1.__proto__.constructor)
    </script>
</html>

image.png

原型对象 实例对象 构造函数之间的联系

image.png

原型链

简单来讲。任何对象都会有_proto_属性,且在js中万物皆对象,由_proto_属性连起来的链条便叫做原型链,且最终值为null
构造函数的原型的_proto_属性指向Object.prototype
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
        
        People.prototype = {
            // 将原型对象采用对象赋值的情况下,constructor的指向会变,手动将constructor的指向改回来
            constructor:People,
            say:function(){
                return "hello"
            },
            eat:function(){
                return "banner"
            }
            
        }
        
        var People1 = new People('尧子陌', "23");
        // 构造函数的原型的_proto_属性指向Object.prototype
        console.log(People.prototype.__proto__=== Object.prototype) //true
        console.log(Object.prototype.__proto__) //null
        
    </script>
</html>

image.png

js成员的查找机制

  • 当我们访问一个对象的属性与方法的时候,首先看这个对象自身有没有属性与方法。
  • 如果没有就开始通过原型对象中的_proto_属性继续查找(Object.prototype)
  • 如果还没有,就以此类推继续向上查找,直至值为null的时候

简单而言,就是沿着一条线查找

原型对象中的this指向问题

  • 构造函数中的this指的是实例化的对象。
  • 原型中的this指的是实例化对象
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型对象中的this指向</title>
    </head>
    <body>
        <script>
            var that

            function Star(name, age) {
                this.name = name;
                this.age = age;
            }
            Star.prototype.sing = function() {

                console.log('hello')
                that = this;
            }
            var star1 = new Star('尧子陌', '22');
            star1.sing()
            console.log(that === star1)
        </script>
    </body>
</html>

image.png

扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法。

注意:内置的数组和字符串等内置对象不能给原型对象覆盖;

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>扩展内置自定义的方法</title>
    </head>
    <body>

    </body>
    <script>
        // 采用原型对象 对内置对象扩展县方法
        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i]


            }
            return sum;
        }
        var arr = [1, 2, 3];
        // 调用新方法
        console.log(arr.sum())
        console.log(Array.prototype)
        
        var arr1 = new Array(11,22,33);
        console.log(arr1.sum())
    </script>
</html>

image.png

call()方法

call()方法可以调用函数,并且可以修改this指向,还可以进行传参。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>call()方法</title>
    </head>
    <body>
        <script>
            function fn(x,y) {
                console.log('手磨咖啡')
                console.log(this) 
                console.log(x+y)
            }
            
            var o ={
                name:"尧子陌"
            }
            // 不仅改变this指向,而且调用函数 甚至能进行传参
            
            fn.call(o,1,2)
        </script>
    </body>
</html>

image.png

继承

ES6之前并没有跟我们提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承

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

核心原理:通过call()把父类型的this指向子类型的this,可以实现子类型继承父类型的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>借用父构造函数函数继承属性</title>
</head>
<body>
<script>
    // 父类构造函数
 function Father(name,age){
        console.log(this) //此时this指向子类的实例对象
 this.name =name;
        this.age = age;
    }
    //子类构造函数
 function Son(name,age,score) {
        // 借助call()方法让父类中的this指向子类的this
 Father.call(this,name,age);
        this.score = score;
    }
    var son = new Son('尧子陌',18);
    console.log(son.name);//尧子陌
</script>
</body>
</html>

image.png

借用原型对象继承父类的方法

思路如下

  • 子类的prototype原型 = new 父类
  • 因为父类的实例化对象会另外开辟空间,不会影响父类的原型对象。
  • 将子类的constructor重新指向子类的构造函数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>借用原型对象继承父类的方法</title>
</head>
<body>
<script>
    // 父构造函数
 function Father(name,age) {
        this.name =name;
        this.age =age;
    }
    Father.prototype.money = function () {
        console.log('10000')
    }
    // 子构造函数
 function Son(name,age,score) {
        Father.call(this,name,age);
        this.score = score;
    }
    //将子类的constructor构造函数重新指向原来的构造函数
 Son.prototype.constructor = Son;
    //子类的原型对象等于父类的实例化对象
 Son.prototype = new Father()
    var father = new Father('惊鸿一面','24');
    father.money()
    var son = new Son('尧子陌','28');
    console.log(son.name)
    son.money()
</script>
</body>
</html>

image.png

ES6新增数组方法

迭代(遍历)方法:forEach(),map(),filter(),some(),every()

forEach()

array.forEach(function(currentValue,index,arr)

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>forEach()方法</title>
</head>
<body>
<script>
    // 创建一个数组
 var arr = [1, 2, 3]
    // 求和的变量
 var sum = 0;
    arr.forEach(function (value, index, array) {
        console.log(value);
        console.log(index);
        console.log(array)
        sum += value;
    })
    console.log(sum)
</script>
</body>
</html>

image.png

filter()

array.filter(funcction(curentValue,index,arr))
注意:主要用来筛选数组,返回的是新数组

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>filter()</title>
</head>
<body>
<script>
    var arr = [20, 50, 80, 100, 150, 500, 600];
    var newArr = arr.filter(function (value, index, array) {
        //筛选大于100的数组元素,返回一个新数组
     return value > 100;
    })
    console.log(newArr)
</script>
</body>
</html>

image.png

some()

array.some(funcction(curentValue,index,arr))
注意:主要用来筛选数组,返回的是布尔值,当查找到第一个满足条件的数组元素,则停止查找

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>some()方法</title>
</head>
<body>
<script>
    var arr = ['pink', 'black', 'red', 'pink', 'pink'];
    var flag = arr.some(function (value, index, array) {
        //当查找到第一个满足的数组元素后,便停止查找,返回值是一个布尔值
         return value = 'pink'
     })
    console.log(flag)
</script>
</body>
</html>

image.png

查询商品案例

核心思路

  • 把数据渲染到页面中(forEach)
  • 根据价格渲染数据(filter)
  • 根据商品名称渲染数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        table {
            width: 400px;
            border: 1px solid #000;
            border-collapse: collapse;
            margin: 0 auto;
        }
        
        td,
        th {
            border: 1px solid #000;
            text-align: center;
        }
        
        input {
            width: 50px;
        }
        
        .search {
            width: 600px;
            margin: 20px auto;
        }
    </style>
</head>

<body>
    <div class="search">
        按照价格查询: <input type="text" class="start"> - <input type="text" class="end"> <button class="search-price">搜索</button> 按照商品名称查询: <input type="text" class="product"> <button class="search-pro">查询</button>
    </div>
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>产品名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>


        </tbody>
    </table>
    <script>
        // 利用新增数组方法操作数据
        var data = [{
            id: 1,
            pname: '小米',
            price: 3999
        }, {
            id: 2,
            pname: 'oppo',
            price: 999
        }, {
            id: 3,
            pname: '荣耀',
            price: 1299
        }, {
            id: 4,
            pname: '华为',
            price: 1999
        }, ];
        // 1. 获取相应的元素
        var tbody = document.querySelector('tbody');
        var search_price = document.querySelector('.search-price');
        var start = document.querySelector('.start');
        var end = document.querySelector('.end');
        var product = document.querySelector('.product');
        var search_pro = document.querySelector('.search-pro');
        setDate(data);
        // 2. 把数据渲染到页面中
        function setDate(mydata) {
            // 先清空原来tbody 里面的数据
            tbody.innerHTML = '';
            mydata.forEach(function(value) {
                // console.log(value);
                var tr = document.createElement('tr');
                tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
                tbody.appendChild(tr);
            });
        }

        // 3. 根据价格查询商品
        // 当我们点击了按钮,就可以根据我们的商品价格去筛选数组里面的对象
        search_price.addEventListener('click', function() {
            // alert(11);
            var newDate = data.filter(function(value) {
                return value.price >= start.value && value.price <= end.value;
            });
            console.log(newDate);
            // 把筛选完之后的对象渲染到页面中
            setDate(newDate);
        });
        // 4. 根据商品名称查找商品
        // 如果查询数组中唯一的元素, 用some方法更合适,因为它找到这个元素,就不在进行循环,效率更高]
        search_pro.addEventListener('click', function() {
            var arr = [];
            data.some(function(value) {
                if (value.pname === product.value) {
                    // console.log(value);
                    arr.push(value);
                    return true; // return 后面必须写true  
                }
            });
            // 把拿到的数据渲染到页面中
            setDate(arr);
        })
    </script>
</body>

</html>

image

字符串方法

trim()方法可以去除字符串两侧的空白
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>
<body>
<input type="text">
<button>点击</button>
<div></div>
<script type="text/javascript">
    var input = document.querySelector('input');
    var bth = document.querySelector('button');
    var div = document.querySelector('div')
    bth.onclick = function () {
        var str = input.value.trim();
        if (str === '') {
            alert('内容为空')
        } else {
            div.innerHTML = str;
        }
    }
    var str2 = '   andy  ';
    console.log(str2.trim().length)
</script>
</body>
</html>

image

对象方法

Object.keys(obj)

Object.keys()方法返回一个所有元素为字符串的数组
Object.keys()obj
  • 效果类似for...in
  • 输出对象中值大于2的key数组
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Object.keys()</title>
</head>
<body>
<script>
    var obj ={
        id:1,
        name:"尧子陌",
        sex:"男"
 }
    console.log(  Object.keys(obj))
</script>
</body>
</html>

image.png

Object.defineProperty()

定义新属性或修改为原来的属性

Object.defineProperty(obj,prop,descriptor)

  • obj:必需 目标对象
  • prop:必需:定义或修改属性的名字
  • descriptor:必需,目标属性所必需有的属性

Object.defineProperty()第三个descriptor说明

  • value:需要修改的值
  • writable:值是否可以被重写
  • enumerable:目标属性是否可以被枚举
  • configurable:目标属性是否可以被删除或者再次修改特性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var obj = {
        name: "尧子陌",
        sex: "男",
        age: 18
 }
    Object.defineProperty(obj, 'name', {
        //不允许修改属性
 writable: false
 })
    obj.name = '惊鸿'
 console.log(obj);
    // 定义新属性或修改属性
 Object.defineProperty(obj, 'say', {
        value: 'hello',
        //目标属性可以被枚举
 enumerable: true,
        //目表属性不允许删除或修改属性
 configurable: false
 })
    console.log(Object.keys(obj))
</script>
</body>
</html>

image.png

查看原文

尧子陌 发布了文章 · 9月16日

javscript高级(2)

创建对象的三种方式

  • 通过new关键字创建对象
  • 通过字面量创建对象
  • 通过构造函数创建对象
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>

    <body>

    </body>
    <script>
        // 利用new关键字创建对象
        var obj1 = new Object();
        // 利用字面量创建对象
        var obj2 = {};
        // 利用构造函数创建对象
        function People(name, age) {
            this.name = name;
            this.age = age;
            this.say = function() {
                console.log('hello word')
            }

        }

        // 利用构造函数创建实例化对象
        var People1 = new People('尧子陌', "24");
        console.log(People1); //打印这个对象
        console.log(People1.name);
        People1.say()
    </script>

</html>

构造函数

    构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值。总之把对象中的公共属性与方法抽取出来,然后封装袋这个函数里面
    

注意事项
1.构造函数用于创建某一类对象,其首字母要大写。
2.构造函数要与new在一起使用才有意义。

new关键字

1.在内存中创建一个新对象
2.让this指向这个新对象
3.执行构造函数的代码,给这个新对象添加属性与方法
4.返回这个新对象(构造函数不需要retern)

静态成员和实例成员

  • 静态成员:在构造函数本体上添加的成员被称为静态成员,只能由构造函数调用
  • 实例成员:在构造函数内部创建的对象成员被称为实例成员,只能由实例化的对象来访问。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>静态成员及实例成员</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

            this.say = function() {
                return 'hello 尧子陌'
            }

        }

        var People1 = new People('尧子陌', "23");
        // 实例化成员只能通过实例化对象调用
        console.log(People1.say())

        // 在构造函数本体上添加的成员属于静态成员,只能构造函数调用
        People.sex = '男';
        console.log(People.sex)
    </script>
</html>

image.png

原型

构造函数很好用 但很浪费内存
javascript规定,每一个构造函数都有一个prototype属性,指向一个对象,我们可以把这些不变的方法定义在prototype上,这样所有的实例化对象都能共享这些方法
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
            
        People.prototype.say =function(){
            return "hello woord"
        }
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        var People2 = new People('惊鸿一面','28');
        console.log(People2.say());
        
        console.log(People1.say === People2.say);
    </script>
</html>

image.png

对象的原型 proto

每个对象向都会有一个_proto_属性,指向构造函数中的prototype对象,且与之全等的关系

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }

        People.prototype.say = function() {
            return "hello woord"
        }
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        console.log(People1.__proto__);//指向构造函数的原型
        console.log(People1.__proto__===People.prototype) //true
    </script>
</html>

image.png

constructor构造函数

constructor:指向的是引用的构造函数,可以让原型对象重新指向构造函数。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
        
        People.prototype = {
            // 将原型对象采用对象赋值的情况下,constructor的指向会变,手动将constructor的指向改回来
            constructor:People,
            say:function(){
                return "hello"
            },
            eat:function(){
                return "banner"
            }
            
        }
        
        var People1 = new People('尧子陌', "23");
        
        console.log(People1.say())

        console.log(People1.__proto__);//指向构造函数的原型
        console.log(People1.__proto__===People.prototype) //true
        console.log(People.prototype.constructor);
        console.log(People1.__proto__.constructor)
    </script>
</html>

image.png

原型对象 实例对象 构造函数之间的联系

image.png

原型链

简单来讲。任何对象都会有_proto_属性,且在js中万物皆对象,由_proto_属性连起来的链条便叫做原型链,且最终值为null
构造函数的原型的_proto_属性指向Object.prototype
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型</title>
    </head>
    <body>

    </body>
    <script>
        function People(name, age) {
            // 在构造函数内部创建的成员属于实例化成员,只有实例化对象才能调用
            this.name = name;
            this.age = age;

        }
        
        People.prototype = {
            // 将原型对象采用对象赋值的情况下,constructor的指向会变,手动将constructor的指向改回来
            constructor:People,
            say:function(){
                return "hello"
            },
            eat:function(){
                return "banner"
            }
            
        }
        
        var People1 = new People('尧子陌', "23");
        // 构造函数的原型的_proto_属性指向Object.prototype
        console.log(People.prototype.__proto__=== Object.prototype) //true
        console.log(Object.prototype.__proto__) //null
        
    </script>
</html>

image.png

js成员的查找机制

  • 当我们访问一个对象的属性与方法的时候,首先看这个对象自身有没有属性与方法。
  • 如果没有就开始通过原型对象中的_proto_属性继续查找(Object.prototype)
  • 如果还没有,就以此类推继续向上查找,直至值为null的时候

简单而言,就是沿着一条线查找

原型对象中的this指向问题

  • 构造函数中的this指的是实例化的对象。
  • 原型中的this指的是实例化对象
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>原型对象中的this指向</title>
    </head>
    <body>
        <script>
            var that

            function Star(name, age) {
                this.name = name;
                this.age = age;
            }
            Star.prototype.sing = function() {

                console.log('hello')
                that = this;
            }
            var star1 = new Star('尧子陌', '22');
            star1.sing()
            console.log(that === star1)
        </script>
    </body>
</html>

image.png

扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法。

注意:内置的数组和字符串等内置对象不能给原型对象覆盖;

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>扩展内置自定义的方法</title>
    </head>
    <body>

    </body>
    <script>
        // 采用原型对象 对内置对象扩展县方法
        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i]


            }
            return sum;
        }
        var arr = [1, 2, 3];
        // 调用新方法
        console.log(arr.sum())
        console.log(Array.prototype)
        
        var arr1 = new Array(11,22,33);
        console.log(arr1.sum())
    </script>
</html>

image.png

call()方法

call()方法可以调用函数,并且可以修改this指向,还可以进行传参。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>call()方法</title>
    </head>
    <body>
        <script>
            function fn(x,y) {
                console.log('手磨咖啡')
                console.log(this) 
                console.log(x+y)
            }
            
            var o ={
                name:"尧子陌"
            }
            // 不仅改变this指向,而且调用函数 甚至能进行传参
            
            fn.call(o,1,2)
        </script>
    </body>
</html>

image.png

继承

ES6之前并没有跟我们提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承

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

核心原理:通过call()把父类型的this指向子类型的this,可以实现子类型继承父类型的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>借用父构造函数函数继承属性</title>
</head>
<body>
<script>
    // 父类构造函数
 function Father(name,age){
        console.log(this) //此时this指向子类的实例对象
 this.name =name;
        this.age = age;
    }
    //子类构造函数
 function Son(name,age,score) {
        // 借助call()方法让父类中的this指向子类的this
 Father.call(this,name,age);
        this.score = score;
    }
    var son = new Son('尧子陌',18);
    console.log(son.name);//尧子陌
</script>
</body>
</html>

image.png

借用原型对象继承父类的方法

思路如下

  • 子类的prototype原型 = new 父类
  • 因为父类的实例化对象会另外开辟空间,不会影响父类的原型对象。
  • 将子类的constructor重新指向子类的构造函数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>借用原型对象继承父类的方法</title>
</head>
<body>
<script>
    // 父构造函数
 function Father(name,age) {
        this.name =name;
        this.age =age;
    }
    Father.prototype.money = function () {
        console.log('10000')
    }
    // 子构造函数
 function Son(name,age,score) {
        Father.call(this,name,age);
        this.score = score;
    }
    //将子类的constructor构造函数重新指向原来的构造函数
 Son.prototype.constructor = Son;
    //子类的原型对象等于父类的实例化对象
 Son.prototype = new Father()
    var father = new Father('惊鸿一面','24');
    father.money()
    var son = new Son('尧子陌','28');
    console.log(son.name)
    son.money()
</script>
</body>
</html>

image.png

ES6新增数组方法

迭代(遍历)方法:forEach(),map(),filter(),some(),every()

forEach()

array.forEach(function(currentValue,index,arr)

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>forEach()方法</title>
</head>
<body>
<script>
    // 创建一个数组
 var arr = [1, 2, 3]
    // 求和的变量
 var sum = 0;
    arr.forEach(function (value, index, array) {
        console.log(value);
        console.log(index);
        console.log(array)
        sum += value;
    })
    console.log(sum)
</script>
</body>
</html>

image.png

filter()

array.filter(funcction(curentValue,index,arr))
注意:主要用来筛选数组,返回的是新数组

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>filter()</title>
</head>
<body>
<script>
    var arr = [20, 50, 80, 100, 150, 500, 600];
    var newArr = arr.filter(function (value, index, array) {
        //筛选大于100的数组元素,返回一个新数组
     return value > 100;
    })
    console.log(newArr)
</script>
</body>
</html>

image.png

some()

array.some(funcction(curentValue,index,arr))
注意:主要用来筛选数组,返回的是布尔值,当查找到第一个满足条件的数组元素,则停止查找

  • currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象的本身
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>some()方法</title>
</head>
<body>
<script>
    var arr = ['pink', 'black', 'red', 'pink', 'pink'];
    var flag = arr.some(function (value, index, array) {
        //当查找到第一个满足的数组元素后,便停止查找,返回值是一个布尔值
         return value = 'pink'
     })
    console.log(flag)
</script>
</body>
</html>

image.png

查询商品案例

核心思路

  • 把数据渲染到页面中(forEach)
  • 根据价格渲染数据(filter)
  • 根据商品名称渲染数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        table {
            width: 400px;
            border: 1px solid #000;
            border-collapse: collapse;
            margin: 0 auto;
        }
        
        td,
        th {
            border: 1px solid #000;
            text-align: center;
        }
        
        input {
            width: 50px;
        }
        
        .search {
            width: 600px;
            margin: 20px auto;
        }
    </style>
</head>

<body>
    <div class="search">
        按照价格查询: <input type="text" class="start"> - <input type="text" class="end"> <button class="search-price">搜索</button> 按照商品名称查询: <input type="text" class="product"> <button class="search-pro">查询</button>
    </div>
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>产品名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>


        </tbody>
    </table>
    <script>
        // 利用新增数组方法操作数据
        var data = [{
            id: 1,
            pname: '小米',
            price: 3999
        }, {
            id: 2,
            pname: 'oppo',
            price: 999
        }, {
            id: 3,
            pname: '荣耀',
            price: 1299
        }, {
            id: 4,
            pname: '华为',
            price: 1999
        }, ];
        // 1. 获取相应的元素
        var tbody = document.querySelector('tbody');
        var search_price = document.querySelector('.search-price');
        var start = document.querySelector('.start');
        var end = document.querySelector('.end');
        var product = document.querySelector('.product');
        var search_pro = document.querySelector('.search-pro');
        setDate(data);
        // 2. 把数据渲染到页面中
        function setDate(mydata) {
            // 先清空原来tbody 里面的数据
            tbody.innerHTML = '';
            mydata.forEach(function(value) {
                // console.log(value);
                var tr = document.createElement('tr');
                tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
                tbody.appendChild(tr);
            });
        }

        // 3. 根据价格查询商品
        // 当我们点击了按钮,就可以根据我们的商品价格去筛选数组里面的对象
        search_price.addEventListener('click', function() {
            // alert(11);
            var newDate = data.filter(function(value) {
                return value.price >= start.value && value.price <= end.value;
            });
            console.log(newDate);
            // 把筛选完之后的对象渲染到页面中
            setDate(newDate);
        });
        // 4. 根据商品名称查找商品
        // 如果查询数组中唯一的元素, 用some方法更合适,因为它找到这个元素,就不在进行循环,效率更高]
        search_pro.addEventListener('click', function() {
            var arr = [];
            data.some(function(value) {
                if (value.pname === product.value) {
                    // console.log(value);
                    arr.push(value);
                    return true; // return 后面必须写true  
                }
            });
            // 把拿到的数据渲染到页面中
            setDate(arr);
        })
    </script>
</body>

</html>

image

字符串方法

trim()方法可以去除字符串两侧的空白
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>
<body>
<input type="text">
<button>点击</button>
<div></div>
<script type="text/javascript">
    var input = document.querySelector('input');
    var bth = document.querySelector('button');
    var div = document.querySelector('div')
    bth.onclick = function () {
        var str = input.value.trim();
        if (str === '') {
            alert('内容为空')
        } else {
            div.innerHTML = str;
        }
    }
    var str2 = '   andy  ';
    console.log(str2.trim().length)
</script>
</body>
</html>

image

对象方法

Object.keys(obj)

Object.keys()方法返回一个所有元素为字符串的数组
Object.keys()obj
  • 效果类似for...in
  • 输出对象中值大于2的key数组
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Object.keys()</title>
</head>
<body>
<script>
    var obj ={
        id:1,
        name:"尧子陌",
        sex:"男"
 }
    console.log(  Object.keys(obj))
</script>
</body>
</html>

image.png

Object.defineProperty()

定义新属性或修改为原来的属性

Object.defineProperty(obj,prop,descriptor)

  • obj:必需 目标对象
  • prop:必需:定义或修改属性的名字
  • descriptor:必需,目标属性所必需有的属性

Object.defineProperty()第三个descriptor说明

  • value:需要修改的值
  • writable:值是否可以被重写
  • enumerable:目标属性是否可以被枚举
  • configurable:目标属性是否可以被删除或者再次修改特性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var obj = {
        name: "尧子陌",
        sex: "男",
        age: 18
 }
    Object.defineProperty(obj, 'name', {
        //不允许修改属性
 writable: false
 })
    obj.name = '惊鸿'
 console.log(obj);
    // 定义新属性或修改属性
 Object.defineProperty(obj, 'say', {
        value: 'hello',
        //目标属性可以被枚举
 enumerable: true,
        //目表属性不允许删除或修改属性
 configurable: false
 })
    console.log(Object.keys(obj))
</script>
</body>
</html>

image.png

查看原文

赞 1 收藏 1 评论 0

尧子陌 收藏了文章 · 9月14日

javascript高级(1)

面向过程及面向思想

面向过程

面向过程就是分析出问题所需要的步骤,然后用函数把这些步骤一个个的实现,使用的时候一个个依次调用就可以了。

面向思想

面向过程就是把事务分成一个个对象,由对象之间分工与合作。

image.png

面向思维的特点

面向过思维特点

  • 抽取对象中公共的属性与行为封装成一个类(模板)
  • 对类进行实例化,获取类的对象

对象是一组无序的相关属性与方法的集合,所有的事物都可以是一个对象。例如字符串 数字 布尔值等等。

  • 属性:对象的特征,在对象中用属性来表示(名词)
  • 方法:对象的行为,在对象中用方法来表示(动词)

在ES6的过程中,引进类的概念。类抽取对象公共的部分,类泛指一大类。

创建类与对象

注意事项

  • 实例化对象中必须要有new 只要有new关键字 类的构造函数constructor才会执行。
  • constructor()是类的构造函数,用于传递参数,返回实例化对象。
  • 通过class创建类 类名首字母大写,后面不用加小括号
  • 类里面的所有函数不需要加function,多个函数之间不需要加逗号。
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>创建类与对象</title>
    </head>
    <body>

    </body>
    <script>
        // 创建类
        class People {
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            say(sing) {
                console.log(sing)
            }
        }

        // 创建实例化对象
        let YaoZiMo = new People('尧子陌', "18");
        console.log(YaoZiMo.name);
        console.log(YaoZiMo.age);
        YaoZiMo.say('两只蝴蝶')
    </script>
</html>

image.png

类的继承

利用extends可让子类继承父类
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>类的继承</title>
    </head>
    <body>
    </body>
    <script>
        // 类的继承
        class Father {
            constructor() {

            }

            money() {
                console.log(100)
            }
        }

        // 继承父类中的方法与属性
        class Son extends Father {

        }

        // 创建子类的实例化对象
        var son = new Son();
        son.money()
    </script>
</html>

image.png

注意事项
1.继承中,如果实例化子类中输入一个方法,先看子类有没有这个方法,如果有就先执行子类的
2.继承中,如果子类里面没有这个方法,就去父类中查找(就近原则)
3.如果子类想使用父类中的方法,就要利用好super()调用父类的构造函数,super必须在this之前调用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>super关键字</title>
    </head>
    <body>
    </body>
    <script>
        // 父类
        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) //调用父类中的构造函数
            }
        };
        // 创建子类的实例化对象
        let son = new Son(1, 2);
        son.sum()
    </script>
</html>

image.png

调用普通函数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>super调用普通函数</title>
    </head>
    <body>

    </body>
    <script>
        // 父类
        class Father {
            say() {
                return 'hello word'
            }
        }

        // 子类
        class Son extends Father {
            say() {
                console.log(super.say())
            }
        }
        var son = new Son();
        son.say()
    </script>
</html>

image.png

子类继承父类的方法同时扩展自己的方法

注意:super()必须在子类构造函数中的this之前调用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>子类继承父类的方法 同时扩展子类的方法 </title>
    </head>
    <body>

    </body>
    <script>
        // 父类 有加法方法
        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()方法必须在子类的this之前进行调用
                super(x, y)
                this.x = x;
                this.y = y;
            }
            subduction() {
                console.log(this.x - this.y)
            }
        }

        // 对子类进行实例化 获取类的对象
        var son = new Son(5, 3);
        // 子类调用父类的方法
        son.sum()

        son.subduction()
    </script>
</html>

image.png

ES6中的类和对象的三个注意点。

1.在ES6中类没有变量提升,所以必须先定义类,才能通过实例化对象
2.类里面的公共属性与方法一定要加this
3.constructor里面的this指向实例化对象,方法里面的this指向这个方法的调用者

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title>使用类的注意事项</title>
    </head>

    <body>
        <button type="button" class="bth">点击</button>
    </body>
    <script>
        var that;
        var _that;
        class People {
            constructor(name, age) {
                that = this;
                console.log(this)
                this.name = name;
                this.age = age;
                this.bth = document.querySelector('button');
                this.bth.onclick = this.sing;
            }

            sing() {
                console.log(this) //里面的this指向bth按钮
                console.log(that.name) //that指是constructor中的this
            }
            dance() {
                _that = this;
                console.log(this) //此时的this指向实例化对象 因为实例化对象调用了dance这个函数

            }
        }

        // 创建类
        var people = new People('尧子陌');
        console.log(that === people)
        people.dance()
        console.log(_that === people)
    </script>

</html>

image.png

查看原文

尧子陌 发布了文章 · 9月14日

javascript高级(1)

面向过程及面向思想

面向过程

面向过程就是分析出问题所需要的步骤,然后用函数把这些步骤一个个的实现,使用的时候一个个依次调用就可以了。

面向思想

面向过程就是把事务分成一个个对象,由对象之间分工与合作。

image.png

面向思维的特点

面向过思维特点

  • 抽取对象中公共的属性与行为封装成一个类(模板)
  • 对类进行实例化,获取类的对象

对象是一组无序的相关属性与方法的集合,所有的事物都可以是一个对象。例如字符串 数字 布尔值等等。

  • 属性:对象的特征,在对象中用属性来表示(名词)
  • 方法:对象的行为,在对象中用方法来表示(动词)

在ES6的过程中,引进类的概念。类抽取对象公共的部分,类泛指一大类。

创建类与对象

注意事项

  • 实例化对象中必须要有new 只要有new关键字 类的构造函数constructor才会执行。
  • constructor()是类的构造函数,用于传递参数,返回实例化对象。
  • 通过class创建类 类名首字母大写,后面不用加小括号
  • 类里面的所有函数不需要加function,多个函数之间不需要加逗号。
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>创建类与对象</title>
    </head>
    <body>

    </body>
    <script>
        // 创建类
        class People {
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            say(sing) {
                console.log(sing)
            }
        }

        // 创建实例化对象
        let YaoZiMo = new People('尧子陌', "18");
        console.log(YaoZiMo.name);
        console.log(YaoZiMo.age);
        YaoZiMo.say('两只蝴蝶')
    </script>
</html>

image.png

类的继承

利用extends可让子类继承父类
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>类的继承</title>
    </head>
    <body>
    </body>
    <script>
        // 类的继承
        class Father {
            constructor() {

            }

            money() {
                console.log(100)
            }
        }

        // 继承父类中的方法与属性
        class Son extends Father {

        }

        // 创建子类的实例化对象
        var son = new Son();
        son.money()
    </script>
</html>

image.png

注意事项
1.继承中,如果实例化子类中输入一个方法,先看子类有没有这个方法,如果有就先执行子类的
2.继承中,如果子类里面没有这个方法,就去父类中查找(就近原则)
3.如果子类想使用父类中的方法,就要利用好super()调用父类的构造函数,super必须在this之前调用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>super关键字</title>
    </head>
    <body>
    </body>
    <script>
        // 父类
        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) //调用父类中的构造函数
            }
        };
        // 创建子类的实例化对象
        let son = new Son(1, 2);
        son.sum()
    </script>
</html>

image.png

调用普通函数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>super调用普通函数</title>
    </head>
    <body>

    </body>
    <script>
        // 父类
        class Father {
            say() {
                return 'hello word'
            }
        }

        // 子类
        class Son extends Father {
            say() {
                console.log(super.say())
            }
        }
        var son = new Son();
        son.say()
    </script>
</html>

image.png

子类继承父类的方法同时扩展自己的方法

注意:super()必须在子类构造函数中的this之前调用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>子类继承父类的方法 同时扩展子类的方法 </title>
    </head>
    <body>

    </body>
    <script>
        // 父类 有加法方法
        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()方法必须在子类的this之前进行调用
                super(x, y)
                this.x = x;
                this.y = y;
            }
            subduction() {
                console.log(this.x - this.y)
            }
        }

        // 对子类进行实例化 获取类的对象
        var son = new Son(5, 3);
        // 子类调用父类的方法
        son.sum()

        son.subduction()
    </script>
</html>

image.png

ES6中的类和对象的三个注意点。

1.在ES6中类没有变量提升,所以必须先定义类,才能通过实例化对象
2.类里面的公共属性与方法一定要加this
3.constructor里面的this指向实例化对象,方法里面的this指向这个方法的调用者

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title>使用类的注意事项</title>
    </head>

    <body>
        <button type="button" class="bth">点击</button>
    </body>
    <script>
        var that;
        var _that;
        class People {
            constructor(name, age) {
                that = this;
                console.log(this)
                this.name = name;
                this.age = age;
                this.bth = document.querySelector('button');
                this.bth.onclick = this.sing;
            }

            sing() {
                console.log(this) //里面的this指向bth按钮
                console.log(that.name) //that指是constructor中的this
            }
            dance() {
                _that = this;
                console.log(this) //此时的this指向实例化对象 因为实例化对象调用了dance这个函数

            }
        }

        // 创建类
        var people = new People('尧子陌');
        console.log(that === people)
        people.dance()
        console.log(_that === people)
    </script>

</html>

image.png

查看原文

赞 2 收藏 2 评论 0

认证与成就

  • 获得 12 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 8月2日
个人主页被 311 人浏览