【问题标题】:Method vs Functions, and other questions方法与函数,以及其他问题
【发布时间】:2013-02-23 11:36:42
【问题描述】:

关于JS,两者有什么区别?我知道方法与对象相关联,但我很困惑函数的目的是什么?它们各自的语法有何不同?

另外,这两种语法有什么区别:

var myFirstFunc = function(param) {
    //Do something
};

function myFirstFunc(param) {
    //Do something
};

另外,我在某处看到我们需要在使用函数之前做这样的事情:

obj.myFirstFunc = myFirstFunc;
obj.myFirstFunc("param");

为什么需要第一行,它的作用是什么?

对不起,如果这些是基本问题,但我从 JS 开始并且很困惑。

编辑:对于最后一段代码,这就是我要说的:

// here we define our method using "this", before we even introduce bob
var setAge = function (newAge) {
  this.age = newAge;
};
// now we make bob
var bob = new Object();
bob.age = 30;
// and down here we just use the method we already made
bob.setAge = setAge;

【问题讨论】:

  • 查找“函数声明与函数表达式”。
  • 你在哪里看到的最后一部分?没有理由这样做,除非 obj.myFirstFunc 未定义并且需要引用 myFirstFunc
  • @MichaelBerkowski:Codecademy。我不记得它在哪里练习了。找到代码,现在编辑OP。
  • 在回答最后一个问题时(这样它就不会打扰我了),他们定义了一个函数并将其分配给myFirstFunc。它们还有一个变量obj,它是一个具有myFirstFunc 属性的类。他们将函数从局部变量复制到对象。从局部变量 (myFirstFunc("param");) 调用函数不需要副本。如果要从对象 (obj.myFirstFunc("param");) 调用函数,则需要副本,尤其是在局部变量超出范围的情况下。

标签: javascript function methods


【解决方案1】:

回答您关于“函数”和“方法”之间有什么区别的标题问题。

这是语义,与您要表达的内容有关。

在 JavaScript 中,每个函数都是一个对象。对象是键:值对的集合。如果一个值是一个基元(数字、字符串、布尔值)或另一个对象,则该值被视为一个属性。如果值是函数,则称为“方法”。

在对象的范围内,函数被称为该对象的方法。它是从对象命名空间MyObj.theMethod().调用的,既然我们说函数是一个对象,那么函数中的函数可以被认为是该函数的方法。

您可以说“我将使用对象的保存方法”之类的话。并且“这个保存方法接受一个函数作为参数。”但你一般不会说函数接受方法作为参数。

顺便说一句,Stoyan StefanovJavaScript 模式 一书详细介绍了您的问题,如果您真的想了解该语言,我强烈推荐您阅读。以下是书中关于该主题的引述:

因此,作为对象的函数 A 可能具有属性和方法,其中一个恰好是另一个函数 B。然后 B 可以接受函数 C 作为参数,并且在执行时可以返回另一个函数D.

【讨论】:

  • 按照这个answer,只是说If a value is a function, it is called a 'method'.好像不准确?
  • @TinaChen 你是对的,这个答案反映了 2013 年 javascript 的状态,需要针对 ES6 进行更新。坦率地说,整件事并不那么重要。随心所欲地调用它:函数/方法。一个函数通常位于顶级(全局)命名空间中,一个方法属于一个类/对象命名空间,并且必须使用该接收器调用。
  • 原始是数字、字符串、布尔值
【解决方案2】:

略有不同——

Method : Method 是一个与对象关联的函数。

var obj = {
name : "John snow",
work : function someFun(paramA, paramB) {
    // some code..
}

Function : 当没有对象与之关联时,它就会发挥作用。

function fun(param1, param2){
// some code...
}

【讨论】:

  • 很好,简单的答案。
【解决方案3】:

许多答案都说方法是在对象上定义函数时调用的函数。

虽然当人们谈论 JavaScript 或一般的面向对象编程时,这个词的使用方式通常是正确的(参见 here),但值得注意的是,在 ES6 中的术语 method 具有非常特殊的含义(参见规范的14.3 Method Definitions 部分)。


方法定义

方法(严格意义上)是通过对象字面量中的简洁方法语法或类声明/表达式中的类方法定义的函数:

// In object literals:
const obj = {
    method() {}
};

// In class declarations:
class MyClass {
    method() {}
}

方法特性

这个answer 很好地概述了方法(严格意义上的)的特殊性,即:

  1. 方法被分配了一个内部[[HomeObject]] 属性,允许它们使用super
  2. 方法不是用prototype 属性创建的,它们没有内部[[Construct]] 方法,这意味着它们不能用new 调用。
  3. 方法的名称不会成为方法范围内的绑定。

以下是一些示例,说明方法(严格意义上)与通过函数表达式在对象上定义的函数有何不同:

示例 1

const obj = {
    method() {
        super.test;         // All good!
    },
    ordinaryFunction: function ordinaryFunction() {
        super.test;         // SyntaxError: 'super' keyword unexpected here
    }
};

示例 2

const obj = {
    method() {},
    ordinaryFunction: function ordinaryFunction() {}
};

console.log( obj.ordinaryFunction.hasOwnProperty( 'prototype' ) );  // true
console.log( obj.method.hasOwnProperty( 'prototype' ) );            // false

new obj.ordinaryFunction();     // All good !
new obj.method();               // TypeError: obj.method is not a constructor

示例 3

const obj = {
    method() {
        console.log( method );
    },
    ordinaryFunction: function ordinaryFunction() {
        console.log( ordinaryFunction );
    }
};

obj.ordinaryFunction()  // All good!
obj.method()            // ReferenceError: method is not defined

【讨论】:

  • 优秀的现代答案
【解决方案4】:

您的第一行是创建一个引用函数的对象。你可以这样引用它:

myFirstFunc(param);

但是你可以将它传递给另一个函数,因为它会像这样返回函数:

function mySecondFunction(func_param){}
mySecondFunction(myFirstFunc);

第二行只是创建了一个名为myFirstFunc 的函数,它的引用方式如下:

myFirstFunc(param);

And 的范围取决于它的声明位置,如果它是在任何其他函数之外声明的,则它属于全局范围。但是,您可以在另一个函数中声明一个函数。然后,该函数的范围仅限于在其内部声明的函数。

function functionOne(){
    function functionTwo(){}; //only accessed via the functionOne scope!
}

您的最后一个示例是创建函数实例,然后通过对象参数引用这些实例。所以这个:

function myFirstFunc(param){};

obj.myFirst = myFirstFunc(); //not right!
obj.myFirst = new myFirstFunc(); //right!

obj.myFirst('something here'); //now calling the function

表示您有一个引用函数实例的对象。这里的关键是,如果函数更改了您存储在obj.myFirst 中的reference,则不会更改。

虽然@kevin 基本上是对的,但 JS 中只有函数,您可以创建更像方法而不是函数的函数,例如:

function player(){

    this.stats = {
        health: 0,
        mana: 0,

        get : function(){
            return this;
        },

        set : function( stats ){
            this.health = stats.health;
            this.mana = stats.mana;
        }  
}    

然后您可以调用player.stats.get(),它会返回给您heathmana 的值。所以我认为getset 在这种情况下是player.stats 对象的方法。

【讨论】:

  • 这确实有帮助。如果我有疑问,我会进一步查找并进一步询问
  • 你评论说不能作为参数传递是不对的。
【解决方案5】:

函数执行语句列表示例:

 function add() { 
     var a = 2; 
     var b = 3;
     var c = a + b;
     return c;
 }

1) 方法是应用于对象示例的函数:

 var message = "Hello world!";
 var x = message.toUpperCase(); // .toUpperCase() is a built in function

2) 使用对象构造函数创建方法。一旦方法属于该对象,您就可以将其应用于该对象。示例:

