美文网首页编程
JS的函数总结

JS的函数总结

作者: will2yang | 来源:发表于2017-08-30 22:31 被阅读0次
  • 函数在javascript里面是对象。每个函数在创建时会附加两个属性:函数的上下文和实现函数行为的代码。
  • 每个函数在创建的时候会有一个prototype属性,它的值是一个拥有constructor属性且值为该函数的对象。
  • 函数是对象,可以像值一样被使用。函数可以保存在变量、对象和数组中。函数可以当做参数传递给其他函数,函数也可以返回函数。因为函数是对象所以函数也可以拥有方法。
  • 函数的不同之处在于它可以被调用。

函数字面量

  1. 保留字 function
  2. 函数名,可以被省略。函数可以利用名字来递归调用自己。如果没有名字,则称之为匿名函数。
  3. 参数。
  4. 函数体,在函数被调用的时候执行。
    函数可以被定义在其他函数中,同事它就能访问把它嵌套在中的父函数的属性。通过函数字面量创建的函数对象包含一个链接到外部的上下文。这被称之为闭包。

调用

  • 调用一个函数时,会暂停当前函数的执行,传递控制权和参数给当前函数。
  • 除了传递的参数之外,每个函数还接受两个附加的参数:this和 arguments。
  • this的值取决于调用的模式。在js中有四种调用模式:
  1. 方法调用模式
    当一个函数被保存为一个对象属性时,我们称之为方法。当一个方法被调用时,this被绑定到该对象。如果表达式包含一个 . 的动作,那么它就是被当做一个方法来调用,方法调用模式的this指向对象。
var myObject = {
  value: 0,
  increment: function (inc) {
    this.value += typeof inc === 'number' ? inc : 1;
  }
};
myObject.increment(1);
document.wirteln(myObject.value);
myObject.increment(2);
document.wirteln(myObject.value);
  1. 函数调用模式
    当一个函数并非一个对象属性时,那么它就是被当做函数调用。
var sum = add(3, 4);

这时,this被绑定到全局对象上。如果语言设计正确,那么 当内部函数被调用时,this 应该任然绑定到外部函数的this变量。
但是

function a(){
  var b = function() {
     console.info(1231231, this);
  }
  b();
}
 a();// 输出windows this 被绑定到外部去了
// 解决方法
var myObject = {};
myObject.fn = function(){
  var that = this;
  var helper = function () {
    that.value = add(that.value, this.value);
  }
  helper();
}
//解决方法2 箭头函数的this指向 外部函数的this
var myObject = {};
myObject.fn = function() {
  var b = () =>{
     console.info(1231231, this);
  }
  b();
}
  1. 构造器调用模式
    构造器调用模式this将会指向new出来的对象。
var Quo = function (string){
  this.status = string;
}

Quo.prototype.get_status = function () {
  return this.status;
}

var myQuo = new Quo("confused");

document.writeln(myQuo.get_status());
  1. apply调用模式(还有call调用模式)
    构造一个参数数组传递给调用的函数,允许我们选择this的值。apply接受两个值 一个是this,另外一个是参数数组。
    这些模式在初始化关键参数this上存在差异。

参数

当函数被调用时,会有一个arguments数组。可以编写一个无需指定参数个数的函数。

var sum = function (){
  var i, sum = 0;
  for (i = 0; i < arguments.length; i += 1) {
    sum += arguments[i];
  }
  return sum;
}

arguments并不是一个数组 只是一个类似数组的对象。只有length属性,没有其他数组方法。

返回

一个函数总会有一个返回值,如果没有那么返回undefined。
如果调用时加了new,且返回值不是对象那么返回新对象即this。

异常

var add = function (a, b) {
  if (typeof a !== 'number' || typeof b !== 'number' ) {
    throw{
      name: 'TypeError',
      message: 'add needs number'
    };
  }

  return a + b;
}

var try_it = function () {
  try {
    add("seven");
  } catch(e) {
    document.writeln(e.name + ':' + e.message);
  }
}

扩充类型的功能

Function.prototype.method = function(name, func){
  this.prototype[name] = func;
  return this;
}

Number.method('integer', function(){
  return Math[this < 0? 'ceil' : 'floor'](this);
})

document.writeln((-10/3).integer());

String.method('trim', function () {
  return this.replace(/^\s+|\s+$/g, '');
})
document.writeln('"' + "  neat  ".trim() + '"');

符合条件时才添加方法

Function.prototype.method = function (name, func) {
  if (!this.prototype[name]) {
    this.prototype[name] = func;
  }
  return this;
}

