JS function的定义方法,及function对象的理解。

废话篇:

今天看到了javascript的原型链,各种指向,各种对象有木有,各种晕,各种混淆有木有。兼职是挑战个人脑经急转弯的极限啊。不过,最终这一难题还是被我攻克了,哇咔咔。现在就把这东西记下来,免得到时候又忘了就悲催了。。。。

正文篇:

function的定义方法,及function对象的理解。

在我大js中秉承着一切都是对象的原则,不论是方法还是其他都不例外。

我们在使用java的时候经常要编写方法,这时候其用的关键字是function,而在js中我们在编写函数的时候也是用这个关键字,所以常常会使我们错把两者进行关联,所以常常会吧我们引导只一个错误的方向。

所以接下来我们先从function的定义开始说起。

一:实际上就和我们最为平常的方法是一样的。

function fname(test){ alert(""+test); }

二:通过Function的函数的构造器进行函数对象的定义。

var fname = new Function("test", "alert(‘‘+test);"); 第一个参数实际上是表示要传入函数中的参数,二第二个参数表示的是当前的函数要执行的过程。两个参数实际上都是string类型的。但是又上可以看出实际上当前的内容是十分的繁杂。

三:通过变量只带一块function关键字定义的方法来进行定义。

var fname = function(test){alert(""+test);}

上面的三种方法虽然最后都是声明定义了一个函数,但是也是有区别的。第一种方法实际上是为函数命名为fname,而二三种方法使用起来实际上是把一个匿名函数赋值给一个变量。使用第二种方法来定义函数的时候,实际上就是调用构造函数并在每次解析的时候都会重新读取并创建一新的函数对象,由此可见当在循环体中调用这样的函数的时候会是十分的低效的,还有一点就是,当我们使用其创建一个函数对象的时候,其并不遵循典型的作用域,而是一直作为顶级函数来执行的。意思就是,当在函数内部调用它的时候,其实他并不会用函数内部定义的变量。而是只能使用全局变量。

第一三种方法实际上市定义了一种函数直接量。当我们不为函数直接量定义名称的时候。函数直接量就叫做匿名函数。那么我们如何调用一个匿名直接量,如下:

  1、执行后得到返回值的函数调用

  //方式一,调用函数,得到返回值。强制运算符使函数调用执行
  (function(x,y){
  alert(x+y);
  return x+y;
  }(3,4));

  //方式二,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行
  (function(x,y){
  alert(x+y);
  return x+y;
  })(3,4);

  2、执行后忽略返回值

  //方式三,调用函数,忽略返回值
  void function(x) {
  x = x-1;
  alert(x);
  }(9);

  嗯,最后看看错误的调用方式

  //错误的调用方式
  function(x,y){
  alert(x+y);
  return x+y;
  }(3,4);

有点扯远了。实际上在使用第一和第三种的方法来说的话,在第一次解析的时候会通过new Function来定义一个函数的对象,并把这一对象作为内部对象来进行存储和运行。由此可知在js中没每写一个对象,实际上就是在其中存储一个相关的函数对象,并在我们需要调用的时候对其进行调用。

接下来我们来咯具体的了解一下分Function对象的定义和内容吧。

  1.首先是我们最为常用的内容arguments对象。他的定义是,一个类似于数组的对象,对应的是传递给函数对象的属性。arguments对象是一个所有的函数内部都可以用的函数内部变量。当我们调用函数的时候,他会存储我们传输进来的参数的数据的。如下端的吗。

1 function test(){
2     if(arguments[0]){
3         alert("arguments:",+arguments[0]);
4     }
5 }
6 test("a");//当前页面中会显示出一个弹出框并显示arguments:a

所以由上面可以看出,arguments对象的使用方式和array是十分的相像的。为什么说他只是类似数组对象呢,因为他仅仅只有length属性但并没有array的其他属性和方法。

  当然在arguments对象中也是有一些其自己的属性的,如下

  • callee,属性存储的是当前的调用的函数对象。当我们使用匿名函数的时候,如果需要调用存储当前的arguments对象的方法对象,此时可以使用当前属性。但是在ECM5中是阻止使用这一属性的。这样做的原因是,函数命名来调用函数的实现是优于这种方式的。
  • caller,这一属性只有当函数正在执行的情况之下才会被定义。当然其返回的内容是当前的和toString方法是一样的,为function的反编译文本。但是实际上在使用的时候返回便以文本之后,js有解析成为函数对象之后执行,所以说,这一属性实际上还是返回函数本身。但是这一属性在ECM5中已经被删除了。
  • length属性,是初始化的时候读取当前函数中的参数后获取的值。所以函数的length属性的值其实就和arguments.length的值的大小是一样的。
  • prototype属性,表示的是当前的function对象的原型对象。也可以了几位当前的函数对象继承了原型对象的属性和方法。具体参见js原型链学习。

