资讯专栏INFORMATION COLUMN

JavaScript 之 面向对象 [ Function类型 ]

AprilJ / 1616人阅读

摘要:类型描述在中的所有函数都是类型的对象定义函数的方式函数声明方式函数名函数体函数声明方式定义函数函数声明方式显示函数声明方式字面量方式函数名函数体字面量方式定义函数字面量方式显示字面量方式构造函数方式函数名参数,函数体函数的参数和函数体,都以

Function类型 描述

在JavaScript中的所有函数都是Function类型的对象

定义函数的方式 函数声明方式
function 函数名 () { 
    函数体 
}
/* 函数声明方式定义函数 */
function fun() {
    console.log( "函数声明方式..." );
}
fun();// 显示 函数声明方式...
字面量方式
var 函数名 = function () { 
    函数体 
}
/* 字面量方式定义函数 */
var fu = function () {
    console.log( "字面量方式..." );
}
fu();// 显示 字面量方式...
构造函数方式
var 函数名 = new Function( 参数,函数体 )

函数的参数和函数体,都以字符串形式填写在括号中,以逗号分隔

在使用构造函数创建一个Function类型的对象时,会得到一个函数

/* 构造函数方式定义函数 */
var fn = new Function( "can", "console.log( can )" );
fn("构造函数方式...");// 显示 构造函数方式...
判断定义的函数是否为Function类型
/* 函数声明方式 */
console.log( fun instanceof Function );// true
/* 字面量方式 */
console.log( fu instanceof Function );// true
/* 构造函数方式 */
console.log( fn instanceof Function );// true
apply()方法

表示用于调用指定函数

该方法接收两个参数

第一个 - this

第二个 - 一个数组

该数组用于存储指定函数的所有参数(实参)

/* 定义一个函数 */
function fun( can ) {
    console.log( can );
}
/* 根据函数语法正常调用函数 */
fun( "这是一个函数" );// 显示 这是一个函数

/*
    根据Function对象提供的apply()方法进行函数调用
     * 参数 this 可以先用 null 站位
 */
fun.apply( null, ["这还是一个函数"] );// 显示 这还是一个函数
call()方法

表示用于调用指定函数

该方法接收两个参数

第一个 - this

第二个 - 函数的参数
-需求多少参数,写多少参数,使用逗号分隔

/* 定义一个函数 */
function fun( can, shu ) {
    console.log( can + shu );
}
/* 根据函数语法正常调用函数 */
fun( "这是一个函数", "..." );// 显示 这是一个函数...

/*
    根据Function对象提供的call()方法进行函数调用
     * 参数 this 可以先用 null 站位
 */
fun.call( null, "这还是一个函数", "..." );// 显示 这还是一个函数...
bind()方法

表示创建一个新的函数(称为绑定函数)

该方法接收两个参数

第一个 - this

第二个 - 函数的参数

需求多少参数,写多少参数,使用逗号分隔

该方法的返回值 - 返回一个新的函数

返回的新函数 - 是对指定函数进行复制得到的

两个函数对函数体进行修改不会相互影响

/* 定义一个函数 */
function fun( can, shu ) {
    console.log( can + shu );
}
/* 根据函数语法正常调用函数 - 对参数进行修改 */
fun( "...", "这是一个函数" );// 显示 这是一个函数...   修改后显示 ...这是一个函数

/*
    根据Function对象提供的bind()方法进行函数调用
     * 参数 this 可以先用 null 站位
     * 两个函数之间不会有影响
 */
var fn = fun.bind( null, "这还是一个函数", "..." );
fn();// 显示 这还是一个函数...
重载

表示定义多个同名的函数,但每个函数可接收的参数不同

在调用时会进行判断,函数会根据形参可接收的个数去匹配传入实参个数相同的

注意

在JavaScript的函数中不存在重载

当函数同名时,最后一次定义的函数有效

/* 重载现象 */
function fn( a, b ){
    return a + b;
}
function fn( a, b, c ){
    return a + b + c;
}
function fn( a, b, c, d ){
    return a + b + c + d;
}
/* 重载的正常显示 */
fn( 1, 2 );// 显示 3
fn( 1, 2, 3 );// 显示 6
fn( 1, 2, 3, 4 );// 显示 10
/* JavaScript中的显示结果 */
console.log( fn( 1, 2 ) );// 显示 NaN
console.log( fn( 1, 2, 3 ) );// 显示 NaN
console.log( fn( 1, 2, 3, 4 ) );// 显示 10
arguments对象

