面向对象(五)--四种调用模式call与apply

2017-03-01  本文已影响0人  believedream

编程语言的几个出发点

变量,基础语法 ,函数
作用域 面向对象

1.函数的四种调用模式

  1. 函数模式
  2. 方法模式
  3. 构造器模式
  4. 上下文模式

1.1函数模式

1 函数的定义方式

        1> 声明式
        2> 表达式式
        3> Function
  1. 单独独立调用的就是函数
    1. 函数名( 参数 )
    2. this 表示全局对象

注意:任何自调用函数都是函数模式
代码演示:

function foo(){
    console.log(this);
}

foo();   //this指的是全局对象window

1.2 方法调用模式 method

方法本身就是函数, 但是方法不是单独独立的调用, 而是通过一个对象引导调用.

obj.方法( 参数 )

代码演示:


var length = 10;
    function fn() {
        console.log( this.length );
    }
    var obj = {
        length: 5,
        method: function ( fn ) {
            fn();              //10
            arguments[ 0 ]();  //2
        }
    };
    obj.method( fn, 1 );

1.3 构造器模式(构造函数模式, 构造方法模式)

使用 new 关键字引导

    -> 执行步骤
        var p = new Person();
        new 是一个运算符, 专门用来申请创建对象, 创建出来的对象传递给构造函数的 this
        利用构造函数对其初始化

        function Person () {
            this.name = 'jim',
            this.age = 19;
            this.gender = 'male';
        }
-> 返回值
    如果不写 return 语句, 那么 构造函数 默认返回 this
    如果在构造函数中写上 return 语句, 并紧跟基本类型( return num, return 1223 ). 则忽略返回类型. 
    如果在构造函数中写上 return 语句, 并且紧跟引用类型, 那么构造函数返回该引用类型数据, 而忽略 this

注意:** 如果调用构造函数的时候, 构造函数没有参数, 圆括号是可以省略的**

1.4上下文调用模式

注意:这两种形式功能完全一样, 唯一不同的是参数的形式.

-> 带有参数的函数如何实现上下文调用
        function foo ( num1, num2 ) {
            console.log( this );
            return num1 + num2;
        } 

        // 函数调用模式
        var res1 = foo( 123, 567 );

        // 方法调用
        var o = { name: 'jim' };
        o.func = foo;

        var res2 = o.func( 123, 567 );

使用 apply 进行调用, 如果函数是带有参数的. apply 的第一个参数要么是 null 要么是对象
如果是 null 就是函数调用, 如果是 对象就是 方法对象, 该对象就是宿主对象, 后面紧跟一个
数组参数, 将函数的参数依次放在数组中.

        例如: 函数模式        foo( 123, 567 );
              apply         foo.apply( null, [ 123, 567 ] )

        如果有一个函数调用: func( '张三', 19, '男' ), 将其修改成 apply 模式
        func.apply( null, [ '张三', 19, '男'] )

        方法模式:           o.func( 123, 567 )
        apply               foo.apply( o, [ 123, 567 ] )

call 调用

在使用 apply 调用的时候, 函数参数, 必须以数组的形式存在. 但是有些时候数组封装比较复杂
所以引入 call 调用, call 调用与 apply 完全相同, 唯一不同是是参数不需要使用数组.

foo( 123, 567 );

foo.apply( null, [ 123, 567 ] );

foo.call( null, 123, 567 );

扩展借用构造函数继承

 借用构造方法实现继承
    function Person ( name, age, gender ) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    function Student ( name, age, gender, course ) {

        Person.call( this, name, age, gender );

        this.course = course;
    }

    var p = new Student ( 'jim', 19, 'male', '前端' );

2.函数的 bind 方法

// 让 t 包含函数体( 原来 ), 同时还包含 对象 
    var t = document.getElementsByTagName.bind( document ), 
        arr = [];
    
    arr.push.apply( arr, t( 'p' ) );

    arr.push.apply( arr, t( 'div' ) );

t('p') 相当于 document.getElementsByTagName('p');


3. Object.prototype 的成员

1) constructor
2) hasOwnProperty 判断该属性是否为自己提供
3) propertyIsEnumerable 判断属性是否可以枚举
4) isPrototypeOf    判断是否为原型对象
5) toString, toLocaleString, valueOf

4.getter 与 setter 的语法糖

语法糖: 为了方便开发而给出的语法结构

    var o = (function () {
        var num = 123;
        return {
            get_num: function () {
                return num;
            },
            set_num: function ( v ) {
                num = v;
            }
        };
    })();

    // 获得数据
    o.get_num();            => o.num 形式

    // 设置
    o.set_num( 456 );       => o.num = 456 形式

    var o = (function () {
        var num = 123;
        return {
                
            // get 名字 () { 逻辑体 }
            get num () {
                return num;
            }

            // set 名字 ( v ) { 逻辑体 }
            set num ( v ) {
                num = v;
            }
        };
    })();
    

5.数组新增方法介绍

ES5 中引入的部分数组方法

  1. forEach
  2. map
  3. filter
  4. some
  5. every
  6. indexOf
  7. lastIndexOf

演示代码:

// 1 forEach
    // var arr = [ 'hello', ' js', {  }, function () {} ];
    // // 遍历 数组
    // arr.forEach( function ( v, i ) {
    //  console.log( i + '=====' + v );
    // });


    // 2 map 映射
    // 语法:      数组.map( fn )
    // 返回一个数组, 数组的每一个元素就是 map 函数中的 fn 的返回值
    // var arr = [ 1, 2, 3, 4 ];

    // 数学中: x -> x * x
    // var a = arr.map(function ( v, i ) {
    //  return v * v;
    // });


    // 3 filter 就是筛选
    // 语法:     数组.filter( function ( v, i ) { return true/false })
    // var arr = [ 1, 2, 3, 4, 5, 6 ];
    // var a = arr.filter( function ( v ) { return v % 2 === 1; });


    // 4 some 判断数组中至少有一个数据复合要求 就返回 true, 否则返回 false
    // var arr = [ '123', {}, function () {}, '123' ];
    // 判断数组中至少有一个数数字
    // var isTrue = arr.some( function ( v ) { return typeof v === 'number'; } );

    // 5 every 必须满足所有元素都复合要求才会返回 true
    // var arr = [ 1, 2, 3, 4, 5, '6' ];
    // var isTrue = arr.every( function ( v ) { return typeof v === 'number'; } );


    // 6 indexOf 在数组中查找元素, 如果含有该元素, 返回元素的需要( 索引 ), 否则返回 -1
    // var arr = [ 1, 2, 3, 4, 5 ];
    // var res = arr.indexOf( 4 );
    // console.log( res );

    // var arr = [ 1, 2, 3, 4, 5, 4, 5, 6 ];
    // var res = arr.indexOf( 4, 4 );
    // console.log( res );

    // 7 lastIndexOf 从右往左找
    // var arr = [ 1, 2, 3, 4, 5, 4, 5, 6 ];
    // var res = arr.lastIndexOf( 4 );
    // console.log( res );

动态创建函数


var Person=new Function('name','console.log(name)');
var p1=new Person('dd');
上一篇下一篇

猜你喜欢

热点阅读