function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
    this.name = function() {return this.firstName + " " + this.lastName;};
}

document.getElementById("demo").innerHTML = person.fullName(); // using the 
method 

方法的定义:方法是作为函数的对象的属性。方法的定义方式与定义普通函数的方式相同,只是它们必须作为对象的属性进行分配。

【讨论】:

    【解决方案6】:

    方法是对象的属性,其值为函数。方法以下列格式在对象上调用:object.method()。

    //这是一个名为developer的对象

     const developer = {
      name: 'Andrew',
      sayHello: function () {
        console.log('Hi there!');
      },
      favoriteLanguage: function (language) {
        console.log(`My favorite programming language is ${language}`);
      }
    };
    

    // favoriteLanguage: 和 sayHello: 和 name: 都是名为 developer 的对象中的属性

    现在假设您需要调用 favouriteLanguage 适当的女巫是对象内部的一个函数..

    你这样称呼它

    developer.favoriteLanguage('JavaScript');
    
    // My favorite programming language is JavaScript'
    

    所以我们称之为:developer.favoriteLanguage('JavaScript'); 它不是一个函数它不是一个对象?这是什么?它是一种方法

    【讨论】:

      【解决方案7】:
      var myFirstFunc = function(param) {
          //Do something
      };
      

      function myFirstFunc(param) {
          //Do something
      };
      

      (几乎)相同。第二个是(通常)只是简写。然而,正如这个 jsfiddle (http://jsfiddle.net/cu2Sy/) 所示,function myFirstFunc 将在输入封闭范围后立即定义函数,而 myFirstFunc = function 只会在执行到达该行时创建它。

      对于方法,它们有一个this 参数,即当前对象,所以:

      var obj = {};
      obj.func = function( ) {
          // here, "this" is obj
          this.test = 2;
      }
      console.log( obj.test ); // undefined
      obj.func( );
      console.log( obj.test ); // 2
      

      您显示的确切语法是因为您也可以这样做:

      function abc( ) {
          this.test = 2;
      }
      var obj = {};
      obj.func = abc;
      obj.func( ); // sets obj.test to 2
      

      但你不应该没有充分的理由。

      【讨论】:

      • 不是我的反对意见,但可能是因为第一个是 FunctionExpression,第二个是 FunctionDeclaration,区别在于它们的创建时间。第一个是在执行那行代码时,第二个是在执行任何代码之前创建的。
      • @user2059238:我想不出一个简单的好理由,但在具有回调的库函数中可能需要它(该函数可以作为参数传递),或者如果你有两种可能的行为可供选择(obj.doYourThing = isAngel ? myGoodFunc : myBadFunc),尽管第二种行为相当愚蠢。它还允许您定义私有函数,如果您使用闭包,它们也是公共的(但只有在您还使用优化编译器时才会有任何好处)。
      • 是的,因为你需要设置它!我的观点是你应该使用bob.setAge = function(){whatever} 而不是function blah(){whatever};bob.setAge=blah;。后者很糟糕,因为它会用变量污染范围,并留下一个仅在应用于对象时才有意义的函数(如果您在函数中使用this,则仅在应用于时 safe一个对象)
      【解决方案8】:

      ecma document

      4.3.31 方法: 作为属性值的函数

      注意当函数作为对象的方法调用时,对象是 作为 this 值传递给函数。

      很清楚:当你调用一个函数时,如果它隐含一个this指向一个对象)并且如果你不能在没有对象的情况下调用该函数,函数应该被命名为method

      【讨论】:

        猜你喜欢
        • 2016-12-04
        • 1970-01-01
        • 2011-07-26
        • 2021-06-16
        • 1970-01-01
        • 2015-01-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-06
        相关资源
        最近更新 更多