函数调用的四种方式

 

1.函数调用方式

2.方法调用方式

var length = 10;
    function fn() {
        console.log( this.length ); // 10
    }
    var obj = {
        length: 5,
        method: function ( fn ) {
            fn();   // 10 前面没有引导对象,是函数调用模式
            arguments[ 0 ](); // 2
            // arguments是一个伪数组对象, 这里调用相当于通过数组的索引来调用.
            // 这里 this 就是 指的这个伪数组, 所以 this.length 为 2
        }
    };
    obj.method( fn, 1 );    // 打印 10 和 2
    //obj.method( fn, 1, 2, 3 );    // 打印 10 和 4

3.构造器调用方式

  function Foo(){
        getName = function(){ alert(1); };
        return this;
    }
    Foo.getName = function(){ alert(2); };
    Foo.prototype.getName = function(){ alert(3); };
    var getName = function(){ alert(4); };
    function getName(){ alert(5); }

    Foo.getName();  // alert ??
    getName();  // alert ??
    Foo().getName(); // alert ??
    getName(); // alert ??
    new Foo.getName(); // alert ??
    new Foo().getName(); // alert ??
    new new Foo().getName(); // alert ??
===========================================================================

function Foo() {
        getName = function () { alert(1); };
        return this;
    }
    Foo.getName = function () { alert(2); };
    Foo.prototype.getName = function () { alert(3); };
    var getName = function () { alert(4); };

    Foo.getName();  // ------- 输出 2 -------
    // 调用 Foo函数 作为 对象 动态添加的属性方法 getName
    // Foo.getName = function () { alert(2); };

    getName();      // ------- 输出 4 -------
    // 这里 Foo函数 还没有执行,getName还没有被覆盖
    // 所以 这里还是 最上面的 getName = function () { alert(4); };

    Foo().getName();    // ------- 输出 1 -------
    // Foo()执行,先覆盖全局的 getName 再返回 this,
    // this 是 window, Foo().getName() 就是调用 window.getName
    // 此时 全局的 getName已被覆盖成 function () { alert(1); };
    // 所以 输出 1
    /* 从这里开始 window.getName 已被覆盖 alert 1 */

    getName();  // -------- 输出 1 --------
    // window.getName alert(1);

    new Foo.getName();     // ------- 输出 2 -------
    // new 就是 找 构造函数(),由构造函数结合性,这里即使 Foo无参,也不能省略 (),所以不是 Foo().getName()
    // 所以 Foo.getName 为一个整体,等价于 new (Foo.getName)();
    // 而 Foo.getName 其实就是函数 function () { alert(2); } 的引用
    // 那 new ( Foo.getName )(), 就是在以 Foo.getName 为构造函数 实例化对象。
    // 就 类似于 new Person(); Person 是一个构造函数

    // 总结来看 new ( Foo.getName )(); 就是在以 function () { alert(2); } 为构造函数来构造对象
    // 构造过程中 alert( 2 ),输出 2

    new Foo().getName();    // ------- 输出 3 -------
    // new 就是 找 构造函数(),等价于 ( new Foo() ).getName();
    // 执行 new Foo() => 以 Foo 为构造函数,实例化一个对象
    // ( new Foo() ).getName; 访问这个实例化对象的 getName 属性
    // 实例对象自己并没有 getName 属性,构造的时候也没有 添加,找不到,就到原型中找
    // 发现 Foo.prototype.getName = function () { alert(3); };
    // 原型中有,找到了,所以 ( new Foo() ).getName(); 执行,alert(3)

    var p = new new Foo().getName();     // ------- 输出 3 -------
    // new 就是 找 构造函数(),等价于 new ( ( new Foo() ).getName )() 输出 3

    // 先看里面的 ( new Foo() ).getName
    // new Foo() 以Foo为构造函数,实例化对象
    // new Foo().getName 找 实例对象的 getName属性,自己没有,去原型中找,
    // 发现 Foo.prototype.getName = function () { alert(3); }; 找到了

    // 所以里层 ( new Foo() ).getName 就是 以Foo为构造函数实例出的对象的 一个原型属性
    // 属性值为一个函数 function () { alert(3); } 的引用

    // 所以外层 new ( (new Foo()).getName )()在以该函数 function () { alert(3); } 为构造函数,构造实例
    // 构造过程中 执行了 alert(3), 输出 3

四.上下文调用方式(call(obj,arg1,arg2....),apply(obj,arg1,arg2....)/apply(obj,[arg1,arg2....]),bind(obj,arg1,arg2...)/bind(obj,[arg1,arg2....]))

五.数组新增方法

1.map 映射

语法: 数组.map( fn )

返回一个数组, 数组的每一个元素就是 map 函数中的 fn 的返回值

var arr = [ 1, 2, 3, 4 ];
     // 数学中: x -> x * x
     var a = arr.map(function ( v, i ) {
        return v * v;
     });
     // a [1, 4, 9, 16]

就是对每一项都进行操作,并返回

 

2.filter 就是筛选, 函数执行结果是 false 就弃掉, true 就收着

var arr = [ 1, 2, 3, 4, 5, 6 ];
    // 筛选奇数
    var a = arr.filter( function ( v ) { return v % 2 === 1; });
    // a [ 1, 3, 5 ]

语法: 数组.filter( function ( v, i ) { return true/false })

3.some 判断数组中至少有一个数据复合要求 就返回 true, 否则返回 false

    var arr = [ '123', {}, function () {}, 123 ];
    // 判断数组中至少有一个数字
    var isTrue = arr.some( function ( v ) { return typeof v === 'number'; } );  // true;

4.every 必须满足所有元素都复合要求才会返回 true

    var arr = [ 1, 2, 3, 4, 5, '6' ];
    // 判断数组中每一个都是数字
    var isTrue = arr.every( function ( v ) { return typeof v === 'number'; } ); } ); // false;

5.indexOf 在数组中查找元素, 如果含有该元素, 返回元素的需要( 索引 ), 否则返回 -1

     var arr = [ 1, 2, 3, 4, 5 ];
     var res = arr.indexOf( 4 );    // 要找 4
     console.log( res );    // 3     找 4 在 索引为 3 找到

     var arr = [ 1, 2, 3, 4, 5, 4, 5, 6 ];
     var res = arr.indexOf( 4, 4 ); // 要找 4, 从索引 4开始找
     console.log( res );    // 找到了 索引为 5

 

6.lastIndexOf 从右往左找

     var arr = [ 1, 2, 3, 4, 5, 4, 5, 6 ];
     var res = arr.lastIndexOf( 4 );
     console.log( res );    // 索引为 5, 从最后一项开始找,即从 length-1 项开始找

 

 

转载于:https://my.oschina.net/u/3937325/blog/1922336

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值