IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript语言精粹学习笔记之函数(二) -> 正文阅读

[JavaScript知识库]JavaScript语言精粹学习笔记之函数(二)

九、作用域

? ? ? ? 作用域控制着变量与参数的可见性及生命周期。对我们来说是一个重要的帮助,因为它减少了名称冲突,并且提供了自身内存管理。

var foo = function () {
    var a = 3, b = 5;
    
    var bar = function () {
        var b = 7, c = 11;

// 此时,a 为 3 , b 为 7 , c 为 11
        a += b + c;

// 此时,a 为 21, b 为 7 , c 为 11
    };
// 此时,a 为 3, b 为5 , c 未定义

    bar();

// 此时,a 为 21, b 为 5 
};

JS中,定义在函数中的参数和变量在函数外部是不可见的,而且在一个函数中的任何位置定义的变量在该函数中的任何地方都可见。

十、闭包

????????

// 创建一个名为 quo 的构造函数。
// 它构造出带有 get_status 方法和 status 私有属性的一个对象。

var quo = function (status) {
    return {
         get_status: function () {
            return status;
        }  
    };
};

// 构造一个 quo 实例

var myQuo = quo("amazed");

document.writeln(myQuo.get_status()); 

这个 quo 函数被设计成无须在前面加上 new 来使用,所以它名字也没有首字母大写。当我们调用 quo 时,它返回包含 get_status 方法的一个新对象。该对象的一个引用保存在myQuo中。即使 quo 已经返回了,但 get_status 方法仍然享有访问 quo 对象的 status 属性的特权。get_status 方法并不是访问该参数的一个拷贝,它访问的就是该参数本身。因为该函数可以访问它被创建时所处的上下文环境。这被称为闭包。

十一、回调

? ? ? ? 函数可以让不连续事件处理变得更容易。

request = qrepare_the_request();
response = send_request_stnchronously(request);
display(response);

这种方式的问题在于网络上的同步请求将会导致客户端进入假死状态。如果网络传输或服务器很慢,响应性的降低将是不可接受的。

我们有一个更好的方法:发起异步请求,提供一个当服务器的响应达到将被调用的回调函数。异步的函数立即返回,这样客户端就不会被阻塞。

request = qrepare_the_request();
send_request_asynchronously(request, function (response){
    display(response);   
});

我们传递了一个函数作为参数给 send_request_asynchronously 函数,它将在收到响应时被调用。

十二、模块

? ? ? ? 模块是一个提供接口却影藏状态与实现的函数或对象。

? ? ? ? 我们可以使用函数和闭包来构造模块。

? ? ? ? 模块模式利用了函数作用域和闭包来创建绑定对象与私有成员的关联。

? ? ? ? 模块模式:一个定义了私有变量和函数的函数,利用闭包创建可以访问私有变量和函数的特权函数,最后返回这个特权函数,或者把它们保存到一个可访问的地方。

模块模式也可以用来产生安全的对象:

var serial_maker = function () {
    // 返回一个用来产生唯一字符串的对象。
    // 唯一字符串由两部分组成: 前缀 + 系列号。
    // 该对象包含一个设置前缀的方法,一个设置序列号的方法。
    // 和一个产生唯一字符串的 gensym 方法

 var prefix = '';
 var seq = 0;
 return {
    set_prefix: function (p) {
         prefix = String(p);
    },
    set_seq: function (s) {
         seq = s;
    },
    gensym: function () {
            var result = prefix + seq;
            seq += 1;
            return result;
        }
    };
};

var seqer = serial_maker();
seqer.set_perfix('Q');
seqer.ser_seq (1000);
var unique = seqer.gensym();  // unique is "Q1000"

seqer 包含的方法都没有用到 this 或 that。?因此没有办法损害 seqer 。除非调用对应的方法,否则没法改变 prefix 或 seq 的值。 seqer 对象是可变的,所以它的方法可能会被替换掉,但替换后的方法依然不能访问私有成员。seqer 就是一组函数的集合,而且那些函数被授予特权,拥有使用或修改私有状态的能力。

