JavaScript高级(2)

JavaScript高级(2)

函数的其他成员

  • arguments
    • 实参集合
  • caller
    • 函数的调用者
  • length
    • 形参的个数
  • name
    • 函数的名称
function fn(x, y, z) {
  console.log(fn.length) // => 形参的个数
  console.log(arguments) // 伪数组实参参数集合
  console.log(arguments.callee === fn) // 函数本身
  console.log(fn.caller) // 函数的调用者
  console.log(fn.name) // => 函数的名字
}

function f() {
  fn(10, 20, 30)
}

f()

高阶函数

  • 函数可以作为参数
  • 函数可以作为返回值

作为参数

function eat (callback) {
  setTimeout(function () {
    console.log('吃完了')
    callback()
  }, 1000)
}

eat(function () {
  console.log('去唱歌')
})

作为返回值

function genFun (type) {
  return function (obj) {
    return Object.prototype.toString.call(obj) === type
  }
}

var isArray = genFun('[object Array]')
var isObject = genFun('[object Object]')

console.log(isArray([])) // => true
console.log(isArray({})) // => true

函数闭包

function fn () {
  var count = 0
  return {
    getCount: function () {
      console.log(count)
    },
    setCount: function () {
      count++
    }
  }
}

var fns = fn()

fns.getCount() // => 0
fns.setCount()
fns.getCount() // => 1

作用域、作用域链、预解析

  • 全局作用域
  • 函数作用域
  • 没有块级作用域
{
  var foo = 'bar'
}

console.log(foo)

if (true) {
  var a = 123
}
console.log(a)

作用域链示例代码:

var a = 10

function fn () {
  var b = 20

  function fn1 () {
    var c = 30
    console.log(a + b + c)
  }

  function fn2 () {
    var d = 40
    console.log(c + d)
  }

  fn1()
  fn2()
}
  • 内层作用域可以访问外层作用域,反之不行。

闭包

闭包就是能够读取其他函数内部变量的函数,
由于在JavaScript语言中,只有函数内部的子函数才能读取局部变量,
由此可以把闭包简单成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的用途

  • 可以在函数外部读取函数内部成员
  • 让函数内成员始终存活在内存中

一些关于闭包的例子

var arr = [10, 20, 30]
for(var i = 0; i < arr.length; i++) {
  arr[i] = function () {
    console.log(i)
  }
}

函数递归

递归执行模型

function fn1 () {
  console.log(111)
  fn2()
  console.log('fn1')
}

function fn2 () {
  console.log(222)
  fn3()
  console.log('fn2')
}

function fn3 () {
  console.log(333)
  fn4()
  console.log('fn3')
}

function fn4 () {
  console.log(444)
  console.log('fn4')
}

fn1()

计算阶乘的递归函数

function factorial (num) {
  if (num <= 1) {
    return 1
  } else {
    return num * factorial(num - 1)
  }
}

递归应用场景

  • 深拷贝

<!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>
    // 深拷贝
    var obj1 = {
      name: 'zs',
      age: 18,
      sex: '男',
      dog: {
        name: '金毛',
        age: 2
      },
      friends: ['ls', 'ww']
    }

    // 深拷贝  把o1的成员拷贝给o2
    function deepCopy(o1, o2) {
      for (var key in o1) {
        // 获取key属性对应的值
        var item = o1[key];

        // 如果item 是对象?
        // var o = {}
        if (item instanceof Object) {
          // var o = {};
          o2[key] = {}; 
          deepCopy(item, o2[key]);
        } else if (item instanceof Array) {
          // 如果item 是数组呢?
          // var arr = [];
          o2[key] = [];
          deepCopy(item, o2[key]);
        } else {
          // 如果是简单类型
          o2[key] = o1[key];
        }
      }
    }


    var obj2 = {};

    deepCopy(obj1, obj2);

    // 修改obj1中的成员 是否会影响obj2?
    obj1.dog.name = 'xxx';
    obj1.friends[0] = 'xxx';

    console.dir(obj2);
  </script>
