全栈工程师开发手册 (作者:栾鹏)

js系列教程4-函数、函数参数教程全解

js中函数也是一种对象,因此有自己的原型对象,可以作为其他对象的属性,也可以作为其他函数的参数。

函数方法

【apply()和call()】

每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于函数体内this对象的值

要想以对象o的方法来调用函数f(),可以这样使用call()和apply()

f.call(o);
f.apply(o);

假设o中不存在m方法,则等价于:

o.m = f; //将f存储为o的临时方法
o.m(); //调用它,不传入参数
delete o.m; //将临时方法删除

下面是一个实际的例子

window.color = "red";
var o = {color: "blue"};
function sayColor(){console.log(this.color);
}
sayColor();            //red
sayColor.call(this);   //red
sayColor.call(window); //red
sayColor.call(o);      //blue
//sayColor.call(o)等价于:
o.sayColor = sayColor;
o.sayColor();   //blue
delete o.sayColor;

apply()方法接收两个参数:一个是在其中运行函数的作用域(或者可以说成是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用),另一个是参数数组。其中,第二个参数可以是Array的实例,也可以是arguments对象

function sum(num1, num2){return num1 + num2;
}
//因为运行函数的作用域是全局作用域,所以this代表的是window对象
function callSum1(num1, num2){return sum.apply(this, arguments);
}
function callSum2(num1, num2){return sum.apply(this, [num1, num2]);
}
console.log(callSum1(10,10));//20
console.log(callSum2(10,10));//20

call()方法与apply()方法的作用相同,它们的区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。换句话说,在使用call()方法时,传递给函数的参数必须逐个列举出来

function sum(num1, num2){return num1 + num2;
}
function callSum(num1, num2){return sum.call(this, num1, num2);
}
console.log(callSum(10,10));   //20

至于是使用apply()还是call(),完全取决于采取哪种函数传递参数的方式最方便。如果打算直接传入arguments对象,或者包含函数中先接收到的也是一个数组,那么使用apply()肯定更方便;否则,选择call()可能更合适

在非严格模式下,使用函数的call()或apply()方法时,null或undefined值会被转换为全局对象。而在严格模式下,函数的this值始终是指定的值

var color = 'red';
function displayColor(){console.log(this.color);
}
displayColor.call(null);//red

var color = 'red';
function displayColor(){'use strict';console.log(this.color);
}
displayColor.call(null);//TypeError: Cannot read property 'color' of null

应用

【1】调用对象的原生方法

var obj = {};
obj.hasOwnProperty('toString');// false
obj.hasOwnProperty = function (){return true;
};
obj.hasOwnProperty('toString');// true
Object.prototype.hasOwnProperty.call(obj, 'toString');// false

【2】找出数组最大元素

javascript不提供找出数组最大元素的函数。结合使用apply方法和Math.max方法,就可以返回数组的最大元素


var a = [10, 2, 4, 15, 9];
Math.max.apply(null, a);//15

【3】将类数组对象转换成真正的数组

Array.prototype.slice.apply({0:1,length:1});//[1]或者[].prototype.slice.apply({0:1,length:1});//[1]

【4】将一个数组的值push到另一个数组中

var a = [];
Array.prototype.push.apply(a,[1,2,3]);
console.log(a);//[1,2,3]
Array.prototype.push.apply(a,[2,3,4]);
console.log(a);//[1,2,3,2,3,4]

【5】绑定回调函数的对象

