《JavaScript权威指南(第六版)》知识点总结(三)

第8章 函数

        除了实参之外,每次调用还会拥有一个值——本次调用的上下文——这就是 this 关键字的值。

        如果函数挂载在一个对象上,作为对象的一个属性,就称它为对象的方法。当通过这个对象来调用函数时,该对象就是此次调用的上下文(context),也就是该函数的 this 的值。用于初始化一个新创建的对象的函数称为构造函数(constructor)。


        8.2.2 函数调用

        this 是一个关键字,不是变量,也不是属性名。JS的语法不允许给 this 赋值。this 没有作用域的限制。嵌套的函数不会从调用它的函数中继承 this。

        如果嵌套函数作为方法调用,其 this 的值指向调用它的对象。如果嵌套函数作为函数调用,其 this 值是全局对象。如果你想访问这个外部函数的 this 值,需要将 this 的值保存在一个变量里,这个变量和内部函数都同在一个作用域里。通常使用变量 self 来保存 this。


        8.3.2 可变长的实参列表:实参对象

        标识符arguments是指向实参对象的引用。实参对象是一个类数组对象,arguments 也包含一个 length 属性。

var max = function (/* number... */) {
  var m = Number.NEGATIVE_INFINITY;
  for (var i = 0; i < arguments.length; i++) {
    if (arguments[i] >= m) {
      m = arguments[i];
    }
  }
  return m;
};
        上述函数称为“不定实参函数”。实参个数不能为零。

        

        8.4 作为值的函数

var operators = {
  add: function (x, y) {
    return x + y;
  },
  substract: function (x, y) {
    return x - y;
  },
  multiply: function (x, y) {
    return x * y;
  },
  divide: function (x, y) {
    return x / y;
  },
  pow: Math.pow
};

var operate2 = function (operator, operand1, operand2) {
  if (typeof operators[operator] === 'function') {
    return operators[operator](operand1, operand2);
  }
  else {
    throw Error('Unknown operator!');
  }
}

var i = operate2('add', operate2('add', 2, 3), operate2('po', 3, 3));
console.log(i);

        自定义函数属性

        函数可以拥有属性,当函数需要一个“静态”变量来调用时保持某个值不变,最方便的方式就是给函数定义属性,而不是全局变量,定义全局变量会让命名空间变得更加杂乱无章。

var uniqueInteger = function () {
  return uniqueInteger.counter++;
};
uniqueInteger.counter = 0;

console.log(uniqueInteger());        //0
console.log(uniqueInteger());        //1
console.log(uniqueInteger());        //2
console.log(uniqueInteger());        //3
console.log(uniqueInteger());        //4
console.log(uniqueInteger.counter);  //5

        阶乘函数,把函数自身当做数组

function factorial (n) {
  if (isFinite(n) && n >= 0 && n === Math.round(n)) {
    if (!(n in factorial)) {
      factorial[n] = n * factorial(n - 1);
    }
    return factorial[n];
  }
  else {
    throw Error('Invalid number');
  }
};
factorial[0] = 1;
console.log(factorial(5));

        8.5 作为命名空间的函数

        假设你写了一段JS代码,这段代码要用在不同的网页中,和大多数代码一样,假定这段代码定义了一个用以存储中间计算结果的变量,但,当模块代码放到不同的程序中运行时,你无法得知这个变量是否已经创建了,如果已经存在这个变量,那么将会和代码发生冲突。解决办法是将代码放入一个函数内,然后调用这个函数。这样全局变量就变成了局部变量。

       

        8.6 闭包

var uniqueInteger = (function () {
  var counter = 0;
  return function () {
    return counter++;
  };
}());

console.log(uniqueInteger());    // 0
console.log(uniqueInteger());    // 1
console.log(uniqueInteger());    // 2
console.log(uniqueInteger());    // 3

// 计数器
var counter = function () {
  var n = 0;
  return {
    count: function () {
      return n++;
    },
    reset: function () {
      n = 0;
    }
  };
};

        可以将计数器的装饰合并为属性存取器方法 getter 和 setter。

function counter(n) {
  return {
    get count() {
      return n++;
    },
    set count(m) {
      if (m >= n) {
        n = m;
      }
      else {
        throw Error('count can only be set to a larger value');
      }
    };
  }
}

var c = counter(1000);
c.count            // 1000,count后面不能加括号
c.count            // 1001
c.count = 2000     // 无返回值
c.count            // 2000
c.count = 2000     // Error


function addPredictProperty(o, name, predict) {
  var value;
  o['get' + name] = function () {
    return value;
  };
  o['set' + name] = function (v) {
    if (predict && !predict(v)) {
      throw Error('set' + name + ': invalid value' + v);
    }
    else {
      value = v;
    }
  };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值