资讯专栏INFORMATION COLUMN

第三天 函数

songze / 681人阅读

摘要:构造函数需要通过运算符调用并产生一个新的对象作为其接受者。使用方法定义高阶函数允许使用者给回掉函数指定接收者。当给高阶函数传递对象方法时使用匿名函数在适当的接受者上调用该方法。通常情况下应该避免使用函数对象的方法。

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

注意:

永远不要直接修改arguments对象

arguments 是一个对象,不是数组,可以通过 [].slice.call(arguments) 将其复制到一个真正的数组中再进行操作

当使用 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] }
 * */

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80971.html

相关文章

  • vue三天

    摘要:最近是让给我折腾的做梦都梦见写。。。留言可按回复已留暂无留言删除该写了返回失败内容时间戳顶次数踩次数失败 最近是让json给我折腾的做梦都梦见写json???。。。阿欧~琢磨着我算是明白了吧~我说说看,你们听听看~有不同观点可以给我留言哟~ 接口就是由前后端协定好异步交互数据的方式,使用ajax的形式或者jsonp的形式进行传递,数据格式可以是字符串或者json 这次用到的知识点: v...

    NickZhou 评论0 收藏0
  • vue三天

    摘要:最近是让给我折腾的做梦都梦见写。。。留言可按回复已留暂无留言删除该写了返回失败内容时间戳顶次数踩次数失败 最近是让json给我折腾的做梦都梦见写json???。。。阿欧~琢磨着我算是明白了吧~我说说看,你们听听看~有不同观点可以给我留言哟~ 接口就是由前后端协定好异步交互数据的方式,使用ajax的形式或者jsonp的形式进行传递,数据格式可以是字符串或者json 这次用到的知识点: v...

    shiyang6017 评论0 收藏0
  • 九天学会Java,三天,选择结构

    摘要:选择结构变量和数据类型,赋值和输出算术运算选择结构循环结构函数定义,函数调用变量作用域栈,程序运行的基石面向对象异常处理语言提供的公用包上一节介绍了的算术运算,如加减乘除等,的运算规则跟四则运算一样。 选择结构 变量和数据类型,赋值和输出 算术运算 选择结构 = 60) { System.out.println(You have passed the exam...

    Java_oldboy 评论0 收藏0
  • 三天

    摘要:今天遇到了什么问题在想填代码的时候挺尴尬的,需求会翻译但是代码本身没办法翻译的,有点难对应上。今天学了什么相关知识,又是看为主的一天。因为在上敲过一点,所以看得比较快,权当复习。引一个笔记第三天 2019.3.8 用时:两小时。 今天遇到了什么问题? 在MDN想填代码的时候挺尴尬的,需求会翻译但是代码本身没办法翻译的,有点难对应上。 今天学了什么? CSS相关知识,又是看为主的一天。因...

    NotFound 评论0 收藏0
  • 三天

    摘要:今天遇到了什么问题在想填代码的时候挺尴尬的,需求会翻译但是代码本身没办法翻译的,有点难对应上。今天学了什么相关知识,又是看为主的一天。因为在上敲过一点,所以看得比较快,权当复习。引一个笔记第三天 2019.3.8 用时:两小时。 今天遇到了什么问题? 在MDN想填代码的时候挺尴尬的,需求会翻译但是代码本身没办法翻译的,有点难对应上。 今天学了什么? CSS相关知识,又是看为主的一天。因...

    yuanxin 评论0 收藏0

发表评论

0条评论

songze

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<