由于apply方法(或者call方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。更简洁的写法是采用下面介绍的bind方法

var o = {};
o.f = function () {console.log(this === o);
}
var f = function (){o.f.apply(o);
};
$('#button').on('click', f);

【bind()】

bind()是ES5新增的方法,这个方法的主要作用就是将函数绑定到某个对象

当在函数f()上调用bind()方法并传入一个对象o作为参数,这个方法将返回一个新的函数。以函数调用的方式调用新的函数将会把原始的函数f()当做o的方法来调用,传入新函数的任何实参都将传入原始函数

[注意]IE8-浏览器不支持

function f(y){return this.x + y; //这个是待绑定的函数
}
var o = {x:1};//将要绑定的对象
var g = f.bind(o); //通过调用g(x)来调用o.f(x)
g(2);//3

兼容代码

function bind(f,o){if(f.bind){return f.bind(o);}else{return function(){return f.apply(o,arguments);}}
}

bind()方法不仅是将函数绑定到一个对象,它还附带一些其他应用:除了第一个实参之外,传入bind()的实参也会绑定到this,这个附带的应用是一种常见的函数式编程技术,有时也被称为’柯里化’(currying)

var sum = function(x,y){return x+y;
}
var succ = sum.bind(null,1);
succ(2); //3,x绑定到1,并传入2作为实参y
function f(y,z){return this.x + y + z;
}
var g = f.bind({x:1},2);
g(3); //6,this.x绑定到1,y绑定到2,z绑定到3使用bind()方法实现柯里化可以对函数参数进行拆分

function getConfig(colors,size,otherOptions){console.log(colors,size,otherOptions);
}
var defaultConfig = getConfig.bind(null,'#c00','1024*768');
defaultConfig('123');//'#c00 1024*768 123'
defaultConfig('456');//'#c00 1024*768 456'

【toString()】

函数的toString()实例方法返回函数代码的字符串,而静态toString()方法返回一个类似’[native code]'的字符串作为函数体

function test(){alert(1);//test
}
test.toString();/*"function test(){alert(1);//test}"*/
Function.toString();//"function Function() { [native code] }"

【toLocaleString()】

函数的toLocaleString()方法和toString()方法返回的结果相同

function test(){alert(1);//test
}
test.toLocaleString();/*"function test(){alert(1);//test}"*/
Function.toLocaleString();//"function Function() { [native code] }"

【valueOf()】

函数的valueOf()方法返回函数本身

function test(){alert(1);//test
}
test.valueOf();/*function test(){alert(1);//test}*/
typeof test.valueOf();//'function'
Function.valueOf();//Function() { [native code] }

js中函数对象的方法,原型方法apply、call、bind、toString、toLocaleString、valueOf相关推荐

  1. Js中访问对象的两种方法

    我们通常都使用点" . '"表示法来访问对象,在js中也可以用方括号" [ ] "来访问对象的属性. 使用[]时,应该将想要访问的属性用字符串的形式放在&quo ...

  2. 理解js中的this指向以及call,apply,bind方法

    <script> function a(){var user = "追梦子";console.log(this.user); //undefinedconsole.lo ...

  3. js中遍历对象的几种方法

    一.前言 我们知道,在js的对象中,有下面几种属性: 可枚举属性 不可枚举属性 从原型链上继承的属性 以Symbol作为key值 今天,我们就来谈一谈如何遍历这些属性. 二.遍历可枚举属性   首先, ...

  4. JS中全局对象的属性和方法

    代码: for(var propValue in this){ document.write(propValue + "<br/>"); } 结果: IE9: stat ...

  5. [JS]请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组。

    请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组. 刚开始复习js题还不太习惯 CSDN上看了一个帖子,说是牛客上的标答, ...

  6. php 遍历对象数组,js中遍历对象(5种)和遍历数组(6种)的方法总结

    本篇文章给大家带来的内容是关于js中遍历对象(5种)和遍历数组(6种)的方法总结,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.遍历对象方法 1.for...in 遍历输出的是对 ...

  7. js中 函数和方法的区别:转载于黑泽君

    js中 函数和方法的区别 在javascript中的解释为: 函数(function)是可以执行的javascript代码块,由javascript程序定义或javascript实现预定义.函数可以带 ...

  8. 初学JavaScript:js中的对象(对象+原型对象)

    文章目录 js对象详解 1.创建对象 字面量模式创建对象 构造函数模式创建对象 2.访问对象 访问属性 访问方法 3.遍历对象中的属性和属性值 4.往对象中新添属性 5.删除对象中的属性 6.Obje ...

  9. HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)

    HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...

最新文章

  1. 简直骚操作,ThreadLocal还能当缓存用
  2. 【人工智能】人类该如何看待人工智能的“诗与远方”?
  3. Oracle数据库定时备份脚本
  4. 2019.04.24笔记
  5. 【Android开发】Android应用程序目录结构
  6. vivado顶层模块怎么建_【第2040期】Node 模块化之争:为什么 CommonJS 和 ES Modules 无法相互协调...
  7. php.ini用哪个,php.ini:哪一个?
  8. JavaWeb-RESTful_用SpringMVC开发RESTful
  9. android bitmap to base64_Android基础(11)—你需要知道的内存知识
  10. MicroBlaze AXI总线 GPIO中断使用(On Atyls Board)
  11. Mysql笔记——DCL
  12. php 伪静态 获取当前页面路径_php url伪静态过程详解
  13. matlab中函数在哪儿,matlab怎么调用函数
  14. TCP可靠传输实现-滑动窗口协议
  15. 转载-一种基于陀螺仪传感器的准确计步器算法
  16. unity导入Standard Assets出现错误
  17. 英特尔核显驱动hd630_英特尔首款独显 Xe Max 评测出炉:低于移动端 GTX 1050 Ti
  18. Android 系统 Bar 沉浸式完美兼容方案
  19. Problem E 寻找最大元素和第二大元素
  20. wstmart系统研究日志二

热门文章

  1. 抓包神器之Charles
  2. boid模型的Matlab程序,基于Boid模型以及吸引—排斥模型的沙丁鱼集群运动行为模拟...
  3. 东北大学oj平台python答案_东北大学大数据班R实训第三次作业
  4. 【python笔记】:python简介
  5. FFmpeg架构之I/O模块分析
  6. 鸿蒙对抗谷歌,华为下定决心对抗谷歌,打出第一张王牌,鸿蒙系统更进一步
  7. Junit4中的新断言assertThat的使用方法
  8. logback为日志配置颜色
  9. 刷新include引进的页面
  10. a标签加onclick点击事件