它到底是什么

String Array 都是系统内置对象(已经定义好,可以直接使用)当然,这货也是一样,我们之前定义的函数,其实就是一个这货的实例。

在JS中,所有的对象都是由函数实现的,函数的数据类型是object。So,我们以前定义的函数也是一个对象。

几种写法

  1. function fn1(a,b){
  2. return a+b;
  3. }
  4.  
  5. //前面表示参数,后面表示函数语句
  6. var fn2 = new Function("a","b","return a+b");
  7.  
  8. // 匿名函数
  9. var fn3=function(a,b){
  10. return a+b;
  11. }
  12.  
  13. console.log(fn1(1,2));
  14. console.log(fn2(1,2));
  15. console.log(fn3(1,2)); // 注意,一定要在声明函数的后面调用

另外,如果函数没有明确的返回值,或者调用了没有参数的return,那么它真正返回的值是undefined

  1. function fn(){
  2. //.....
  3. }
  4.  
  5. function fn1(){
  6. return;
  7. }
  8.  
  9. console.log(fn()===undefined); // true
  10. console.log(fn1()===undefined); // true

arguments  

arguments只有在代码运行的时候才起作用,它是一个数组(准确的说是伪数组),保存函数的参数。

  1. function fn(){
  2. var sum=0;
  3. for(var i=0;i<arguments.length;i++){
  4. sum+=arguments[i];
  5. }
  6. return sum;
  7. }
  8.  
  9. var sum = fn(1,2);
  10. var sum2 = fn(1,2,3);
  11. console.log(sum); //
  12. console.log(sum2); //
  13.  
  14. function fn1(a,b,c,d){
  15. console.log(arguments.length);
  16. console.log(arguments[0]);
  17. }
  18.  
  19. fn1(); // 0 、 undefined
  20. fn1(1); // 1 、 1
  21. fn1('a',2); // 2 、 a
  22. fn1('李志',2,3); // 3 、 李志
  23. fn1('李B',2,2,3,4,4); // 6 、 李B

Length

我们需要了解两个东东,形参与实参(不同的资料书籍可能叫法有所差异)

形参:函数定义的时候的参数  实参:调用函数的时候传递的参数

length指的是形参个数   arguments.length指的是实参个数

  1. function fn(a, b) {
  2. console.log(fn.length);
  3. console.log(arguments.length);
  4. }
  5.  
  6. fn(1, 2); // 2 2
  7. fn(1); // 2 1

call  apply

1,借用另一个对象的方法  2,替换this指向

Apply方法  调用函数,并用指定对象替换函数的this值,同时用指定数组替换函数的参数。

Call方法    调用一个对象的方法,用另一个对象替换当前对象。

  1. //对象1
  2. var obj1={
  3. getAllStudentsNumbers:function(sum,sum1){
  4. return sum+sum1}
  5. };
  6.  
  7. //对象2
  8. var obj2={
  9. getDetail:function(){
  10. return {name:'阿拉三',age:'18'}
  11. }
  12. };
  13. console.log(obj1.getAllStudentsNumbers.call(obj2,10,200)); //
  14. console.log(obj1.getAllStudentsNumbers.apply(obj2,[10,200])); //

Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)

我们通过如下方式将其转换成数组

  1. /* slice : 截取数组,返回的还是数组,这里我们截取全部 */
  2. var divs = document.getElementsByTagName("div")
  3. var domNodes = Array.prototype.slice.call(divs);

还可以实现继承,在上篇文章中说过,这里不做赘述。

caller callee

caller属性 获取调用当前函数的函数。caller属性只有当函数正在执行时才被定义。

返回函数调用者,主要用于察看函数本身被哪个函数调用.

  1. function fn() {
  2. //判断某函数是否被调用
  3. if (fn.caller) {
  4. alert(fn.caller.toString());
  5. } else {
  6. alert("函数直接执行");
  7. }
  8. }
  9.  
  10. function fn1() {
  11. fn();
  12. }
  13. fn1();
  14. fn();

callee属性 返回正被执行的 Function 对象,即指定的Function 对象的正文。

