JavaScript面向对象编程——Function范例

Function范例

Function与函数

函数它只定义一次,但能够被实行或挪用屡次 。
Function范例是JavaScript供应的援用范例之一,经由过程Function范例建立Function对象。
在JavaScript中,函数也是以对象的情势存在的。每一个函数都是一个Function对象。函数名,实质就是一个变量名,是指向某个Function对象的援用。

// 1.函数声明体式格局
function fun(){
    console.log('this is function');
}
// 2.字面量体式格局
var fn = function(){
    console.log('this is function too');
}
// 推断函数是不是为Function范例的
console.log(fun instanceof Function);// true
console.log(fn instanceof Function);// true
// JavaScript中一切的函数都是Function范例的对象

/*
    3.建立Function范例的对象 -> 是一个函数
      var 函数名 = new Function(参数,函数体);
      * 因为函数的参数和函数体都是以字符串情势通报给Function的
  */
var f = new Function('a','console.log(a)');
f(100);// 以函数体式格局举行挪用

Function范例

组织函数

在JavaScript中,函数除了能够经由过程函数定义语句或字面量表达式两种体式格局定义以外,还能够经由过程Function范例举行定义。(注重:经由过程Function范例定义函数的效力远不如经由过程函数定义语句或字面量表达式两种体式格局定义。现在,定义函数具有三种体式格局,这三种体式格局之间存在肯定的差异。)

// 1.Object与Function都是本身的范例
console.log(Object instanceof Object);// true
console.log(Function instanceof Function);// true
// 2.Object本身是组织函数,而组织函数也是函数,是函数都是Function范例
console.log(Object instanceof Function);// true
// 3.Function是援用范例,用于建立对象,是对象都是Object范例
console.log(Function instanceof Object);// true
// 变量的声明提早
console.log(v);// undefined
var v = 100;
// 假如运用函数声明体式格局定义函数时 -> 函数的声明提早
fun();
function fun(){
    console.log('this is function');
}

apply()要领

Function的apply()要领用于挪用一个函数,而且吸收指定的this值,以及一个数组作为参数。
语法结构:
1.thisArg参数:可选项,在func函数运行时运用this值。
2.argsArray参数:可选项,一个数组或许类数组对象,个中你谁人的数组元素将作为零丁的参数传给func函数。也能够运用argments对象作为参数
3.返回值:挪用该函数的返回效果。

// 定义函数
function fun(value){
    console.log('this is ' + value);
}
// 函数的挪用体式格局
fun('function');// 语法结构:函数称号()

    apply(thisArg,argArray)要领 -> 用于挪用一个指定函数
     参数
       thisArg - this
       argArray - 数组,作为参数(实参)的列表
  
fun.apply(null, ['function']);

call()要领

Function的call()要领用于挪用一个函数,而且吸收指定的this值作为参数,以及参数列表。
语法结构:
1.thisArg参数:在func函数运行时运用的this值。
2.arg1,arg2,…参数:指定的参数列表。
3.返回值:挪用该函数的返回效果。
apply()与call()异常类似,差别之处在于供应参数的体式格局。

bind()要领

Function的bind()要领用于建立一个新的函数(称之为绑定函数),而且吸收指定的this值作为参数,以及参数列表。

// 定义函数
function fun(value){
    console.log('this is ' + value);
}
/*
    bind(thisArg, arg1, arg2, ...)要领
    * 作用 - 用于建立一个新函数(称为绑定函数)
    * 参数
      * thisArg - this
       arg1, arg2, ... - 示意参数列表
    * 返回值 - 返回新的函数
 */
// var f = fun.bind();// 相对于从指定函数复制一份出来
// console.log(f);
// f();

fun('周芷若');// this is 周芷若

var f = fun.bind(null, '张无忌');
f();// this is 张无忌

没有重载

在其他开辟言语中,函数具有一种特征,叫做重载。所谓的重载,就是定义多个同名的函数,但每一个函数吸收的参数的个数差别,顺序会依据挪用是通报的实参个数举行推断,详细挪用的是哪一个函数。

// 定义函数
function fun(value){
    console.log('this is ' + value);
}

    bind(thisArg, arg1, arg2, ...)要领
     作用 - 用于建立一个新函数(称为绑定函数)
     参数
       thisArg - this
       arg1, arg2, ... - 示意参数列表
     返回值 - 返回新的函数
 
 var f = fun.bind();// 相对于从指定函数复制一份出来
 console.log(f);
 f();

fun('周芷若');// this is 周芷若

var f = fun.bind(null, '张无忌');
f();// this is 张无忌

但在JavaScript中函数时没有重载征象的。也就是说,假如同时定义多个同名函数,只要末了一个定义的函数时有用的。
不过,JavaScript供应的arguments对象,该对象能够模仿函数重载的征象。arguments对象是函数内部的当地变量;arguments已不再是函数的属性了。
arguments对象能够猎取函数的一切参数,但arguments对象并非一个数组,而是一个类数组对象(没有数组特有的要领)。

递归

在一个函数体内,假如想挪用本身函数的话,有两种体式格局;
1.经由过程运用本身函数完成
2.经由过程运用arguments对象的callee属性完成。
挪用本身的函数被称之为递归函数。在某种意义上,递归近似于轮回。两者都反复实行雷同的代码,而且两者都须要一个停止前提以防止无穷轮回或许无穷递归。

/* 函数的递归 -> 就是在指定函数的函数体中挪用本身函数
function fun(){
    // 当前函数的逻辑内容
    console.log('this is function');
    // 挪用本身函数 -> 完成递归
    fun();
}
fun();
*/