当然对于函数对象js中也是有定义一些基本方法的。

  • apply方法相信你不会陌生,制定方法替换当前的this指针,冰用穿入的对象中的数据替换当前函数的参数值。上例子:

    function test(){
        alert("" + this);
    }
    
    function testTwo(a){    console.log("this:"+this);
        console.log("a:"+a);
    }
    
    testTwo.apply(test, [1]);
    
    //输出的效果是this:function test(){ alert("" + this);} 与 a:1
    
    

    实际上apply是用第一个参数中的对象替换当前的函数中的this指针,并用数组参数中的数据来来替换但钱的函数调用时的参数。

  • bind方法,其效果是不论当前的函数怎么调用他的this指针代表的值都是一样的。

     1 var displayArgs = function (val1, val2, val3, val4) {
     2     document.write(val1 + " " + val2 + " " + val3 + " " + val4);
     3 }
     4
     5 var emptyObject = {};
     6
     7 var displayArgs2 = displayArgs.bind(emptyObject, 12, "a");
     8
     9 displayArgs2("b", "c");
    10
    11 // Output: 12 a b c 

    由上面可见实际上bind函数就有点像是绑定当前的内容和一个数据的关系。并返回一个一个可调用对象。

  • call方法使用效果实际上和apply方法是一样的,只是其后面传递的第二个参数不在是严格要求是数组。
时间: 2024-10-13 16:13:02

JS function的定义方法,及function对象的理解。的相关文章

get定义方法——Javascript设置对象属性为"只读"

get 定义方法时,表示该方法只能被读取 参考:https://www.cnblogs.com/season-huang/p/seasonhuang.html 原文地址:https://www.cnblogs.com/marquess/p/12600485.html

js数组的定义方法与基本使用

声明方式:new array()   和  [] 不支持关联数组,只支持索引数组 * 数组元素的操作 *1.添加 * a.使用下标方式a[索引]=值; * b.在尾部添加一个元素  数组名.push(值); * c.在头部添加一个元素   数组名.unshift(值); *2.删除 * a.delete  数组名[索引];并且值变为undefined * b.数组名[索引] = undefined * c.尾部的删除  数组名.pop(); * d.头部的删除  数组名.shift(); * e

js中使用使用原型(prototype)定义方法的好处

经常在前端面试或是和其他同行沟通是,在谈到构造在JS定义构造函数的方法是最好使用原型的方式:将方法定义到构造方法的prototype上,这样的好处是,通过该构造函数生成的实例所拥有的方法都是指向一个函数的索引,这样可以节省内存. 当然,这种说法没有任何问题,只是在实现上,并非只有使用prototype的方式才能达到这样的效果,我们可以将方法以函数的形式定义在构造函数之外,然后在构造函数中通过this.method = method的方式,这样生成的实例的方法也都通过索引指向一个函数,具体如下:

JS实现AOP拦截方法调用

//JS实现AOP拦截方法调用function jsAOP(obj,handlers) {    if(typeof obj == 'function'){        obj = obj.prototype;    }    for(var methodName in handlers){        var _handlers = handlers[methodName];        for(var handler in _handlers){            if((hand

字符串方法,js中的数组方法,ES5新增的数组方法,以及jQuery中的数组方法

说明:本片主要对比介绍与数组操作相关的方法 (一)字符串方法(String对象方法) indexOf() //检索字符串 lastIndexOf() //从后向前搜索字符串 match() //找到一个或多个正则表达式的匹配 replace() //替换与正则表达式匹配的子串 search() //检索与正则表达式相匹配的值 slice() //提取字符串的片断,并在新的字符串中返回被提取的部分 split() //把字符串分割为字符串数组 substr() //从起始索引号提取字符串中指定数目

【笔记】js Function类型 内部方法callee

运用function实现阶乘 以往的做法是如下的 function factorial(num){ if(num <= 1){ return 1; }else{ return num * factorial(num - 1); } } 但是如果一旦函数名改变 函数内部的递归调用行数也要进行改变 重用性很不好所以可以使用function 内部的callee()方法,此方法是function 类型内部的一个属性,它是一个指针指向函数参数对象的函数,即callee所在函数的本身 所以以后的阶乘可以这样

js中Function的apply方法与call方法理解

首先,function是一个指向Function对象,函数名是一个指向函数的指针.那么在函数体内,就会有一个作用域,即this关键字. this关键字指的是函数运行的作用域,举个例子来说, <script type="text/javascript"> function funcA() { alert(this); alert("Function A"); } </script> 上面这段代码中的函数funcA定义在全局环境中,那么函数体内的

JS函数的定义与调用方法

原文:http://www.cnblogs.com/mq0036/p/3934867.html JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式 1.方法调用模式:先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来执行方法,this即指当前的myobject 对象.var blogInfo={ blogId:123, blogName:"werwr", showBlog:function(){alert(

初始化JQuery方法与(function(){})(para)匿名方法介绍

一.初始化JQuery对象 DOM加载完成时运行代码 1.$(document).ready(function(){ 全写 // 在这里写你的代码... }); 2.jQuery(function(){ // 在这里写你的代码... }); 3.$(function(){ 简写方法,$等价于jQuery // 在这里写你的代码... }); 以上三个等价,这个函数初始化为一个jQuery对象:$(obj); 都是在DOM加载完成时运行代码 二.(funtion(){})():立即执行函数:相当于