该对象可以获取当前指定函数中的所以参数(实参),并存储到一个类数组中

该对象只能在函数中使用

length属性 - 表示函数中参数的个数

该方法可以模拟实现函数的重载

function fun(){
    /* 通过length属性获取函数参数的个数 */
    var add = arguments.length;
    /* 再通过条件语句进行判断 */
    switch ( add ) {
        /* 根据参数的个数进行显示 */
        case 2:
            /* 由于arguments对象将获取到的参数储存到一个类数组中,可以使用数组的方式进行提取 */
            return arguments[0] + arguments[1];
            break;
        case 3:
            return arguments[0] + arguments[1] + arguments[2];
            break;
        case 4:
            return arguments[0] + arguments[1] + arguments[2] + arguments[3];
            break;
    }
}
/* 可以模拟出重载的效果 */
console.log( fun( 1, 2 ) );// 显示 3
console.log( fun( 1, 2, 3 ) );// 显示 6
console.log( fun( 1, 2, 3, 4 ) );// 显示 10
递归

表示在一个函数中,调用自身

注意

如果不给递归设置一个出口,会出现类似于循环语句中的 死循环

解决

通过在递归的过程中不断改变数据值

在进行条件判断来设置出口

利用return语句的结束效果,结束递归

arguments对象的callee属性

该属性表示当前正在执行的函数

function fun() {
    console.log( "啊哈哈" );
    /*
        调用自身函数 - 实现递归
         * 会出现类似于循环语句中的 死循环
     */
    fun();
}
fun();

/* 可以设置一个循环出口 */
function fn( a ) {
    console.log( a );
    /* 通过条件判断来设置出口 */
    if ( a >= 10 ) {
        /* 利用return语句的结束效果,结束递归 */
        return;
    }
    /* 在递归的过程中不断改变数据值 */
    fn( a + 1 );
}
/* 传入一个数值用于条件判断 */
fn( 0 );

/* 如果将递归函数赋值个一个变量,再将递归函数清空释放,在去执行变量会出错 */
function fu( b ) {
    console.log( b );
    if ( b >= 10 ) {
        return;
    }
    /*
        新函数(s)在执行时,内部的函数体,依然是旧函数(fu)的
        当执行到改变数据值时,调用的目标依旧是旧函数(fu)而没有更改成新函数(s)
        所以会报错 - TypeError: fu is not a function

        可以通过arguments对象的callee属性去替换函数名
        arguments对象的callee属性
         * 该属性表示当前正在执行的函数
     */
    // fu( b + 1 );
    /* 修改后在执行就可正常显示 */
    arguments.callee( b + 1 );
}
fu( 0 );
/* 将递归函数赋值个一个变量 */
var s = fu;
/* 将递归函数清空释放 */
fu = null;
/* 使用函数方式执行变量 */
s( 0 );
/* 会报错 */
console.log( s );// 显示 fu is not a function
匿名函数

表示定义一个没有函数名的函数

匿名函数的用法

将匿名函数作为参数传递给其他函数

这种方法也可以叫做 回调函数

将匿名函数用于执行一次性任务

这种方法也可以叫做 自调函数

/* 创建一个匿名函数 */
function (){
    console.log( "啊哈哈" );
}
回调函数

表示一个函数做为参数传入到另一个函数中

/* 定义一个函数 - 该函数做为另一个函数的参数 */
var fn = function () {
    return 10;
}

/* 定义另一个函数 */
var fun = function ( f ) {
    /* 传进该函数体中的是一个函数,可以直接调用 */
    return f();
}
/* 当前函数的参数为另一个函数 */
var s = fun( fn );
console.log( s );// 显示 10
自调函数

表示在定义函数后自行调用

用法

第一种 - 两个小括号

第一个小括号 - 定义匿名函数

第二个小括号 - 调用

/* 第一种方法 */
(function(){
    console.log( "啊哈哈" );
})();

第二种 - 一个小括号中包含另一个小括号

第一个小括号 - 定义匿名函数

第二个小括号(被包含的) - 调用

/* 第二种方法 */
(function(){
    console.log( "呀吼吼" );
}());

第三种 - 叹号 + 小括号

叹号后写匿名函数

小括号 - 调用

/* 第三种方法 */
!function(){
    console.log( "哦哦哦" );
}();
作为值的函数

表示一个函数做为另一个函数的返回值

