资讯专栏INFORMATION COLUMN

JS语言核心——“函数”

EsgynChina / 2374人阅读

摘要:比如,以对象的方法的形式调用函数并传入两个参数可以传入的参数可以是数组和类数组的。方法的该方法主要作用是将函数绑定至某个对象,方法返回一个新的函数,调用这个新的函数会把绑定的函数在对象中当做方法来调用。

参数

形参(parameter):函数中定义的变量

实参(argument):运行时的函数调用时传入的参数

上下文(context):通过对象来调用函数时,这个对象就是this就是上下文;

闭包(closure):函数嵌套在函数当中

1 函数调用的方式

有4种方法来调用JavaScript函数:

作为函数

作为方法

作为构造函数

通过call方法和apply方法间接调用

ES3 和非严格模式下的ES5中,调用上下文(this的值)是全局对象。在严格模式下,调用上下文则是undefined

1.1 函数调用

语法:

functionName()

window.name = "hello";
(function () {
    console.log(this); //window
})()

"use strict";
window.name = "hello";
(function () {
    console.log(this); //undefined
})()
1.2 方法调用

语法:

obj.functionName()

方法和this关键字是面向对象编程规范的核心

方法链

方法链:当方法的返回值是一个对象,这个对象还可以再调用它的方法。这个方法调用序列就是方法链;

1.3 构造函数调用

没有形参的构造函数调用都可以省略小括号

1.4 间接调用

call方法:使用它自有的实参列表作为函数的实参;

apply方法:要求以数组的形式传入参数;

2 函数的实参和形参 2.1 可选形参

当调用函数的时候传入的实参比函数声明时指定的形参个数要少,剩下的形参都将是undefined;所以在定义函数的时候应当给省略的参数赋一个默认值:

function pushArray(o, /* optional */ a) {
    if (a === undefined) a = [];
    // a = a || [];
    for (var property in o) a.push(property);
    return a;
}
var o = {
    name: "Oliver",
    age: 18
};
var a = ["friends"];
console.log(pushArray(o, a).toString()); //friends,name,age
2.2 实参对象

省略的实参都是undefined;多出的参数自动忽略

另外,可以通过arguments来获取多余的参数,arguments.length获得参数个数

不定实参函数(varargs function):接收任意个数的实参

不定实参函数的实参个数不能为零;

ES5之前,arguments[0]和x指代同一个值;

function pushArray(a) {   
    console.log(a); //Array
    arguments[0] = 10;
    console.log(a); //Array
    console.log(arguments[0]); //10
}
var a = ["friends"];
pushArray(a);
2.3 将对象属性用作实参

最好通过名值对的形式传入参数(传入的实参都写入一个多带带的对象之中,在调用的时候传入一个对象)

function outputString(obj) {
    var fname = obj.firstName,
        lname = obj.lastName,
        age = obj.age;
    console.log(`your fisrtName: ${fname}; lastName: ${lname}; age: ${age}`);
}
outputString({firstName: "Oliver", lastName: "Young", age: 18}); //your fisrtName: Oliver; lastName: Young; 
3 作为值的函数

函数也是值,可以将函数赋值给变量,存储在对象的属性和数组的元素中,作为参数传入另外一个函数等

函数是对象,可以定义自己的属性

log.conter = 10;
function log () {
    console.log(log.conter);
}
log(); //10

这样函数就不需要再定义一个全局变量

4作为命名空间的函数

将代码放入一个函数内,然后调用这个函数:

不同的写法:

function log (i) {
    console.log("hello" +i);
}
log(100);

(function log (i) {
    console.log("hello" + i);
}(100))

(function log (i) {
    console.log("hello" + i);
})(100)

小括号括起来避免JavaScript解释器解析为函数声明语句

5 闭包

词法作用域(lexical scoping):函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。

闭包:函数对象可以通过作用域相互关联起来,函数体内部的变量都可以保存在函数作用域内。

上面的log.conter属性就可以使用包括在闭包中:

var pro = (function() {
    var conter = 10;

    function log(argument) {
        console.log(conter++);
    }
    return log;
})();
pro(); //10
pro(); //11
pro(); //12

使用多个嵌套函数:

function counter () {
    var num = 0;
    return {
        count: function () {
            return num ++;
        },
        reset: function () {
            num = 0;
        }
    };
}
var newCounter = counter(); //这里是新的计数器,再赋值一个变量可以得到另外一个计数器,两者不受影响
console.log(newCounter.count()); //0
console.log(newCounter.count()); //1
console.log(newCounter.count()); //2
newCounter.reset();
console.log(newCounter.count()); //0
console.log(newCounter.count()); //1
console.log(newCounter.count()); //2
6 函数属性、方法和构造函数 6.1 length属性

函数的length返回的是形参的数量;函数内部arguments.length返回的是实参的数量

function add(x, y) {
    return arguments.length;
}
console.log(add.length); //2
console.log(add(1)); //1
6.2 prototype属性 6.3 call()和apply()方法

通过调用方法的形式来间接调用函数,call和apply的第一个实参是要调用函数的母对象,它是调用上下文。

比如,以对象o的方法的形式调用函数f()并传入两个参数:f.call(o, 1, 2)

apply可以传入的参数可以是数组和类数组的。

