zoukankan      html  css  js  c++  java
  • js基础语法之函数

    普通函数

    function foo(a, b){
    	return a + b;
    }
    
    foo(10, 20)
    
    >>> 30
    

      匿名函数

    var f = function(){console.log(123)};
    
    f()
    
    >>> 123
    

      自执行函数

    (function(a,b){return a + b})(10, 20)

    >>> 30

      内置函数forEach

        传一个参数:

    var a1 = [11, 22, 33, 44, 55];
    a1.forEach(function(i){
    	console.log(i);
    })
    
    >>> 11
        22
        33
        44
        55
    

      传两个参数:

    var a1 = [11, 22, 33, 44, 55];
    a1.forEach(function(k, inde){
    	console.log(k, inde);
    })
    
    >>> 11 0
        22 1
        33 2
        44 3
        55 4
    

      分析:第二个参数为其value在数组中所对应的索引值

      传三个参数:

    var a1 = [11, 22, 33, 44, 55];
    
    a1.forEach(function(k, inde, z){
    	console.log(k, inde, z);
    })
    
    
    >>> 11 0 (5) [11, 22, 33, 44, 55]
        22 1 (5) [11, 22, 33, 44, 55]
        33 2 (5) [11, 22, 33, 44, 55]
        44 3 (5) [11, 22, 33, 44, 55]
        55 4 (5) [11, 22, 33, 44, 55]
    

      分析:第三个参数为迭代的数组

    内置函数.map()

    1 var a1 = [11, 22, 33, 44, 55];
    2 a1.map(function(i){
    3     return i + 1
    4 })
    5 
    6 >>> (5) [12, 23, 34, 45, 56]

      解析:将a1数组中的各个元素分别加1,最终以数组的形式返回结果.

    当不给函数传值时,函数返回NaN.

    1 function foo(a, b){
    2     return a + b;
    3 }
    4 foo()
    5 
    6 >>> NaN

    分析: foo函数需要两个函数,函数调用时没有给传参数,结果返回NaN.

    当函数返回值为多个时,最终返回的结果为最后一个.

    1 function bar(a, b){
    2     return 10, 20, 30;
    3 }
    4 var x = bar();
    5 x
    6 
    7 >>> 30

    例外一种情况:

     1 function bar(a, b){
     2     return 10, 20, 30;
     3 }
     4 var x, b = bar()
     5 x
     6 
     7 >>> 30
     8 
     9 b
    10 
    11 >>> 30
    12 
    13 x, b
    14 
    15 >>> 30

     

    当函数传入值的个数多余接收参数的数量时,多余的参数将不会被使用.

    1 function foo(a, b){
    2     return a + b
    3 }
    4 foo(10, 20, 300)
    5 
    6 >>> 30

    实现简单加法器:

    function mySum(a, b){
    	var ret = 0;
    	for (var i=0; i < arguments.length; i++){
    		ret += arguments[i];
    	}
    	return ret;
    }
    mySum(10, 20)  // 传入两个值
    
    >>> 30

    mySum(10, 20, 30) // 传入三个值

    >>> 60

    mySum(10) // 传入一个值

    >>> 10

    mySum() // 不穿值时输出0

    >>> 0

      

    箭头函数

    var a1 = [11, 22, 33, 44, 55];
    a1.forEach((i)=>{
    	console.log(i);
    })
    
    >>> 11
        22
        33
        44
        55
    

      箭头函数是匿名函数的简写,箭头函数的this是固定的.

    变量加在顺序:

    function f1(){
      var x1 = 100; } x1 >>> Uncaught ReferenceError: x1 is not defined at <anonymous>:1:1

      在全局中无法调用局部变量.

    var x2 = 200;
    function f2(){
      console.log(x2);
    }
    f2()
    
    >>> 200
    

      在局部作用域中可以调用全局变量.

    var x2 = 200;
    function f2(){
      x2 += 1;
    }
    x2
    
    >>> 200  // 打印x2直接调用x2,此时函数f2还没有执行,调用的是全局变量x2=200.
    
    f2()
    x2
    
    >>> 201  // 在执行函数f2之后,x2增加1,然后调用x2,此时全局变量中的x2值为201.
    

      

    作用域:

      首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。

    例1:

    var city = 'BeiJing';
    function f() {
      var city = 'ShangHai';
      function inner(){
      var city = 'ShenZhen';
      console.log(city);
      }
      inner();
    }
    
    f();

    >>> ShenZhen

      函数从上往下执行,city的值为'BeiJing',当执行到f()时,开始执行f()的函数体,执行完成之后,此时的city的值为'ShangHai',函数再往下执行,当执行到inner()时,开始执行inner的函数体,此时的city的值为'ShenZhen',然后执行打印,此时console的作用域中有city并且其值为'ShenZhen',所以打印结果为'ShenZhen'。

     例2:

    var city = 'BeiJing';
    function Bar() {
      console.log(city);
    }
    function f() {
      var city = 'ShangHai';
      return Bar;
    }
    var ret = f();
    ret();
    
    >>> BeiJing
    

      函数由上至下开始执行,此时city的值为'BeiJing',然后执行ret(),此时的ret为f(),执行f函数的函数体,此时city的值为'ShangHai',返回Bar,此时的ret()为Bar(),执行Bar函数的函数体,打印city,但是函数Bar的作用域中没有city变量,然后去外层作用域即全局作用域中查找,全局作用域中city的值为'BeiJing',所以打印结果为'BeiJing'. 

    例3:闭包

    var city = 'BeiJing';
    function f() {
      var city = 'ShangHai';
      function inner() {
      	console.log(city);
      }
      return inner;
    }
    var ret = f();
    ret();
    
    >>> ShangHai
    

      函数由上至下开始执行,,此时city的值为'BeiJing',执行ret(),此时的ret为f函数,开始执行f的函数体,此时的city的值为'ShangHai',返回inner,此时的ret为inner函数,接着执行inner的函数体,打印city,但是inner的局部作用域中没有city,就像外层作用域查找,外层作用域的city的值为'ShangHai',所以打印结果为ShangHai.

    语法分析:

     JavaScript中在调用函数的那一瞬间,会先进行词法分析.

       词法分析的过程:

        当函数调用的前一瞬间,会先形成一个激活对象:Active Object(AO),并会分析一下3个方面:

        1. 函数参数,如果有,则将此参数赋值给AO,且值为undefined.如果没有,则不做任何操作.

        2. 函数局部变量,如果AO上有同名的值,则不做任何操作.如果没有,则将此变量赋值给AO,并且值为undefined.

        3. 函数声明,如果AO上有,则会将AO上的对象覆盖.如果没有,则不做任何操作.

        函数内部无论是使用参数还是使用局部变量都到AO是上找.

    例1:

    var age = 18;
    function foo(){
    	console.log(age);
    	var age = 22;
    	console.log(age);
    	function age() {
    		console.log('呵呵');
    	}
    	console.log(age);
    }
    foo();
    
    >>> ƒ age() {
    		console.log('呵呵');
    	}
    >>> 22
    >>> 22
    

      

    内置对象和方法

      JavaScript中所有的事务都是对象: 字符串、数字、数组、日期、等等。在JavaScript中对象是拥有属性和方法的数据。

      区分s1  = 'yingying'和s2 = new String('yingying')的区别:

      

    var s1 = 'yingying';
    var s2 = new String('yingying');
    s1
    
    >>> "yingying"
    
    s2
    
    >>> String {"yingying"}
    
    s2.length
    
    >>> 8
    
    typeof s1
    
    >>> "string"
    
    typeof s2
    
    >>> "object"

     s2. slice(2, 5)


     >>> "ngy"

      

     玩儿法二:

    var o1 = {'a': 100, 'b': 200};
    o1.length
    
    >>> undefined
    

      对象不能使用length属性计算长度.

    var o1 = {'a': 100, 'b': 200};
    for(var i in o1){
    	console.log(i);
    }
    
    >>> a
        b
    

      循环对象(相当于python中的字典)时打印的是对象(相当于python中的字典)的key.

    var o1 = {'a': 100, 'b': 200};  // 创建对象的方式
    o1['a']
    
    >>> 100
    
    o1.a
    
    >>> 100
    

      o1['a']相当于o1.a.

    var o2 = new Object();  // 创建对象的另外一种方式;
    o2.name = 'yingying';
    
    >>> "yingying"
    
    o2
    
    >>> {name: "yingying"}
    

      

    创建一个对象:

    var Person = function(dream){
    	this.dream = dream;
    };
    var p1 = new Person('咸鱼翻身');
    p1
    
    >>> Person {dream: "咸鱼翻身"}
    
    p1.dream
    
    >>> "咸鱼翻身"

     Person.prototype.makeDream = function(){
     console.log('在做白日 梦!');
     }

     >>>  ƒ (){

       console.log('在做白日 梦!');
       }

     var p2 = new Person('鲤鱼打挺');

     p2.dream

     >>>  "鲤鱼打挺"

     p2.makeDream

     >>> ƒ (){

       console.log('在做白日 梦!');
       }

      

    var Yellow = function(dream){
    	Person.call(this, dream);
    }
    Yellow.prototype = Object.create(Person.prototype)
    Yellow.prototype.constructor = Yellow;
    Yellow.prototype.sing = function(){
    	console.log('龙的传人');
    }
    var p3 = new Yellow('没有蛀牙!')
    p3.dream
    
    >>> "没有蛀牙!"
    
    p3.makeDream()
    
    >>> 在做白日 梦!
    
    
    p3.sing()
    
    >>> 龙的传人
    

      

     

     Date对象

    方法一: 不指定参数

    var d1 = new Date();
    console.log(d1.toLocaleString());
    
    >>> 2018/9/5 下午6:10:12
    

      方法二:参数日期字符串

    var d2 = new Date("2004/3/20 11:12");
    console.log(d2.toLocaleString());
    var d3 = new Date("04/03/20 11:12");
    console.log(d3.toLocaleString());
    
    >>> 2004/3/20 上午11:12:00
        2020/4/3 上午11:12:00
    

      方法三:参数为毫秒数

    var d3 = new Date(5000);
    console.log(d3.toLocaleString());
    console.log(d3.toUTCString());
    
    >>> 1970/1/1 上午8:00:05
       Thu, 01 Jan 1970 00:00:05 GMT
    

      方法四:参数为年月日小时分钟秒毫秒

    var d4 = new Date(2004,2,20,11,12,0,300);
    console.log(d4.toLocaleString());  //毫秒并不直接显示
    
    >>> 2004/3/20 上午11:12:00
    

      Date对象的方法:

    var d = new Date();
    d
    >>> Wed Sep 05 2018 18:47:41 GMT+0800 (中国标准时间)
    
    d.getDate()  // 获取日
    
    >>> 5
    
    d.getDay()  // 获取星期
    
    >>> 3
    
    d.getMonth()  // 获取月(0-11)(获取的月加1为当前月份)
    
    >>> 8
    
    d.getFullYear()  // 获取完整年份
    
    >>> 2018
    
    d.getYear()  // 获取年份
    
    >>> 118
    
    d.getHours()  // 获取小时
    
    >>> 18
    
    d.getMinutes()  // 获取分钟
    
    >>> 47
    
    d.getMilliseconds()  // 获取毫秒
    
    >>> 272
    
    d.getTime()  // 获取时间戳
    
    >>> 1536144461272
    

      

    将当前时间格式化为指定格式:

    function timeFormat(){
        var weekDict = {
            1: '星期一',
            2: '星期二',
            3: '星期三',
            4: '星期四',
            5: '星期五',
            6: '星期六',
            7: '星期日',
        };
        var d = new Date();
        var y = d.getFullYear().toString();
        var m = d.getMonth().toString();
        var D = d.getDate().toString();
        var h = d.getHours().toString();
        var M = d.getMinutes().toString();
        var w = d.getDay();
        var week = weekDict[w];
    
        var ret = y.concat('-', m, '-', D, ' ', h, ':', M, ' ', week);
        console.log(ret);
    }
    
    timeFormat()
    
    
    >>> 2018-8-5 19:56 星期三  // 示例时间
    

      

    序列化:

      

    var o1 =  {'name': 'yingying', 'age': 20};
    o1
    
    >>> {name: "yingying", age: 20}
    
    var s1 = JSON.stringify(o1);  // 序列化
    s1
    
    >>> "{"name":"yingying","age":20}"
    
    JSON.parse(s1)  // 反序列化
    
    >>> {name: "yingying", age: 20}
    

      

    正则

    验证手机号的合法性:

    var r1 = new RegExp('^1[3-9]\d{9}$');  // d的需要转译
    r1.test('18812342234')
    
    >>> true
    var r1 = new RegExp('^1[3-9][0-9]{9}$');
    r1.test('18812342234')
    
    >>> true
    

      另一种创建正则的方式:

    /^1[3-9][0-9]{9}$/.test('18812342234')
    
    >>> true
    
    /^1[3-9]d{9}$/.test('18812342234')   // 在这种创建方式相加不需要转译
    
    >>> true
    

      JS正则大坑:

      坑一:

    var r3 = new RegExp('^[a-zA-Z][a-zA-Z0-9]{5,11}$')
    r3.test('yingying')
    
    >>> true
    
    r3.test()  // 没有输入则按照undefined去匹配;
    
    >>> true
    
    r3.test(undefined)  // 将undefined按照字符串'undefined'去匹配;
    
    >>> true
    
    r3.test('undefined')
    
    >>> true
    

      坑二:

      正则表达式中不能有空格,否则将会出现异常.

    var s1 = 'ying Ying';
    s1.replace('i', '哈哈')
    
    >>> "y哈哈ng Ying"
    
    s1.replace(/i/, '哈哈')
    
    >>> "y哈哈ng Ying"
    
    s1.replace(/y/i, '哈哈')
    
    >>> "哈哈ing Ying"
    
    s1.replace(/y/gi, '哈哈')
    
    >>> "哈哈ing 哈哈ing"
    

      i表示忽略大小写的匹配模式

      g表示全局匹配模式

       出现这种情况的原因是在匹配过程中,当匹配成功是,系统会保留一个指针,当下次匹配时从指针的位置开始匹配,直到结束位置.当到结束位置还未匹配成功就返回False,下次再从起始位置开始.

    var r5 = /alex/g;
    r5.test('alex')
    
    >>> true
    
    r5.test('alex')
    
    >>> false
    
    r5.test('alex')
    
    >>> true
    

      

    r5.lastIndex
    
    >>> 0
    
    r5.test('alex')
    
    >>> true
    
    r5.lastIndex
    
    >>> 4
    
    r5.test('alex')
    
    >>> false
    
    r5.lastIndex
    
    >>> 0
    

      正则表达式加上g就会记录一个lastInedx属性用来记录下次从哪里开始匹配.

     随机数

    Math.random()  // 产生0到1之间的随机数
    
    >>> 0.0640924093253199
    

      

     取最大值

    Math.max(10, 20, 30)
    
    >>> 30
    

      

    round

    Math.round(6.5)
    
    >>> 7
    

    开平方

    Math.sqrt(0.1)
    
    >>> 0.31622776601683794
    

      

  • 相关阅读:
    hbase coprocessor 二级索引
    文档:ubuntu安装.pdf
    Python过滤敏感词汇
    nginx 对django项目的部署
    ZooKeeper 的常用操作方法
    Python操作reids
    教你为nginx 配置ssl 证书!
    单线程多任务异步爬虫
    go语言入门之环境的搭建
    关于csrf跨站请求伪造攻击原理,与csrftoken防范原理
  • 原文地址:https://www.cnblogs.com/ZN-225/p/9590941.html
Copyright © 2011-2022 走看看