如下是一个递归算法 - 计算 1+2+3+4+...+n

什么是递归?    可以这样理解,一个方法,自己调用自己,用上一次调用得出的结果作为这次的参数。

传统方式的缺点:

1、破坏了,零重复法则,当一旦函数名称更改,需要更改多处

2、fn是一个全局变量,fn内部一般使用局部变量,而这里是一个全局变量,这是一个潜在的全局变量污染

  1. var fn=function(n){
  2. return n>0 ? n+fn(n-1) : 0;
  3. }
  4. console.log('采用传统方式:'+fn(10));

优点:这样就让代码更加简练。又防止了全局变量的污染

  1. var fn=(function(n){
  2. return n>0 ? n+arguments.callee(n-1) : 0;
  3. })(10);
  4. console.log('采用callee方式: '+fn);

constructor prototype

constructor属性,就是用来构造对象实例的函数引用。

prototype属性,获取对象的原型。

每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

contructor,prototype属性是系统自动生成的。但本质上只是是函数对象的属性而已。

对象是一个函数,而函数对象含有contructor,prototype等属性,

那么实例化的过程就是拷贝构造函数属性的过程,所以每个实例自然就拥有了contructor,prototype这两个属性。

自定义对象:函数实现的--函数又是Function的一个实例,所以这个自定义对象含有Function对象的一切属性和方法

  1. var product = function(){}
  2. /*自动有一个 prototype属性 它是一个对象--- 原型对象*/
  3. /* product.prototype也是对象,对象都是函数实现的,这货也包含Function对象的一切属性和方法,所以他也有。*/
  4. product.prototype.buy=function(){}
  5. product.prototype={}

bind  

Bind方法,创建具有与原始函数相同的主体的绑定函数。 在绑定功能中,this对象解析为传入的对象。 该绑定函数具有指定的初始参数。

为了能在改变了上下文之后继续引用到this,大家通常选择使用self that _this 等方式先保存起来。这是完全可以的,现在有了bind:

  1. var obj={
  2. fn1:function(){
  3. console.log(1);
  4. },
  5. fn2:function(){
  6. console.log(2);
  7. },
  8. fn3:function(fn){
  9. fn();
  10. console.log(3);
  11. },
  12. fn4:function(){
  13. // var that=this; // 还保存吗?
  14. // this.fn3(function(){
  15. // console.log(4);
  16. // that.fn1();
  17. // that.fn2();
  18. // });
  19. this.fn3(function(){
  20. console.log(4);
  21. this.fn1();
  22. this.fn2();
  23. }.bind(this)); // 咦,发生什么?
  24. },
  25. }
  26. obj.fn4();

再看一眼:

  1. var foo={
  2. x:3,
  3. }
  4. var bar=function(){
  5. console.log(this.x);
  6. }
  7. bar();
  8. var boundFunc=bar.bind(foo);
  9. boundFunc();

想到了什么?call? apply? 没错,看下面三者的区别:

  1. fn1.hello.call(fn2,1,2,3);
  2. fn1.hello.apply(fn2,[1,2,3]);
  3. fn1.hello.bind(fn2)(1,2,3);

好消息是,IE8以下并不支持。肿么办?

没关系,大牛们写好了,我们来看一下

  1. if (!Function.prototype.bind) {
  2. Function.prototype.bind = function (oThis) {
  3. if (typeof this !== "function") {
  4. throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  5. }
  6. var aArgs = Array.prototype.slice.call(arguments, 1),
  7. fToBind = this,
  8. fNOP = function () {},
  9. fBound = function () {
  10. return fToBind.apply(this instanceof fNOP ? this : oThis || this ,
  11. aArgs.concat(Array.prototype.slice.call(arguments)));
  12. };
  13. fNOP.prototype = this.prototype;
  14. fBound.prototype = new fNOP();
  15. return fBound;
  16.  
  17. };
  18. }

最后:

JS中,函数的使用是非常之灵活,比如闭包、立即函数、等等等等,以后有机会专门讨论。