function fun() {
    var s = 10;
    return function () {
        return s;
    }
}
console.log( fun()() );// 显示 10
作用域链

表示函数作用域有权限访问除自身内部的函数作用域之外的其他作用域

并且会把次特性传递个自身内部的函数作用域

var a = 100;// 全局变量
function fun1(){
    var b = 200;// fun1函数作用域的局部变量
    // 内部函数
    function fun2(){
        var c = 300;// fun2函数作用域的局部变量
        // 内部函数
        function fun3(){
            var d = 400;// fun3函数作用域的局部变量
            // 调用变量
            console.log(a);// 100
            console.log(b);// 200
            console.log(c);// 300
            console.log(d);// 400
        }
        fun3();
        // 调用变量
        // console.log(a);// 100
        // console.log(b);// 200
        // console.log(c);// 300
        // console.log(d);// d is not defined
    }
    fun2();
    // 调用变量
    // console.log(a);// 100
    // console.log(b);// 200
    // console.log(c);// c is not defined
    // console.log(d);// d is not defined
}
fun1();
闭包理论

表示在全局作用域可以访问到函数作用域中的数据

作用域的逆向操作(个人理解)

/* 定义一个全局变量但不赋值 */
var s;
function fun(){
    var v = 100;
    /* 在函数作用域中对全局变量进行赋值 */
    s = function(){
        console.log(v);
    }
    s();
}
fun();// 显示函数体的内容 100
/* 访问全局变量会得到在函数作用域中数值 */
s();// 显示全局变量的值 100

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108222.html

相关文章

  • 面向对象JavaScript继承(一) 类式继承

    摘要:那你们肯定会问为什么共用,而没有共用呢,下面就给你解释,请看引用类型是共用的值类型是私用的。 引言 面向对象的编程语言都具继承这一机制,而 JavaScript 是基于原型(Prototype)面向对象程序设计,所以它的实现方式也是基于原型(Prototype)实现的. 继承的方式 类式继承 构造函数继承 组合继承 原型式继承 寄生式继承 寄生组合式继承 1.类式继承 //声明父...

    forsigner 评论0 收藏0
  • javascript面向对象总结

    摘要:之面向对象总结前言在中是没有类的概念的,所以它的对象与基于类的语言中的对象不同。一理解对象张三上面通过构造函数创建了一个对象,并为它添加了三个属性。 JavaScript之面向对象总结 前言:在ECMAScript中是没有类的概念的,所以它的对象与基于类的语言中的对象不同。ECMA-262把对象总结为:无序属性的集合,其属性包含基本值、对象或者函数。 一、理解对象 var person...

    taowen 评论0 收藏0
  • 温故知新javascript面向对象

    摘要:应该非常小心,避免出现不使用命令直接调用构造函数的情况。上面代码表示,使用属性,确定实例对象的构造函数是,而不是。当然,从继承链来看,只有一个父类,但是由于在的实例上,同时执行和的构造函数,所以它同时继承了这两个类的方法。 基本概念 类和实例是大多数面向对象编程语言的基本概念 类:类是对象的类型模板 实例:实例是根据类创建的对象但是,JavaScript语言的对象体系,不是基于类的,...

    赵连江 评论0 收藏0
  • JavaScript面向对象Function类型

    摘要:一类型概述与函数函数声明方式字面量方式判断函数是否为类型中所有函数都是类型的对象创建类型的对象是个函数函数名参数函数体由于函数的参数和函数体都是以字符串形式传递给以函数方式进行调用属性定义一个构造函数犬夜叉使用构造函数创建对象对象具有与构 JS(JavaScript) 一.Function类型概述1.Function与函数; // 函数声明方式 function fun(){ ...

    mingde 评论0 收藏0
  • JS面向对象的程序设计继承的实现 - 原型链

    摘要:简单回顾一下构造函数原型和实例对象之间的关系每个构造函数都有一个原型对象。找到生成构造函数的原型对象的构造函数,搜索其原型对象,找到了。 JS面向对象的程序设计之继承的实现 - 原型链 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《JavaS...

    zhaochunqi 评论0 收藏0
  • JS面向对象的程序设计继承-继承的实现-借用构造函数

    摘要:面向对象的程序设计之继承继承的实现借用构造函数前言最近在细读高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。继承了注意,这一段代码借调了超类型的构造函数。 JS面向对象的程序设计之继承-继承的实现-借用构造函数 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下...

    duan199226 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<