如果把 seqer.gensym 作为一个值传递给第三方函数,那个函数能用它产生唯一字符串,但是不能通过它来改变 prefix 或 seq 的值。

十三、级联

? ? ? ? 有些方法没有返回值。如果我们让这些方法返回 this 而不是 undefined, 就可以启用级联。

? ? ? ? 在一个级联中我们可以在单独一条语句中依次调用同一个对象的很多方法。

????????一个启用级联的Ajax 类库可能允许我们以这样的形式去编码:

getElement('myBoxDiv').
    move(350, 150).
    width(100).
    height(100).
    color('red').
    border('10px outset').
    padding('4px').
    appendText("Please stand by").

on('mousedown', function (m) {
    this.startDrag(m, this.getNinth(m));
}).
on('mousemove', 'drag').
on('mouseup', 'stopDrag').
later(2000, function () {
    this.
        color('yellow').
        setHTML("what hath God wraught?").
        slide(400, 40, 200, 200);
}).
tip('This box is resizeable');

这里,getElement 函数产生一个对应于 id="myBoxDiv" 的DOM元素并提供了其他功能的对象。该方法允许我们移动元素,修改它的尺寸和样式,并添加行为。这些方法每一个都返回该对象,所以调用返回的结果可以被下一次调用所用。

级联可以产生出具备很强表现力的接口,它也能帮助控制那种构造试图一次做太多事情的接口的趋势。

十四、套用

? ? ? ? 函数也是值,套用 允许我们将函数与传递给它的参数相结合去产生出一个新的函数。

????????

var add1 = add.curry(1);
document,writeln(add1(6)); // 7

JS并没有 curry 方法,但我们可以通过给 Function.prototype 添加功能来实现:

Function.method('curry', function () {
    var args = arguments, that = this;
    return function () {
        return that.apply(null, args.concat(arguments));
    };
})

curry 使用Array 的concat 方法去连接两个参数数组。

这样做会有问题,arguments 数组并非一个真正的数组,所以它并没有 concat 方法。

要避开这个问题我们必须在两个 arguments 数组上都应用数组的 slice 方法。这样产生出拥有 concat 方法的常规数组。

Function.method('Curry', function () {
    var slice = Array.prototype.slice,
        args = slice.apply(arguments),
        that = this;
    return function () {
        return that.apply(null, args.concat(slice.apply(arguments)));
    };
});

十五、记忆

? ? ? ? ? 函数可以用对象先记住先前操作的结果,从而能避免无谓的运算,这种优化被称为记忆。

? ? ? ? JS的对象和数组要实现记忆是比较方便的:

var fibonacci = function (n) {
    return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

for (var i = 0; i <= 10; i += 1) {
    document.writeln('//' + i + ':' + fibonacci(i));
}

// 0:0
// 1:1
// 2:1
// 3:2
// 4:3
// 5:5
// 6:8
// 7:13
// 8:21
// 9:34
// 10:55

如果我们让该函数具备记忆功能,就可以减少它的运算量。

在一个名为memo的数组里保存我们的存储结果,存储结果可以隐藏才闭包中。当我们的函数被调用时,这个函数首先看是否已经知道存储结果,如果已经知道,就立即返回这个存储结果。

var fibonacci = function () {
    var memo = [0, 1];
    var fib = function (n) {
        var result = memo[n];
        if (typeof result !== 'number') {
            result = fib(n - 1) + fib(n - 2);
            memo[n] = result;
        }
        return result;
    };
    return fib;
}();

这个函数的返回同样的结果

还可以使用 memoizer 来定义 fibonacci 函数,提供其初始的 memo 数组和 fundamental 函数:

var fibonacci = memoizer([0, 1], function (shell, n) {
    return shell(n - 1) + shell(n - 2);
});

还能继续优化:

var fibonacci = memoizer([1, 1], function (shell, n) {
    return n * shell(n - 1);
});

要产生一个可以记忆的阶乘函数,我们只需要提供基本的阶乘公式即可。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 10:46:04  更:2021-07-14 10:48:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 20:53:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码