javaScript 函数

《JavaScript高级程序设计》读书笔记

箭头函数

let a = (x,y) => x*y

任何可以使用函数表达式的地方,都可以使用箭头函数。但不能使用 arguments、super 和 new.target,也不能用作构造函数,也没有prototype 属性

函数名

指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。

所有函数对象都会暴露一个只读的name属性,包含关于函数的信息。如果函数是一个获取函数、设置函数,或者使用bind() 实例化,那么标识符前面会加一个前缀

function foo() {}
let bar = function() {};
let baz = () => {};
console.log(foo.name); // foo
console.log(bar.name); // bar
console.log(baz.name); // baz
console.log((() => {}).name); //(空字符串)
console.log((new Function()).name); // anonymous
function foo() {}
console.log(foo.bind(null).name); // bound foo
let dog = {
    years: 1,
    get age() {
        return this.years;
    },
    set age(newAge) {
        this.years = newAge;
    }
}
let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age');
console.log(propertyDescriptor.get.name); // get age
console.log(propertyDescriptor.set.name); // set age

理解参数

在使用非箭头函数时,可以在内部访问 arguments对象,一个类数组对象。

function sayHi(name, message) {  
    console.log("Hello " + name + ", " + message); 
} 

function sayHi() {  
    console.log("Hello " + arguments[0] + ", " + arguments[1]); 
}

箭头函数中的参数

如果函数是使用箭头语法定义的,那么传给函数的参数将不能使用arguments关键字访问,而只能通过定义的命名参数访问。

注意:ECMAScript中所有参数都是按值传递的,不可能按引用传递参数,如果对象作为参数传递,那么传递的值就是这个对象的引用。

没有重载

如果定义了两个同名的函数,则后定义的会覆盖先定义的。

默认参数值

function makeKing(name='heihei') {
     return `king ${name} VIII`;
}
console.log(makeKing());//king heihei VIII
console.log(makeKing('huang'))//king huang VIII

默认参数作用域与暂时性死区

给多个参数定义默认值实际上跟使用 let 关键字顺序声明变量一样。所以后定义默认值的参数可以引用先定义的参数。前面定义的参数不能引用后面定义的,也不能引用函数体的作用域。

参数扩展与收集

// 之前
console.log(myFun.apply(null, values));

function myFun(..values) {
    return values.reduce((x, y) => x + y, 0);
}

函数声明与函数表达式

函数声明:在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。

函数表达式:必须等到代码执行到它那一行,才会在执行上下文生成函数定义。

函数内部

arguments

类数组对象,包含调用函数时传入的所有参数。只以function 关键字定义函数时才有。该对象还有一个属性 callee ,是指向arguments 对象所在函数的指针。

function factorial(num) {
    if(num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}

this

在标准函数中:this 引用的是把函数当成方法调用的上下文对象。

在箭头函数中:this 引用的是定义箭头函数的上下文。

caller

引用的是调用当前函数的函数,或者如果是在全局作用域中调用的则为null。

function outer () {
    inner()
}
function inner() {
    console.log(inner.caller);
}
outer()
// ƒ outer () {
//    inner()
// }

new.target

如果函数时正常调用的,则new.target 的值是 undefined;如果是使用new 关键字调用的,则new.target 将引用被调用的构造函数。

函数属性与方法

属性

  • length 保存函数定义的命名参数的个数
  • prototype 保存引用类型所有实例方法的地方

方法(设置调用函数时函数体内this 对象的值)

  • apply() 第一参数是this的值,第二个参数是Array的实例或arguments 对象。
  • call() 第一个参数是this的值,剩下的参数逐个传递。
  • bind() 创建一个新的函数实例

递归

一个函数通过名称调用自己

尾调用优化

尾调用优化条件

  • 代码在严格模式下执行(因外该状态下不能使用f.arguments 和 f.caller)
  • 外部函数的返回值是对尾调用函数的调用
  • 尾调用函数返回后不需要执行额外的逻辑
  • 尾调用函数不是引用外部函数作用域中自由变量的闭包

尾调用优化的代码

function fib(n){
    if(n < 2) {
        return n;
    }
    return fib(n - 1) + fib(n -2);
}
"use strict"
function fib(n) {
    return fibImpl(0, 1, n);
}
function fibImpl(a, b, n){
    if(n === 0){
        return a;
    }
    return fibImpl(b, a + b, n - 1);
}
fib(6);    // 8

 闭包

引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现。

立即调用的函数表达式

(function () {
    // 块级作用域
})();

私有变量

任何定义在函数或块中的变量,都可以认为是私有的,因为这个函数或块的外部无法访问器中的变量。私有变量包含函数参数、局部变量,以及函数内部定义的其他函数。

特权方法:是能够访问函数私有变量(及私有函数)的公有方法。

构造函数实现特权方法

function MyObject() {
    let private = 10;
    function privateFun() {
        return false;
    }
    // 特权方法
    this.publicMethod = function() {
        private++;
        return privateFun();
    };
};

let myobj = new MyObject();
myobj.publicMethod();

问题:必须通过构造函数来实现这种隔离,每个实例都会重新创建一遍方法。

静态私有变量实现

(function() {
    let private = 10;
    function privateFun() {
        return false;
    }

    MyObj = function() {};
    MyObj.prototype.publicMethod = function() {
        private++;
        return privateFun();
    };
})();

 利用原型更好地重用代码,只是每个实例没有了自己的私有变量。

模块模式

在单例对象基础上加以扩展,使其通过作用域链来关联私有变量和特权方法。

let singleton = function() {
    let private = 10;
    function privateFun() {
        return false;
    }

    return {
        public:true,
        publicMethod() {
            return privateFun();
        }
    }
}();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天巨兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值