Home  >  Q&A  >  body text

javascript - JS中的函数与方法怎么区别?

原来 JavaScript 中的函数与方法有区别的。
例如 Array 对象:
Array 对象的函数有:Array.isArray 函数。
Array 对象的方法有:concat()、join()、pop()、push() 等方法。

JS中的函数与方法怎么理解和区别?

PHPzPHPz2725 days ago1141

reply all(9)I'll reply

  • 数据分析师

    数据分析师2017-10-01 01:22:03

    javascript - What is the difference between functions and methods in JS? -PHP Chinese website Q&A-javascript - What is the difference between functions and methods in JS? -PHP Chinese website Q&A

    Let’s take a look and learn.

    reply
    0
  • 黄舟

    黄舟2017-04-10 13:15:00

    你说的所谓函数是类的方法。

    a = [1,2,3]
    Array.isArray(a) #return true   isArray是类Array的方法
    

    你说的所谓的方法就是类所生成对象的方法。

    a = [1,2,3]
    a.pop()    #return 3  pop()是Array类所生成的对象a的方法
    

    这里所谓的类指的是构造函数

    之前写的关于函数的笔记,你可以作为个参考。

    Function

    在JavaScript中,函数是Function类的具体实例。而且都与其它引用类型一样具有属性和方法。函数名实际上是指向函数对象的指针,函数可以作为参数参与到传参和返回值中。

    函数定义

    //函数声明式定义
    function foo(num1,num2){
        return num1 + num2;
    }
    //函数表达式定义
    var foo = function(num1,num2){
        return num1 + num2;
    };
    //使用Function构造函数定义
    var foo = new Function("num1","num2","return num1 + num2");
    //实际上创建一个Function实例并不一定要赋值给具体的指针,可以直接执行
    (function(x,y){return x+y})(1,2);
    //之所以用圆括号把function(){}括起来是因为js解释器会将function解释为函数声明,而函数声明不能直接跟着(x,y),我们需要将其转换为函数表达式。
    //(1,2)表示要传递跟函数的参数。
    //上面的例子也可以写成:
    function foo(x,y){
        return x+y;
    }(1,2);
    //函数声明的方式无法定义匿名函数,因此如果想使用匿名函数,则必须用函数表达式的定义方式。
    

    函数的对象特性

    因为函数是Function的实例,而函数名仅仅是该实例的一个引用地址。因此可以作为参数和返回值参与到函数的传参过程中。

    function call_some_function(some_function, some_argument) {
        return some_function(some_argument);
    }
    function add_10(num) {
        return num + 10;
    }
    console.log(call_some_function(add_10,20)); //30
    

    函数的内部属性

    arguments | this

    • arguments对象中保存着传递给函数的参数
    • arguments.length返回传入参数的个数
    • Note: length属性表示函数定义时候默认接收的参数数量。arguments.length表示函数实际执行时接收的参数数量。
    function test_arguments() {
        if (arguments.length == 2) {
            console.log(arguments.length); 
            console.log(arguments); 
        } else {
            console.log(arguments.length); 
            console.log(arguments); 
            arguments.callee(4, 5);
        };
    }(1, 2, 3)
    /**
     3
    { '0': 1, '1': 2, '2': 3 }
    2
    { '0': 4, '1': 5 }
     **/
    
    • arguments.callee()主要用在递归函数中调用函数自身的情境中。js和别的语言不同在于函数名只是一个指针,可以随时变化,函数中利用函数名来调用自身属于高耦合,可能会出现问题,而arguments.callee()调用自身就会规避掉这个问题
    function factorial(num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * factorial(num - 1);
        };
    }
    function callee_f(num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * arguments.callee(num - 1);
        };
    }
    factorial(10); //运行正常
    f = factorial;
    factorial = null;
    f(10); //error
    
    callee_f(10); //运行正常
    f = callee_f;
    callee_f = null;
    f(10); //运行正常
    
    • this主要用来帮助函数引用函数所处作用域中的对象。
    var color = 'red';
    function syaColor() {
        console.log(this.color);
    }
    syaColor(); //red
    var o = new Object();
    o.color = 'blue';
    o.sayColor = sayColor;
    o.sayColor(); //blue
    

    call()和apply()

    call()和apply()是每个函数都包含的自有方法。之前已经提到了函数是定义的对象,那么调用函数时候,函数中的this是对当前与下变量的调用。而如果想改变函数执行所在域空间,则可以使用call()和apply()来实现。

    color = 'red';
    var o = {color: 'blue'};
    function sayColor() {
        console.log(this.color);
    }
    sayColor(); //red
    sayColor.call(this); //red
    sayColor.call(o); //blue
    

    app()和call()的作用是相同的,区别主要在于传入参数的不同。

    call(this,para1,prar2,prar3) 第一个参数是函数要执行的作用域,后面的参数是函数的输入参数,有多少个依次写多少个。

    apply(this,[para1,para2,prara3])第一个参数也是函数要执行的作用域,后面是一个Array的数组对象。

    使用call()/apply()来扩充作用域最大的好处是对象和方法的解耦。

    内置对象

    Global对象可以理解成最外层的对象,所有的对象,以及不属于其它对象的属性和方法都被包含在Global对象中。
    * isNaN(x) 用来检查参数x是否为数字。如果为数字返回false,否则返回true
    * isFinite(x) 用来检查参数x是否为无穷大/小,如果是无穷大/小,则返回true
    * parseInt(x) 用来解析字符串并返回整数
    * parseFloat(x) 用来解析字符串并返回浮点数
    * encodeURI()encodeURIComponent()会对字符串进行特殊的UTF-8编码,规避一些特殊字符来让浏览器能够读懂。他俩的区别主要在于encodeURI()不会对本身属于URI的特殊字符进行编码,而encodeURIComponent()会对其发现的所有非标准字符进行编码。

    var uri = "http://www.wrox.com/illegal value.htm#start";
    //http://www.wrox.com/illegal%20value.htm#start
    console.log(encodeURI(uri))
    //http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start
    console.log(encodeURIComponent(uri))
    
    • 对应的解码函数为decodeURI()decodeURIComponent()
    • eval(script) 用来将script的内容在解释器中执行并返回对应的结果。非常强大!

    Note:在浏览器中,windows对象封装了Global对象,并承担了很多额外的任务和功能。

    Math对象为另一个内置对象。为JavaScript提供了数学计算功能。

    reply
    0
  • PHPz

    PHPz2017-04-10 13:15:00

    函数和方法是同一种东西。

    面相对象叫“方法”,面相过程叫“函数”。C语言叫函数,Java叫方法。也就是习惯问题,你讲哪个,对方都能听懂。

    reply
    0
  • PHPz

    PHPz2017-04-10 13:15:00

    其实简单来说,你所说的函数可以认为是oo中的静态方法,一般来实现一些不指定某个具体对象的公用方法,其实没有啥区别,能用静态方式实现一定可以通过动态方式实现,仅仅是设计上的考虑。

    剥离出公用方法或者静态方法以后,单个对象的占用的资源就少很多。

    reply
    0
  • 阿神

    阿神2017-04-10 13:15:00

    其实方法和函数是一样的,只是叫法不一样而已。
    Array其实是一个Function,是构造函数。而Function其实也是对象,所以可以在Array上添加方法(如isArray,相当于其他语言中类的静态方法)。
    而concat等方法是在Array原型(可以参考汤姆大叔的文章)上的方法,其实例可以调用,如[].concat([1]);

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 13:15:00

    不用分那么清,本质是一样的

    reply
    0
  • PHPz

    PHPz2017-04-10 13:15:00

    对象的某个属性是函数时,称其为方法。
    When the value of a property is a function, we call it a method. To invoke the method m of an object o, we write o.m().
    牛书3.6节

    reply
    0
  • 黄舟

    黄舟2017-04-10 13:15:00

    可以去看一下Stack Overflow关于这个问题的讨论Difference between a method and a function

    简单来说:函数是一段代码,需要通过名字来进行调用。它能将一些数据(函数的参数)传递进去进行处理,然后返回一些数据(函数的返回值),也可以不返回数据。

    所有传递给函数的数据都是显示传递的

    方法也是一段代码,也需要通过名字来进行调用,不过方法跟一个对象相关联。方法和函数基本上是一样的,主要区别在于:

    1. 方法中的数据时隐式传递的(“ 方法在 C++ 中是被称为成员函数”。因此,在 C++ 中的“方法”和“函数”的区别,就是“成员函数”和“函数”的区别。此外,诸如 Java 一类的编程语言只有“方法”。所以这时候就是“静态方法”和“方法”直接的区别。)

    2. 方法可以操作类的内部数据(对象是类的实例化–类定义了一个数据类型,而对象是该数据类型的一个实例化)。方法可以操作已在类中声明的私有实例(成员)数据。

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 13:15:00

    函数依附于某个对象后,就可以说成是一个对象的方法。

    函数着重定义,方法强调执行。

    假设有一个对象obj,他存在两个方法,fn1和fn2。

    obj.fn1( obj.fn2 )
    

    我们可以这样描述:调用obj下的fn1方法,并将传递obj中名为fn2的函数。我们在提到方法时,一般有执行的味道,方法执行的后果是有返回值。在此处代码中,obj.fn2的传递,并不表示obj.fn2被执行了,仅仅是一个函数的传递。 即:将函数作为某个方法的参数,这种用法在JS中非常常见,比如各种回调处理。

    函数的宿命是被调用,被调用时一般称为执行对象的方法,当然你也可以说调用了对象的某个函数。

    reply
    0
  • Cancelreply