美文网首页
二、JavaScript 笔记之一等公民函数

二、JavaScript 笔记之一等公民函数

作者: cqzhangjian | 来源:发表于2019-07-23 11:12 被阅读0次

    函数抽象的产物,可以作为变量使用。

    • 函数定义:
      function foo() {}
      或者
      var foo = function(){}
      两种方式完全等价,第二种可以通过 foo 变量传递

    1. 变量作用域及变量提升

    • 作用域:两类(1.局部作用域 2.全局作用域)
      先聊下 定义变量 的 var ,在函数中采用 var 定义的变量 只能在函数中使用,外部不能引用,称为函数局部变量;采用 var 在函数外部定义的变量称为 全局变量,函数可以使用全局的变量。当没有在 严格模式下,在函数中不采用 var 来定义变量,该变量如果在 浏览器环境中,会自动绑定在 window 对象下成为一个全局变量,这样会造成全局变量污染。避免全局变量污染,可以定义名称空间,如:
    // 唯一的全局变量MYAPP:
    var MYAPP = {};
    
    // 其他变量:
    MYAPP.name = 'myapp';
    MYAPP.version = 1.0;
    
    // 其他函数:
    MYAPP.foo = function () {
        return 'foo';
    };
    
    

    注意:在块级作用域 例如 if 或 for等语句的时候,定义的局部变量在跨级作用域以外也可以使用,为了避免这种情况,在es6 出现了 let 来定义变量,来代替 var 定义变量,从而使定义在块级的变量有了块级作用域范围,在外部不能引用。以上是定义变量,如果定义常量 es6 出现了 const来定义常量。

    • 变量提升问题
      函数有个特点,就是会将函数内定义的变量提升到函数的顶端。赋值不会。

    2. 解构赋值

    解构:同时对一组变量进行赋值

    • 对数组进行解构:
            var attr = ['java','es6']
            var [x,y] = attr
            console.log(x,y)
            var [z,] = attr
            console.log(z)
            var attr2 = ['a','b',['aa','bb']]
            var [,,[k,j]] = attr2
            console.log(k,j)
    
    • 对 对象解构
            var person = {
                name: 'zhangsan',
                age: 12,
                sex: true,
                address: {
                    city: 'Beijing',
                    street: 'No.1 Road'
                }
            }
            var {name,age,} = person
            console.log(name,age)
            var {name,age,address:{city,street}} = person
            console.log(name,age,city,street)
            var {name1} = person
            console.log(name1) //undefined 是因为 解构对象的时候,对象的属性名称跟变量名称不一致造成。
            var {name:name1} = person
            console.log(name1) // 通过属性赋值变量的形式解决   ,对象的属性名称跟变量名称不一致
            var {color = '黄色'} = person  //解构过程中对象没有属性,可以采用赋默认值
            console.log(color)
    

    注意: 对已申明的变量进行解构赋值 使用 () 包裹起来

     var name,age
            var person = {
                name: 'zhangsan',
                age: 12,
                sex: true,
                address: {
                    city: 'Beijing',
                    street: 'No.1 Road'
                }
            };
           (   {name,age} = person  )
            console.log(name,age)
    
    • 应用场景举个例子
            var x = 1, y = 2;
            [y,x] = [x,y];
            console.log(x,y); // 2,1 交换了位置
            var person = {
                name: '张三',
                age: 12
            };
            function foo({name ='默认值',age= 0}) {
                console.log(name,age)
            }
            foo(person)
    

    3.方法

    方法和普通函数没有多大区别,对象上绑定函数称为方法而已。

    • 坑1,方法中的 this
            'use strict'
       
            function foo() {
                console.log(this)
            }
            window.foo();
            foo();
    注意: 严格模式下,foo()执行后,打印的undefined,在非严格模式下 foo()执行后打印的是window对象
    
    • 坑2,还是 this
            'use strict'
    
            var person = {
                name: 'lisi',
                foo: foo
            }
       
            function foo() {
                console.log(this.name)
            }
            person.foo();
           // foo(); //Cannot read property 'name' of undefined
           var foo2 = person.foo;
           //foo2(); //Cannot read property 'name' of undefined
    
    • 坑3 继续 this
            'use strict'
    
            var person = {
                name: 'lisi',
                foo: function(){
                     function getName(){
                         return this.name;
                     }
                     return getName();
                }
            }
            //person.foo(); // Cannot read property 'name' of undefined
    

    解决:

            'use strict'
    
            var person = {
                name: 'lisi',
                foo: function(){
                     var that =  this;
                     function getName(){
                         return that.name;
                     }
                     return getName();
                }
            }
            person.foo();
    
    • apply 改变 this 的指向对象
      例子:
            'use strict'
            function foo(){
                return this.name;
            }
            var person = {
                name: 'lisi',
                age: 25,
                getName: foo
            };
            console.log(person.getName());
            console.log(foo.apply(person,[]));
    
    

    apply(this,参数):第一个参数传入的对象,第二个参数方法调用的参数,参数类型为Array ----> foo.apply(person,[]);
    apply 方法 跟 call 方法类似,区别在于第二个参数,apply传入的参数打包成Array再传入;call方法 参数是按顺序传入的。
    如果普通方法执行,第一个参数可传入 null

    • apply(),我们还可以动态改变函数的行为,采用装饰器模式
             'use strict'
            //计算 parseInt 方法调用的次数
            var tempParseInt = parseInt;
            var count  = 0 ;
            window.parseInt = function(){
                console.log(count++);
                return tempParseInt.apply(null,arguments);
            }
            parseInt('10');
            parseInt('20');
            parseInt('20');
            parseInt('20');
    

    4. 高阶函数

    一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

    function foo (x,y,fun){
                 console.log(fun(x) + fun(y));
                return fun(x) + fun(y);
             }
             foo(-1,2,Math.abs);
    

    在JavaScript Array 对象中提供了几个高阶函数:
    1.array.map((x)=>{return x}) 返回一个新的 array
    2.array.reduce((x,y)=>{return x + y}); //实现累加 返回一个计算结果
    [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)

    3.array.filter((x)=>{return true/false}) //返回新的过滤的数组,return false 过滤掉当前元素。
    array.filter((element, index, self)=>{}) //可以接收多个参数的函数

    4.array.sort((x,y)=>{return 0/-1/1}) 返回排序好的数组,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1
    ...... array 类型中提供了很多高阶函数,用到再查吧。

    相关文章

      网友评论

          本文标题:二、JavaScript 笔记之一等公民函数

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