第三天 函数

1、函数挪用,要领挪用及组织函数挪用之间的差别

这部份比较简单,直接看代码吧:

function hello() {
    console.log('Hello, World');
}
// 函数的挪用
hello(); // Hello, World

var obj = {
    welcome: function() {
        console.log('Hello, ' + this.name);
    },
    name: 'dreamapple'
};
// 要领挪用
obj.welcome(); // Hello, dreamapple

function Student(name, age) {
    this.name = name;
    this.age = age;
    console.log('My name is ' + this.name + ', and my age is ' + this.age);
}
// 组织函数的挪用
var s = new Student('dreamapple', 23); // My name is dreamapple, and my age is 23

注重

  • 函数挪用将全局对象(处于严厉形式下则为undefined)作为接收者。平常很少运用函数挪用语法来挪用要领。

  • 要领挪用将被查找要领属性的对象作为挪用接收者。

  • 组织函数须要经由过程new运算符挪用,并发生一个新的对象作为其接收者。

2、控制高阶函数的运用

JavaScript中将函数作为参数或返回值的函数被称为高阶函数,下面引见一些经常使用的JS内置高阶函数

Array.sort

  • sort 函数须要运用者传入一个排序划定规矩,以下:

var arr = [1, 9, 3, 4, 2];
// 返回一个排序的效果
var arr1 = arr.sort(function(x, y) {return x>y?1:-1});
console.log(arr1); // [ 1, 2, 3, 4, 9 ]

Array.map

  • 运用 map 可以简化对数组的遍历操纵,其参数为一个函数,以下:

var arr = [1, 9, 3, 4, 2];
var arr2 = arr.map(function(x) {
    return x * 2 + 1;
});
console.log(arr2); // [ 3, 5, 7, 9, 19 ]

var arr3 = [1.4,1.5,3.2,3.6]
arr3 = arr3.map(Math.ceil)
console.log(arr3)//[2, 2, 4, 4]

call

  • 运用call要领自定义接收者来挪用函数。

  • 运用call要领可以挪用在给定的对象中不存在的要领。

  • 运用call要领定义高阶函数许可运用者给回掉函数指定接收者。

// 运用call
var obj1 = {
    sayHello: function(msg) {
        console.log('Hello,' + this.name + ' ' + msg);
    },
    name: 'dreamapple'
};

var obj2 = {
    name: 'dream'
};


// 第一个参数是要领的挪用者,盈余的参数就是原函数的参数
obj1.sayHello.call(obj2, 'haha'); // Hello,dream haha

// 高阶函数运用call
function compute(arg) {
    var sum = 0;
    for(var i = 0; i < arg.length; i++) {
        sum += arg[i];
    }
    return sum;
}

function highFunc() {
    return compute.call(null, arguments);
}

console.log(highFunc(1, 2, 3, 4, 5)); // 15

var arr = [1,2,3,4,5];
console.log(highFunc(arr)); // 毛病

arguments 的运用

JavaScript给每一个函数都隐式地供应了一个部分变量 arguments

  • 运用隐式的arguments对象完成可变参数的函数。

  • 斟酌对可变参数的函数供应一个分外的牢固元数的版本,从而使运用者无需借助apply要领。

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

console.log(multArgsFunc(1, 2, 3, 4)); // 10
console.log(multArgsFunc(1, 2, 3, 4, 5)); // 15

注重:

  1. 永远不要直接修正arguments对象

  2. arguments 是一个对象,不是数组,可以经由过程 [].slice.call(arguments) 将其复制到一个真正的数组中再举行操纵

  3. 当运用 arguments 时小心函数嵌套,一般应当运用变量保留 arguments 的援用

apply

  • 运用apply要领指定一个可计算的的参数数组来挪用可变参数的函数。

  • 运用apply要领的第一个参数给可变参数的的要领供应一个接收者。

注重:
apply的用法和call相似,唯一的区分在于call不接收参数数组,而apply可以接收参数数组,纵然参数个数牢固只要一个或两个,运用apply时也须要将参数用 [] 包裹起来,例子以下:

 // 运用apply
function compute() {
    var sum = 0;
    for(var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

function wrapper(arr) {
    return compute.apply(null, arr); // 给compute函数通报多个参数
}

var arr = [1, 2, 3, 4, 5];
console.log(wrapper(arr)); // 15

bind

运用 bind 来提取具有肯定接收者的要领

  • 要注重, 提取一个要领不会将要领的接收者绑定到该要领的对象上。

  • 当给高阶函数通报对象要领时,运用匿名函数在恰当的接收者上挪用该要领。

  • 运用bind要领建立绑定到恰当接收者的函数。

  • 挪用 f.bind(someObject) 会发生一个新的函数对象。在这个新的函数对象中,this被永远绑定到了bind的第一个参数上面,不管后期这个新的函数被怎样运用。

示例以下:

function f(){
    return this.a;
}

var g = f.bind({a:"jack"});
console.log(g()); // jack

var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, jack


function Person(name){
 this.nickname = name;
 this.distractedGreeting = function() {
 
   setTimeout(function(){
     console.log("Hello, my name is " + this.nickname);
   }, 500);
 }
}
 
var alice = new Person('Alice');
alice.distractedGreeting();
//Hello, my name is undefined


function Person(name){
  this.nickname = name;
  this.distractedGreeting = function() {
    setTimeout(function(){
      console.log("Hello, my name is " + this.nickname);
    }.bind(this), 500); // <-- this line!
  }
}
 
var alice = new Person('Alice');
alice.distractedGreeting();
// after 500ms logs "Hello, my name is Alice"


this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};
 
module.getX(); // 81
 
var getX = module.getX;
getX(); // 9, 因为在这个例子中,"this"指向全局对象
 
// 建立一个'this'绑定到module的函数
var boundGetX = getX.bind(module);
boundGetX(); // 81

3、不要信任函数的对象的toString要领

  • 当挪用函数的toString要领时,并没有请求JavaScript引擎可以精确地获取到函数的源代码。

  • 因为在差别的引擎下挪用toString要领的效果能够差别,所以相对不要信任函数源代码的细致细节。

  • toString要领的实行效果并不会暴露存储在闭包中的部分变量值。

  • 一般情况下,应当防止运用函数对象的toString要领。

(function(x) {
    return x + 1;
}).toString();
/*
 * 输出效果
 * function (x) {
 *  return x + 1;
 * }
 * */

(function(x) {
    return x + 1;
}).bind(10).toString();
/*
 * 因为运用了宿主环境的内置库供应的函数,JavaScript引擎会视图供应当函数的源代码的实在示意
 * 而宿主环境中bind一般是其他言语(如C++)供应的是一个编译后的函数
 * function (x) { [native code] }
 * */

(function(x) {
    return function(y) {
        return x + y;
    }
}).bind(20).toString();
/*
 * function () { [native code] }
 * */
    原文作者:Jaywii
    原文地址: https://segmentfault.com/a/1190000007545720
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