递归 todo

作用域

var foo = function () {
  var a = 3, b = 5;

  var bar = function () {
    var b = 7, c = 11;
    a += b + c;
  };
  //a为3 b 为5
  bar();
  //a为21 b 为5
}

了解js奇怪的作用域。

闭包

函数可以访问它被创建时所处的上下文环境。这杯称之为闭包。

var fade = function(node) {
  var level = 1;
  var step = function () {
    var hex = level.toString(16);
    node.style.backgroundColor = '#FFFF' + hex + hex;
    console.info('#FFFF' + hex + hex);
    if(level < 15){
      level += 1;
      setTimeout(step, 1000);
    }
  }
  setTimeout(step, 1000);
}

fade(document.body);

只要step还需要父函数里的变量那么这个变量就不会释放。

回调

模块

我们可以使用函数和闭包来构造模块,模块是一个提供接口却隐藏状态与实现的函数或对象。通过函数产生模块,我们可以摒弃全局变量的使用,从而缓解js的糟糕特性。
定义一个方法替换寻找字符串中的HTML实体并把他们替换为对应的字符。

String.method('deentityify', function() {

//需要替换的字符实体保存在全局变量里太污染,保留在函数里每次需要求值,但是保留在闭包里很理想
  var entity = {
    quot: '"',
    lt: '<',
    gt: '>'
  };

  return function() {
    return this.replace(/&([^&;]+);/g,
      function (a, b) {
        var r = entity[b];
        return typeof r === 'string' ? r : a;
      }
  }
})

模块的一般形式就是利用闭包创建可以访问的私有变量和函数的特权函数,最后返回这个特权函数,或者把他们保存到一个可以访问到的地方。
使用模块摒弃了全局变量的使用。它促进了信息隐藏和其他优秀的设计实践。对于应用的封装或者构建其他单例对象,模块模式非常有效。
模块也可以产生安全的对象,假定我们要构造一个用来生产序列的对象。

var serial_maker = function () {
  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_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym();

级联

一些方法没有返回值,一些这只或修改对象的某个状态却不返回任何值得方法就是经典的例子。如果我们让这些方法返回this而不是undefinded那么就可以启动级联。


getElement('myBoxDiv')
  .move(350, 150)
  .width(100)
  .height(100)
  .color('red')

柯里化

函数也是值,从而我们可以利用有趣的方式操作函数值。柯里化允许我们把函数与传递给它的参数相结合,产生出一个新的函数。

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)));
  }
})

记忆 todo

函数可以将先前操作的结果记录在某个对象里,从而避免无所谓的重复运算。

相关文章

  • 【基础系列】JS使用技巧专题

    JS使用技巧专题 1开发技巧 1.1函数使用 1.1.1函数声明方式 JS函数的写法总结 http://blog....

  • js 随机函数

    在写js中,我们经常遇见 js 随机函数,总结一下最近写验证码的时候 用到过的js 随机函数 Math.rando...

  • 前端面试必问总结

    前言 本文用于总结个人在工作期间总结的一些面试题 题目列表 js的函数声明 js的原型链 js的闭包 js的Pro...

  • js函数总结

    一声明:函数声明,存在声明提升函数表达式 二内部对象:每个函数都有this,argments两个对象。apply ...

  • JS函数总结

    声明:本文是学习阮一峰的JS标准参考教程,的学习笔记,并不是自己原创。 1. 函数声明(Function Decl...

  • JS的函数总结

    函数在javascript里面是对象。每个函数在创建时会附加两个属性:函数的上下文和实现函数行为的代码。 每个函数...

  • 函数表达式

    以下内容总结自《JS高级程序设计》第三版 什么是函数表达式? 函数表达式,是JS中定义函数的一种方式。在JS中,共...

  • 微信小程序遇坑——多次点击页面重复加载及数据重复提交

    目前总结解决方法:同时需要设置模块的函数,函数都可放置在util.js中去。 首先: 一、在util.js中放入如...

  • JS申明函数的方法和函数中this的指向

    最近在学js,了解到js函数的重要性,因此做一个总结。 1.js函数申明方式 1.直接申明 2.定义变量来申明 注...

  • js闭包中的this(匿名函数中的this指向的是windows

    目录 一、总结 二、js闭包中的this 回到顶部 一、总结 1、普通函数中的this指向的是对象,匿名函数中的t...

网友评论

    本文标题:JS的函数总结

    本文链接:https://www.haomeiwen.com/subject/rivpdxtx.html