</body>
</html>
  • 遍历DOM树

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>遍历DOM树</title>
</head>
<body>
  <h1>遍历 DOM 树</h1>
  <p style="color: green;">Tip: 可以在遍历的回调函数中任意定制需求</p>
  <div>
    <ul id="list">
      <li>123</li>
      <li>456</li>
      <li>789</li>
    </ul>
    <div>
      <div>
        <span>haha</span>
      </div>
    </div>
  </div>
  <div id="demo_node">
    <ul>
      <li>123</li>
    </ul>
    <p>hello</p>
    <h2>world</h2>
    <div>
      <p>dsa</p>
      <h3>
        <span>dsads</span>
      </h3>
    </div>
  </div>
  <script>
    // 遍历指定元素下所有的子元素
    function loadTree(parent, callback) {
      for (var i = 0; i < parent.children.length; i++) {
        // 遍历第一级子元素
        var child = parent.children[i];
        // console.log(child);
        if (callback) {
          // 处理找到的子元素
          callback(child);
        }

        // 递归调用
        loadTree(child);
      }
    }

    var ul = document.getElementById('list');
    loadTree(ul, function (element) {
      element.onclick = function () {
        console.log(this.innerText);
      }
    });
  </script>
</body>
</html>

正则表达式

  • 了解正则表达式基本语法
  • 能够使用JavaScript的正则对象

正则表达式简介

正则表达式的作用

1.给定的字符串是否符合正则表达式的过滤逻辑(匹配)
2.可以通过正则表达式,从字符串中获取我们想要的特定部分(提取)
3.强大的字符串替换能力(替换)

正则表达式的特点

1.灵活性、逻辑性和功能性非常的强
2.可以迅速地用极简单的方式达到字符串的复杂控制
3.对于刚接触的人来说,比较晦涩难懂

正则表达式的测试

在线测试正则

正则表达式的组成

  • 普通字符abc 123
  • 特殊字符(元字符):正则表达式中有特殊意义的字符\d \w

常用元字符

元字符说明
\d匹配数字
\D匹配任意非数字的字符
\w匹配字母或数字或下划线
\W匹配任意不是字母,数字,下划线
\s匹配任意的空白符
\S匹配任意不是空白符的字符
.匹配除换行符以外的任意单个字符
^表示匹配行首的文本(以谁开始)
$表示匹配行尾的文本(以谁结束)

限定符

限定符说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

其他
[] 字符串用中括号括起来,表示匹配其中的任一字符,相当于或的意思
[^] 匹配除中括号以内的内容
\ 转义符
| 或者,选择两者中的一个。注意|将左右两边分为两部分,而不管左右两边有多长多乱
() 从两个直接量中选择一个,分组
eg:gr(a|e)y匹配gray和grey
[\u4e00-\u9fa5] 匹配汉字

验证手机号:

^\d{11}$

验证邮编:

^\d{6}$

验证日期 2012-5-01

^\d{4}-\d{1,2}-\d{1,2}$

验证邮箱 xxx@itcast.cn:

^\w+@\w+\.\w+$

验证IP地址 192.168.1.10

^\d{1,3}\(.\d{1,3}){3}$

JavaScript 中使用正则表达式

创建正则对象

方式1:

var reg = new RegExp('\d', 'i');
var reg = new RegExp('\d', 'gi');

方式2:

var reg = /\d/i;
var reg = /\d/gi;

参数

标志说明
i忽略大小写
g全局匹配
gi全局匹配+忽略大小写

正则匹配

// 匹配日期
var dateStr = '2015-10-10';
var reg = /^\d{4}-\d{1,2}-\d{1,2}$/
console.log(reg.test(dateStr));

正则提取

// 1. 提取工资
var str = "张三:1000,李四:5000,王五:8000。";
var array = str.match(/\d+/g);
console.log(array);

// 2. 提取email地址
var str = "123123@xx.com,fangfang@valuedopinions.cn 286669312@qq.com 2、emailenglish@emailenglish.englishtown.com 286669312@qq.com...";
var array = str.match(/\w+@\w+\.\w+(\.\w+)?/g);
console.log(array);

// 3. 分组提取  
// 3. 提取日期中的年部分  2015-5-10
var dateStr = '2016-1-5';
// 正则表达式中的()作为分组来使用,获取分组匹配到的结果用Regex.$1 $2 $3....来获取
var reg = /(\d{4})-\d{1,2}-\d{1,2}/;
if (reg.test(dateStr)) {
  console.log(RegExp.$1);
}