function fn(v){
    console.log(v);
    if (v >= 10) {
        return;
    }
    // fn(v + 1);
    arguments.callee(v + 1);
}
fn(0);//致使失足

var f = fn;
fn = null;
f(0);
// console.log(f);

特别函数

匿名函数

JavaScript能够将函数作为数据运用。作为函数本体,他就像一般的数据一样,不肯定要有名字。默许名字的函数被称之为匿名函数。
匿名函数的两种用法:
1.能够将匿名函数作为从参数通报给其他函数。如许,吸收函数就可以应用所通报的函数来完成某些事请。
2.能够定义某个匿名函数来实行某些一次性使命。

 JavaScript语法中,定义函数必需定义函数称号 -> 匿名函数
function (){
    console.log('this is function');
}


    匿名函数的作用:
    1.将匿名函数作为参数通报给其他函数 -> 回调函数
    2.将匿名函数用于实行一次性使命 -> 自调函数
 

回调函数

当一个函数作为参数通报给另一个函数时,作为参数的函数被称之为回调函数。

// 作为另一个函数(fn)的参数的函数(one) -> 回调函数
var one = function(){
    return 1;
}

function fn(v){
    return v();
}
// one函数仅是作为fn函数的参数涌现 -> 并非挪用
// var result = fn(one);
/*
    以上代码等价于以下代码
    以下代码中作为参数的函数 -> 匿名回调函数
  */
var result = fn(function(){return 1;});

console.log(result);// 1

自调函数

所谓自调函数就是在定义函数后自行挪用。
1.第一对括号的作用,安排的是一个匿名函数。匿名函数吸收一个参数
2.第二个对括号的作用,是‘马上挪用’。在挪用时,向匿名函数通报参数内内容。
自调函数只需将匿名函数的定义放进一对括号中,然后表面在跟一个对括号。


    自调函数 - 定义即挪用的函数
     第一个小括号 - 用于定义函数
     第二个小括号 - 用于挪用函数
 
// 全局作用域 - 生命周期:JavaScript文件从实行到实行终了
(function(value){
    // 函数作用域 - 生命周期:从函数挪用到挪用终了
    console.log('this is ' + value);
})('function');
// 表达式语法
(function(value){
    // 函数作用域 - 生命周期:从函数挪用到挪用终了
    console.log('this is ' + value);
}('function'));

!function(value){
    // 函数作用域 - 生命周期:从函数挪用到挪用终了
    console.log('this is ' + value);
}('function');

+function(value){
    // 函数作用域 - 生命周期:从函数挪用到挪用终了
    console.log('this is ' + value);
}('function');

作为值的函数

将一个函数作为另一个函数的效果举行返回,作为效果返回的函数称之为作为置的函数。

var one = function(){
    return 100;
}
// 作为值的函数 -> 内部函数的一种特别用法
function fun(){
    var v = 100;
    // 内部函数
    return function(){
        return v;
    };
}

var result = fun();
// console.log(result);// one函数
// console.log(result());// 100

console.log(fun()());

闭包

作用域链

许多开辟言语中都具有块级作用域,但ECMAScript5版本中并没有跨级作用域,这经常会致使明白上的疑心。
虽然ECMAScript5版本没有块级作用域,但具有函数作用域。在某个函数内部定义的变量的作用域就是该函数作用域。
每一段JavaScript代码(全局代码或函数)都有一个与之关联的作用域。这个作用域链是一个对象列表或链表,这组最想定义了这段代码“作用域中”的变量。

var a = 10;// 全局变量
function fun(){
    var b = 100;// fun函数作用域的局部变量
    // 内部函数
    function fn(){
        var c = 200;// fn函数作用域的局部变量
        // 内部函数
        function f(){
            var d = 300;// f函数作用域的规划变量
            // 挪用变量
            console.log(a);// 10
            console.log(b);// 100
            console.log(c);// 200
            console.log(d);// 300
        }
        f();
        // 挪用变量
        // console.log(a);// 10
        // console.log(b);// 100
        // console.log(c);// 200
        // console.log(d);// d is not defined
    }
    fn();
    // 挪用变量
    // console.log(a);// 10
    // console.log(b);// 100
    // console.log(c);// c is not defined
    // console.log(d);// d is not defined
}
fun();

闭包是什么

JavaScript许可函数嵌套,而且内部函数能够接见定义在外部函数中的一切变量和函数,以及外部函数能接见的一切变量和函数。然则,外部函数却不能接见定义在内部函数中的变量和函数。
当内部函数以某种体式格局呗任何一个外部函数作用域接见时,一个闭包就产生了。
闭包就是词法示意包含没必要盘算的变量的函数,也就是说,该函数能运用函数外定义的变量。

var n;// 定义变量,但不初始化值
function fun(){// 函数作用域
    var v = 100;
    // 举行初始化值 -> 一个函数
    n = function(){
        console.log(v);
    }
    // n();
}
fun();

n();// 100

闭包的特性和作用
特性:
1.局部变量:在函数中定义有同享意义的局部变量。
2.内部函数:在函数(f)中声明内嵌函数,内嵌函数(g)对函数(f)中的局部变量举行接见。
3.外部运用:函数(f)向外返回此内嵌函数(g),外部能够经由过程此内嵌函数持有并接见声明在函数(f)中的局部变量,而此变量在外部是经由过程其他门路无法接见的。
作用
1.供应可同享的局部变量。
2.庇护同享的局部变量。供应特地的读写变量的函数。
3.防止全局污染。

    原文作者:武文佳
    原文地址: https://segmentfault.com/a/1190000016026840
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