对js中Function的浅见的更多相关文章

  1. js中function的与众不同

    js中function的与众不同在于可以被调用

  2. js中function参数默认值

    --在dreamweaver做网站时,函数定义是在一个*.js文件中,其中定义了一个func,有四个参数,function func(string1,url,flag,icon),然后在另一个asp中 ...

  3. 使用另一种方式实现js中Function的调用(call/apply/bind)

    在JavaScript中函数的调用可以有多种方式,但更经典的莫过于call和apply.call跟apply都绑定在函数上,他们两个的第一个参数意义相同,传入一个对象,他作为函数的执行环境(实质上是为 ...

  4. js 中 (function($){...})(jQuery) 含义

    js中定义函数常用写法是 function name(arg){ //arg则是匿名函数的参数. //... } 调用函数时的写法是: name(arg); ===================== ...

  5. prototype.js中Function.prototype.bind方法浅解

    prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...

  6. js中Function引用类型中一些常见且有用的方法和属性

    Function类型 函数由于是Function类型的一个实例,所以函数名就是一个指向函数对象的指针,不会与某个函数死死的连接在一起,这也导致了js中没有真正的重载,但好处是,函数对象可以作为另一个函 ...

  7. js中(function(){})()的写法用处

    直到今天我才明白的一个玩意!!! 来来来,首先嘛,JS中函数有两种命名方式 1.一种是声明式. 而声明式会导致函数提升,function会被解释器优先编译.即我们用声明式写函数,可以在任何区域声明,不 ...

  8. js中(function(){}()),(function(){})(),$(function(){});之间的区别

    1. (function(){}())与(function(){})() 这两种写法,都是一种立即执行函数的写法,即IIFE (Immediately Invoked Function Express ...

  9. js中function函数

    function:是具备某个功能的方法,方法本身没有意义,只有执行方法才有价值. function: 1 创建一个函数: 2 执行这个方法: 例: 创建 function 方法名(){ 存放某个功能的 ...

随机推荐

  1. 检索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))

    Resvr32 .net中引用控件的名称 如果注册成功,问题不在出现 但是如果是在x64位的系统中,即使控件注册成功,错误依照提示,是因为大多数第三方写的COM控件,只支持32位的系统, 在VS中找到 ...

  2. iis7 压缩js文件和启用gzip压缩

    压缩js文件 打开IIS 7的配置文件:c:\windows\system32\inetsrv\config\applicationhost.config 在<staticContent loc ...

  3. thinkphp端口配置

    <?php return array( //'配置项'=>'配置值' 'MODULE_ALLOW_LIST' => array('Home'), 'DEFAULT_MODULE' = ...

  4. Firemonkey 在 iOS 平台能显示更多的 emoji 字符

    使用 Firmonkey 在显示 emoji 字符时,有些 emoji 并无法显示彩色,见下图: 经查 FMX 源码,是因为判断 emoji 的字符区段不足造成的,经过修改后,便可显示,见下图: 修改 ...

  5. 泛函编程(38)-泛函Stream IO:IO Process in action

    在前面的几节讨论里我们终于得出了一个概括又通用的IO Process类型Process[F[_],O].这个类型同时可以代表数据源(Source)和数据终端(Sink).在这节讨论里我们将针对Proc ...

  6. 基础-WeakReference

    一.概述 为了更好的理解WeakHashMap的原理,我们有必要先来了解一下WeakReference的作用及实现原理.Java中有一个专门的包java.lang.ref,里面定义了我们通常所说的几种 ...

  7. python常用工具小函数-字符类型转换

    Python3有两种表示字符序列的类型:bytes和str.前者的实例包含原始的8位值就是的字节,每个字节有8个二进制位:后者的实例包含Unicode字符.把Unicode字符转成二进制数据最常见的编 ...

  8. cnodejs社区论坛3--发表话题

  9. GJM :用JIRA管理你的项目(三)基于LDAP用户管理 [转载]

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  10. Type.js – 帮助你更好的控制网页字体排版

    Type.js 是一款很好的网页字体排版工具.它可以让你使用新的 CSS 属性,在网页上试下更精细的排版控制.设置很简单.上传 type.js 到您的网站,并在你的 HTML 链接中引用.接下来,你就 ...