JS基础知识-es6(6)-函数

函数

  1. 在传递函数参数时,ES5中想要创建带有参数默认值的函数往往会这样写,这样写能满足大部分的需要,但是当参数,比如age为0时,不会返回0而会返回20,因为0是一个假值:
function makeRequest(name, age, sex){
    // 当||左侧的值为假时,会返回右侧的值
    name = name || "emoji";
    age = age || 20;
    callback = callback || function(){};
}

为了更好兼容上面所述的异常情况,我们会使用typeof来检测参数的类型,这样写更安全了,但是代码就显的啰嗦繁杂了:

function makeRequest(name, age, sex){
    // 当||左侧的值为假时,会返回右侧的值
    name = (typeof name !== "undefined") || "emoji";
    age = (typeof age!== "undefined") || 20;
    callback = (typeof callback!== "undefined") || function(){};
}

ES6中支持给参数直接设置默认值,具体也可以看【解构】那篇文章:

// es6里会认为参数是必须的,设置了默认值可以规避不传值的报错,null会被认为是一个有效值
function makeRequest(name, age = 20, sex = "male"){
    // 当||左侧的值为假时,会返回右侧的值
    name = (typeof name !== "undefined") || "emoji";
    age = (typeof age!== "undefined") || 20;
    callback = (typeof callback!== "undefined") || function(){};
}

对arguments参数的影响:
在ES5的非严格模式下,arguments会跟着参数的重复赋值而更改,而在严格模式下,arguments会记录原始调用的值,不会随着具名参数的改变值而改变,这个和ES6是一样的:

// es5非严格模式下
function mixArgs(first, second){
    console.log(first, second);    // k i
    console.log(first === arguments[0]);    // true
    console.log(second === arguments[1]);    // true
    first = "e";
    second = "m";
    console.log(first, second);    // e m
    console.log(first === arguments[0]);    // true
    console.log(second === arguments[1]);    // true
}

mixArgs("k","i");

// es6无论是否严格模式下
function mixArgs(first, second = "b"){
    console.log(first, second);    //k i
    console.log(first === arguments[0]);    //true
    console.log(second === arguments[1]);    //true
    first = "e";
    second = "m";
    console.log(first, second);    // e m
    console.log(first === arguments[0]);    // false    arguments[0] = k
    console.log(second === arguments[1]);    // false    arguments[0] = i
}

mixArgs("k","i");

扩展运算符:

// 会将该数组分割为独立参数,并把他们传递进去
let values = [1,2,3,4,5];
console.log(Math.max(...values));    // 5

箭头函数:

需要从函数体内返回一个对象字面量,需要将该字面量包裹在圆括号内,表示括号内是一个字面量不是一个函数体

var getTempItem = id => ({ id: id, name: "Temp" });

//等于
var getTempItem = function(id){
    return {
        id: id,
        name: "Temp"
    };
}
// 箭头函数中没有自己的this,this都是最外层环境中的this,使用apply、call、bind都没有用
function foo() {
    return () => {
        return () => {
            return () => {
                return () =>{
                    console.log("id:", this.id);
                }
            }
        }
    }
}

let f = foo.call({id:1})
let t1 = f.call({id:2})()(); // id:1
let t2 = f().call({id:3})(); // id:1
let t3 = f()().call({id:4}); // id:1
  • 不适用箭头函数的场景
(1)const cat = {
        live:9,
        jumps:()=>{
            this.live++  // this在外层环境指向window
        }
    }
(2)button.addEventListener("click", () => {
        this.classList... // this指向window
    })

部署管道机制:前一个函数的输出是后一个函数的输入

const emoji = (...func) => val => func.reduce((a,b) => b(a), val);

emoji = function(...func) {
    return function(val) {
        return func.reduce(function(a,b){
            return b(a)
        }, val)
    }
}
const plus = a => a+1;
const mult = a => a*1;
mult(plus(5));

立即执行函数
我们知道这两种写法可以说是一样的:

// 写法1
(function(){/*函数体*/})()

// 写法2
(function(/*函数体*/){}())

在使用es6时,立即执行函数的参数调用不能包含在箭头函数定义括号内,即只能用写法1

尾调用:
尾调用指调用函数的语句是另一个函数的最后语句

function doSomething() {
    // 尾调用
    return doSomethingElse();
}

尾调用优化

function f(x) {
    return g(x);
}

// 三种情况都不属于尾调用
// 情况一
fuction f(x) {
    let y = g(x);
    return y;
}
// 情况二
function f(x) {
    return g(x)+1;
}
// 情况三
function f(x) {
    g(x)+1;
}

函数调用时会在内存中形成一个调用记录,称为“调用帧”,保存调用位置和内部变量信息。比如A函数中调用了B函数,那在A的调用帧上方会形成一个B的调用帧。等B运行结束,将结果返回A,B的调用帧才会消失。
尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置和内部变量信息不会再用到了。只要直接用内层函数的调用帧取代外层函数的调用帧。

function f() {
    let m = 1;
    let n = 2;
    return g(m+n);
}
f();
自动优化为:
function f () {
    return g(3);
}
最终为
g(3)

如果改为中间调用
function f() {
    let m = 1;
    let n = 2;
    let fn = g(m+n);
    return fn;
}
调用g(m+n)时就会保存m、n变量等信息

function addOne(a) {
    let one =  1;
    function inner(b) {
        return b + one;
    }
    return inner(a);
}

上面的函数不会进行尾调用优化,因为内层函数inner用到了外层函数addOne内部变量one;

字符串与正则:
字符查找:

var msg = "hello world!";
 
console.log(msg.startsWith("Hello"));    // true
console.log(msg.endsWith("!"));    // true
console.log(msg.includes("o"));    // true


console.log(msg.startsWith("o"));    // false
console.log(msg.startsWith("world!"));    // true
console.log(msg.startsWith("x"));    // false

// startsWith 和 includes 会从索引位置开始找
// endsWith 字符串长度-参数得到的值 开始查找  12 - 8 = 4
console.log(msg.startsWith("o", 4));    // true
console.log(msg.endsWith("o", 8));    // true
console.log(msg.includes("o", 8));    // false  

重复指定次数的新字符串(可以用来缩进和补全):

console.log("x".repeat(3));   // "xxx"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,556评论 0 5
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,382评论 0 1
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    陈老板_阅读 449评论 0 1
  • 三,字符串扩展 3.1 Unicode表示法 ES6 做出了改进,只要将码点放入大括号,就能正确解读该字符。有了这...
    eastbaby阅读 1,532评论 0 8
  • 碧绿溪水潺潺流, 火红枫叶随波游。 有缘千里来相会, 江南好个金色秋。 注:第一张照片来自一叶知秋,第二张来自人到...
    金赛月阅读 542评论 13 20