// 4. 提取邮件中的每一部分
var reg = /(\w+)@(\w+)\.(\w+)(\.\w+)?/;
var str = "123123@xx.com";
if (reg.test(str)) {
  console.log(RegExp.$1);
  console.log(RegExp.$2);
  console.log(RegExp.$3);
}

正则替换

// 1. 替换所有空白
var str = "   123AD  asadf   asadfasf  adf ";
str = str.replace(/\s/g,"xx");
console.log(str);

// 2. 替换所有,|,
var str = "abc,efg,123,abc,123,a";
str = str.replace(/,|,/g, ".");
console.log(str);

案例:验证表单

<!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>
    <label for="txtQQ">QQ号:<input type="text" id="txtQQ"><span></span></label><br>
    <label for="txtEmail">邮箱:<input type="text" id="txtEmail"><span></span></label><br>
    <label for="txtPhone">手机:<input type="text" id="txtPhone"><span></span></label><br>
    <label for="txtBirth">生日:<input type="text" id="txtBirth"><span></span></label><br>
    <label for="txtName">姓名:<input type="text" id="txtName"><span></span></label><br>
    <script>
        // 1.验证QQ号
        addCheck('txtQQ', /^\d{5,12}$/, '请输入正确的QQ号格式');
        addCheck('txtEmail', /^\w+@\w+(\.\w+)+$/, '请输入正确的邮箱格式');
        addCheck('txtPhone', /^[1-9]\d{10}$/, '请输入正确的手机号格式');
        addCheck('txtBirth', /^\d{4}-\d{1,2}-\d{1,2}$/, '请输入正确的日期格式');
        addCheck('txtName', /^[\u4e00-\u9fa5]{0,}$/, '请输入2-4个汉字');

        // 文本框的验证封装成一个函数
        // 第一个参数是元素的id
        // 第二个参数 正则表达式对象 RegExp
        // 第三个参数 是提示的文本
        function addCheck(elementId, reg, tip) {
            var element = document.getElementById(elementId);
            element.onblur = function () {
                var span = this.nextElementSibling;
                // 验证
                if (!reg.test(this.value)) {
                    span.innerText = tip;
                    span.style.color = 'red';
                } else {
                    span.innerText = '';
                    span.style.color = '';
                }
            }
        }

        // onchange 改变
    //     var txtQQ = document.getElementById('txtQQ');
    //     // txtQQ.onchange = function () {
    //     //     console.log("111");
    //     // }
    //     // 当光标离开文本框的时候
    //     txtQQ.onblur = function () {
    //         // 验证用户的输入是否是QQ号
    //         var reg = /^\d{5,12}$/;
    //         var span = this.nextElementSibling;
    //         // 检测输入的文本是否匹配指定的模式(正则表达式)
    //         if (!reg.test(this.value)) {
    //             //  不匹配 在文本框后面的span中进行相应的提示

    //             span.innerText = '请输入正确的QQ格式';
    //             span.style.color = 'red';
    //         } else {
    //             // 匹配
    //             span.innerText = '';
    //             span.style.color = '';
    //         }
    //     }
    </script>
</body>

</html>

