JavaScript读书笔记语言精粹——函数(一)

函数

  JavaScript 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。

函数对象

  JavaScript中的函数就是对象,可以把函数赋值给变量,或者作为参数传递给其他函数,并且可以给它们设置属性,甚至调用它们的方法。函数与众不同的是它们可以被调用,且每个函数在创建时会附加两个隐藏属性,函数的上下文和实现函数行为的代码。
  每个函数对象在创建时会有一个 prototype 属性,它的值是一个拥有 constructor 属性且值为该函数的对象。

函数字面量

  函数对象通过函数字面量来创建:

// 创建一个名为 add 的变量,并用来把两个数字相加的函数赋值给它
var add = function (a, b) {
return a + b;
};
// 箭头函数
var add = (a, b) => return a + b;

函数字面量包括四个部分:

  • 关键词 function
  • 函数名,可有可无
  • 包含在括号内的参数,当然参数也是可有可无的,括号不能少。
  • 是一组包裹在大括号内的语句块,也就是函数要执行的具体代码,当然不写代码也没问题,{}是必不可少的。
(function () {});
 
var a = function() {}; 

var obj = {fn: function() {}};

上面三种函数的写法都是可以的。

调用

  调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明时定义的形式参数,每个函数还接收两个附加的参数: this 和 arguments。

有4种方式可以调用JavaScript函数:
  1. 作为方法调用
  2. 作为函数调用
  3. 作为构造函数调用pply
  4. 通过apply()和call()方法间接调用

方法调用模式

  方法调用是通过对象的属性来调用函数。方法调用的上下文是调用它的对象,可以通过this关键字引用该对象。

  • this是一个关键字,不是变量,也不是属性名。JavaScript不允许给this赋值。
// increment 方法接收一个可选的参数,如果参数不是数字,那么默认使用数字1
var myObject = {
    value: 0,
    increment: function (inc) {
                  this.value += typeof inc === 'number' ? inc : 1;
             }
};
myObject.increment(); 
console.log(myObject.value); // 1
myObject.increment(2); 
console.log(myObject.value); // 3

函数调用模式

  函数调用就是直接通过function对象来调用函数。

var sum = add (1, 2); // sum值为3

函数调用的上下文(this的值)是全局对象(window),即 this 被绑定到全局对象。

构造器调用模式

  如果函数或方法调用之前带有关键字new,它就是构造函数调用。

  • 构造函数调用和普通的函数调用以及方法调用在实参处理、调用上下文和返回值方面都有不同。
  • 构造函数调用会创建一个新的空对象,这个对象继承自构造函数的 prototype 属性。构造函数使用这个新创建的对象作为调用上下文,同时 this 会被绑定到新创建的对象。
var Quo = {
    fun: function() {
        console.log(this === Quo);
    }
};

Quo.fun();              // true,方法调用
var myQuo = new Quo.fun();  // false,构造函数调用

Apply调用模式和Call调用模式

  JavaScript中的函数也是对象,函数对象也可以包含方法。其中的2个方法call()和apply()可以用来间接地调用函数。

  • apply方法让我们构建一个参数数组传递给调用函数。它允许我们选择 this 的值。
  • apply和call的功能是一样的,只是传入的参数列表形式不同。
var array = [1, 2];
var sum = add.apply(null, array); // sum值为3
var sum1 = add.call(null, 2, 3); // sum1值为5

参数

  JavaScript中的函数定义并未指定函数形参的类型,函数调用也不会对传入的实参值做任何类型检查。实际上,JavaScript函数调用甚至不检查传入形参的个数。函数对于未传入的参数赋值为undefined,对于多余的参数忽略。

  当函数被调用时,会得到一个参数: arguments 数组。函数可以通过此参数访问所有它被调用时传递给它的参数列表,包括那些没有被分配给函数声明时定义的形式参数的多余参数。arguments 拥有一个 length 属性,但它没有任何数组的方法。

var sum = function ()  {
    var i, sum = 0;
    for (i = 0; i < arguments.length; i++){
        sum +=arguments[i];
    }
    return sum;
};
console.log(sum(1, 2, 4, 5)); // 12

返回

  当一个函数被调用时,它从第一个语句开始执行,并在遇到关闭函数体的 } 时结束。

  • return 语句可用来使函数提前返回。 当 return 执行时,函数立即返回而不再执行余下的语句。
  • 一个函数总是会返回一个值。如果没有指定返回值,则返回 undefined。
  • 如果函数调用时在前面加上了 new 前缀,且返回值不是一个对象,则返回 this (该新对象)。

异常

  JavaScript 提供一套异常处理机制。异常是干扰程序的正常流程的不寻常的事故。下面有几种异常类型:

  • 1.SyntaxError:解析代码时发生语法错误;
  • 2.ReferenceError:引用一个不存在的变量时发生错误;或将一个值分配给无法分配的对象,比如对函数的运行结果或者this赋值;
  • 3.RangeError:当一个值超出有效 范围时发生的错。(数组长度为负数 或Number对象的方法参数超出范围 或函数堆栈超过最大值);
  • 4.TypeError:变量或参数不是预期类型时发生的错误。比如对字符串等原始类型的值使用new命令,就会抛出这种错误;因为new命令的参数应该是一个构造函数;

扩充类型的功能

  JavaScript 允许给语言的基本类型扩充功能。 通过给Object.prototype添加方法, 可以让该方法对所有对象都可用。 这样的方式对函数、数组、字符串、数字、正则表达式和布尔值同样适用。

// 移除字符串首尾空白的方法
Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};
String.method('trim', function () {
    return this.replace(/^\s+|\s+$/g, '');
});
console.log('"' + "   neat  ".trim() + '"'); // "neat"
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

plustard1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值