6.4 bind()方法

ES5的该方法主要作用是将函数绑定至某个对象,方法返回一个新的函数,调用这个新的函数会把绑定的函数在对象中当做方法来调用。

function add(y) {
    return this.x + y;
}
var o = {
    x: 100
};
var g = add.bind(o);
console.log(g(100)); //200

柯里化(currying):除了第一个实参外,传入bind的实参也会绑定至this;

function add(x, y) {
    return x + y;
}
var o = {

};
var g = add.bind(o, 100); //x是100
console.log(g(100)); //200 y是100

//上面的o对象可以去掉:
function add(x, y, z) {
    return x + y + z;
}
var g = add.bind(null, 100, 100, 100); //x是100 y是100 z是100
console.log(g()); //300

//又如:
function add(y, z) {
    return this.x + y + z;
}
var g = add.bind({x:100}, 100, 100); //{x是100} y是100 z是100
console.log(g()); //300
6.5 toString()方法 6.6 Function()构造函数

Function()构造函数所创建的函数并不是使用此法作用域:

var scope = "global";
function constructFunction () {
    var scope = "local";
    return new Function("return scope");
}
console.log(constructFunction()()); //global

var scope = "global";
function constructFunction () {
    var scope = "local";
    return function () {
        return scope
    };
}
console.log(constructFunction()()); //local
6.7 可调用的对象 7 函数式编程 7.1 使用函数处理数组

如要计算元素的平均值:

var arr = [1,2,3,4,5];
var total = 0;
for (var i = 0; i < arr.length; i++) {
    total += arr[i];
};
var result = total/arr.length;
console.log(result); //3

函数式编程风格:

var arr = [1,2,3,4,5];
function sum (a, b) {
    return a + b;
}
var total = arr.reduce(sum);
var result = total/arr.length;
console.log(result); //3
7.2 高阶函数

高阶函数(higher-order function):就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个新函数

function reverse(fun) {
    return function () {
        var result = fun.apply(this, arguments);
        return !result;
    }
}
var even = function (x) {
    return x % 2 === 0;
};

var odd = reverse(even);
console.log(odd(100)); //False
console.log(even(100)); //True
7.3 不完全函数 7.4 记忆

记忆(memorization):部分结果在函数式编程中被缓存起来,这种缓存技巧就是“记忆”

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

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

相关文章

  • 以vue依赖统计为核心的框架(函数),mve

    摘要:试用过几回,不满的地方,是一个框架,必须最好按它的方式来编码,与混编,使用文件。经过一翻网络搜索,勉强明白了依赖更新的实现方式,便尝试着自己去实现一个框架。如今有依赖更新这种技术的存在,我觉得找到了可能。 初接触vue,惊为天人,它的更新方式极为取巧,但也是人们保持路人的原因:似乎没有一个严格的数学证明保证按它的方式能精确更新到DOM。不过脑子里推演的似乎不会发生失败,而且每次界面都能...

    Carl 评论0 收藏0
  • task0002(一)- JavaScript数据类型及语言基础

    摘要:不过让流行起来的原因应该是是目前所有主流浏览器上唯一支持的脚本语言。经过测试,数字字符串布尔日期可以直接赋值,修改不会产生影响。再考虑对象类型为或者的情况。对于结果声明其类型。判断对象的类型是还是,结果类型更改。 转载自我的个人博客 欢迎大家批评指正 1. 第一个页面交互 这里最需要学习的老师的代码中,每一部分功能都由函数控制,没有创建一个全部变量。且最后有一个函数来控制执行代码...

    elarity 评论0 收藏0
  • 33 个 js 核心概念(二):数据类型

    摘要:举个例子在上面的例子可以看到,我们声明是一个数字,但是我们在之后将的值又改成了字符串和布尔值后面会讲这些类型。基本类型字符串表示一个字符串,如。因此,我们可以写一个函数,用来精确检测类型。 showImg(https://segmentfault.com/img/remote/1460000017309509?w=850&h=572); 定义 1. 什么是数据类型? 数据类型,就是将...

    QiShare 评论0 收藏0
  • JavaScript 简介

    摘要:简介原文链接简称是一种轻量级,解释型的编程语言,其函数是一等公民。标准的目标是让任何一种程序设计语言能操控使用任何一种标记语言编写出的任何一份文档。核心规定了如何映射基于的文档结构,以便简化对文档的任意部分的访问和操作。 JavaScript 简介 原文链接 JavaScript ( 简称:JS ) 是一种 轻量级,解释型 的编程语言,其函数是一等公民。众所周知,它是用于网页开发的脚...

    URLOS 评论0 收藏0
  • JS面向对象之一 【概述】

    摘要:更形象的我们还可以将面向对象理解为一种宗教信仰。这就导致面向对象教的程序员们在写时就很难受。所以为了满足信仰面向对象教的需求通过构造函数的形式模拟了伪类。这个套路的核心就是类那么里没有类所以其实是通过构造函数来模拟的伪类。 JS面向对象之一 【概述】 在学习JS的面向对象之前,我们应该先自问这样几个问题: 面向对象是什么意思? 学习面向对象的核心是什么? 为什么要学习面向对象?(它的...

    JohnLui 评论0 收藏0

发表评论

0条评论

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