这篇文章有 282 个评论

  1. instagram begeni satin al

    Hey there! Do you know if they make any plugins to protect against hackers?
    I’m kinda paranoid about losing everything
    I’ve worked hard on. Any tips?

  2. I’m more than happy to discover this great site. I wanted to thank you
    for your time due to this wonderful read!! I definitely
    savored every little bit of it and I have you saved as a favorite to see
    new stuff in your blog.

  3. Women's recovery house

    Good blog you have here.. It’s difficult to find excellent writing like yours
    these days. I honestly appreciate people like you!
    Take care!!

  4. confinement meal

    I need to to thank you for this good read!! I absolutely loved every little bit
    of it. I’ve got you book-marked to check out new things you post…

  5. Derick

    I’ve been exploring for a little for any high-quality
    articles or blog posts in this sort of house . Exploring in Yahoo
    I ultimately stumbled upon this site. Reading this information So i am happy to convey that I’ve a very good uncanny feeling I came upon exactly what I needed.
    I most unquestionably will make sure to do not omit this website and give it a glance on a relentless basis.

  6. trentonlhwl185.trexgame.net

    Hello There. I found your blog using msn. This is a very well written article.
    I’ll make sure to bookmark it and return to read more of your useful information. Thanks for the post.
    I will definitely return.

  7. Fire damage restoration cost

    Thank you for another wonderful article. Where else may anyone get that
    kind of information in such a perfect means of writing?

    I’ve a presentation next week, and I’m on the look for such information.

  8. Socken mit foto

    Hi, Neat post. There is an issue with your site in internet explorer, might test this?

    IE nonetheless is the marketplace chief and a good portion of other
    folks will leave out your fantastic writing because of this problem.

  9. USA people search

    Write more, thats all I have to say. Literally, it seems as
    though you relied on the video to make your point. You definitely know what youre talking about,
    why throw away your intelligence on just posting videos
    to your site when you could be giving us something informative to read?

  10. x6wgzdh884.doodlekit.com

    Hey! Do you know if they make any plugins to help with SEO?
    I’m trying to get my blog to rank for some targeted
    keywords but I’m not seeing very good gains.
    If you know of any please share. Cheers!

  11. Hi there mates, how is the whole thing, and what you want to say regarding this paragraph, in my view its
    actually remarkable in support of me.

  12. Donette

    Hello There. I discovered your blog using msn. That
    is a really well written article. I’ll make sure to bookmark it and return to learn extra of your helpful info.

    Thanks for the post. I’ll certainly comeback.

  13. 레플리카

    Hmm it appears like your site ate my first comment (it was super long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog.
    I as well am an aspiring blog blogger but I’m still new to the whole thing.

    Do you have any tips and hints for beginner blog writers?

    I’d definitely appreciate it.

  14. https://opendialogus.co.uk/

    Hmm it looks like your website ate my first comment (it
    was super long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly
    enjoying your blog. I too am an aspiring blog blogger but I’m still new
    to the whole thing. Do you have any recommendations for first-time blog writers?

    I’d certainly appreciate it.

  15. When I originally commented I clicked the “Notify me when new comments are added” checkbox and now
    each time a comment is added I get four e-mails with
    the same comment. Is there any way you can remove people from that
    service? Thanks!

  16. Hello! I know this is kinda off topic however
    , I’d figured I’d ask. Would you be interested in trading links or maybe guest writing a blog post or vice-versa?
    My site goes over a lot of the same subjects as yours and I believe we
    could greatly benefit from each other. If you happen to be interested feel free to shoot me an e-mail.
    I look forward to hearing from you! Wonderful blog by the way!

  17. Shayne

    I visited many blogs but the audio quality for audio songs current at this site is truly fabulous.

  18. Himalayan Salt

    hello there and thank you for your info – I have definitely
    picked up something new from right here. I did however expertise some technical issues using this web site, since
    I experienced to reload the website many times previous to I could get it to
    load correctly. I had been wondering if your web hosting is OK?
    Not that I am complaining, but sluggish loading instances times will
    very frequently affect your placement in google
    and could damage your quality score if advertising and marketing with Adwords.
    Well I am adding this RSS to my e-mail and can look
    out for a lot more of your respective fascinating content.
    Ensure that you update this again very soon.

  19. Anitra

    If some one wishes to be updated with latest technologies afterward he must be pay a visit
    this web site and be up to date daily.

  20. Shop apple earpods online

    Hello there, just became alert to your blog through Google,
    and found that it’s truly informative. I’m going to watch out for brussels.
    I will be grateful if you continue this in future. A lot of people will be benefited from
    your writing. Cheers!

  21. adolph sharifi

    good poster ! your powerbloger! good luck~~Excellent blog here! Additionally your website quite a bit up fast! What host are you the use of? Can I am getting your affiliate hyperlink on your host? I desire my website loaded up as quickly as yours lol

  22. mylesalwgq.blognody.com

    It is not my first time to pay a quick visit this site,
    i am visiting this site dailly and take pleasant facts from here all
    the time.

  23. Joni

    Spot on with this write-up, I seriously think this amazing site needs much more attention.
    I’ll probably be back again to read more,
    thanks for the info!

  24. Alexis

    Howdy! This blog post could not be written any better!

    Going through this post reminds me of my previous roommate!
    He always kept preaching about this. I am going to send this article to him.
    Fairly certain he’ll have a good read. Many thanks for sharing!

  25. Wow that was odd. I just wrote an really long comment but after I clicked
    submit my comment didn’t appear. Grrrr… well I’m not writing all that over again. Regardless, just wanted to say wonderful blog!

发表评论