为什么传递未定义的javascript函数参数?

时间:2017-07-21 22:01:18

标签: javascript anonymous-function

所以我正在学习Javascript,我看到了这段代码:

var apple = {//... an object with some properties};
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});

其中someMethod和a_property_of_apple是有效的方法和属性。

我的问题与匿名函数的参数b有关,该参数未在其他任何地方声明或定义:

function (b) {return ...

这里发生了什么?什么是b以及它为什么被使用?

提前为问题的基本性质道歉。如果有人只想在我身上放下一些专注的术语来阅读,那将是一个很好的解释。

4 个答案:

答案 0 :(得分:2)

匿名函数是传递给callback function调用的apple.method()

apple.method()将在执行期间的某个时刻调用该匿名函数(或将其传递给另一个函数)。每当它被调用时,它将被调用,该参数将在回调中可用。您可以将其称为b,或response,或任何您想要的(逻辑名称最佳),并且能够在匿名函数中使用它。

您应该在MDN上阅读Callback functions

编辑:我会向你解释这些部分

var apple = {}这是对象的定义

var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});定义水果等于调用apple.someMethod(...)

的返回值

apple.someMethod(function (b) {return b.a_property_of_apple});apple.someMethod的调用,function (b) {return b.a_property_of_apple}是唯一的参数。

匿名函数b中的function (b) {return b.a_property_of_apple}参数将被传递给apple.someMethod中的调用。

以下是一个示例代码段。

// define apple
var apple = {
    // define method
	someMethod: function( callback ) {
		var obj = {
			a_property_of_apple: "Eat me!" // this will be returned
		}

        // return the invocation of callback with obj as argument
		return callback(obj);
	}
}

var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});

console.log(fruit);

编辑:好的,将使用稍微不那么抽象的东西作为例子。

// notice employees being passed to this function
// that is called an argument and is usable inside the function
var orginization = function( employees ) {
   // this will take the empoyees argument and assign it to this.employees
	// or set this.employees to an empty array if there is no employees argument
	this.employees = employees || [ ];

	// this is a method ( a method is a function on an object )
	// this function takes 3 arguments
	this.addEmployee = function( employee ) {
		// we use the 3 arguments to push a new object with title, name, and salary
		// properties provided by the function arguments
		this.employees.push( employee );
	}

	// this method returns the value stored in this.employees
	this.getEmployees = function() {
		return this.employees;
	}
}

// this is a variable an array of employees only containing 1 employee
// i will use it in the creation of my new orginization
var employess = [
	{
		title: "CEO",
		name: "Enola",
		salary: "$$$$$$$"
	}
];


// i use the new to create learningInc from originization( employees )
// originization is a constructor function which creates an object
// with methods and properties found on the constructor
var learningInc = new orginization( employess );


// console.log learningInc.getEmployees() an you will see still only the CEO
// works here

console.log( "before newHire: ", learningInc.getEmployees() );

// lets make a newHire
var newHire = {
	title: "Peon",
	name: "Sadly McFrownFace",
	salary: "$"
};

// add the newHire to the employess of learningInc wth out getEmployees() method
learningInc.addEmployee( newHire );


// log the new value of learningInc.getEmployees and you see we now have 2 employees
console.log(  "after newHire: ", learningInc.getEmployees() );

好的,现在注意这一行var learningInc = new orginization( employess );

我将作为参数传递给此函数的employees变量用于此函数var orginization = function( employees ) { ... }

希望得到这个帮助。

答案 1 :(得分:0)

这里有几个概念在起作用

  1. 功能声明vs function expressions;您可以使用function作为运算符来定义函数,并将函数分配给标识符并像任何普通对象一样传递它
  2. 回调;你可以将函数CB传递给另一个由A调用的函数A(由A 定义)
  3. 传递没有标识符的内容
  4. 功能声明

    // declare function
    function foo(argFoo) {
        console.log('foo', argFoo);
    }
    
    // invoke function
    foo('was declared'); // "foo" "was declared"
    

    功能表达

    // express function
    var bar = function (argBar) {
        console.log('bar', argBar);
    };
    
    // invoke function
    bar('was expressed'); // "bar" "was expressed"
    

    回调

    function fizz(callback) {
        console.log('first I fizz');
        callback();
    }
    
    function buzz() {
        console.log('then I buzz');
    }
    
    fizz(buzz);
    // "first I fizz"
    // "then I buzz"
    

    没有标识符的传递
    基本上,就地定义事物

    // say we have some fn fizzbuzz
    function fizzbuzz(foo) {
        console.log(foo);
    }
    
    // we could pre-define what we want to pass to it
    var i = 1;
    fizzbuzz(i); // 1
    
    // or we could pass directly
    fizzbuzz(1); // 1
    
    // with anything we like
    fizzbuzz({some: 'object'}); // {some: "object"}
    
    // even a function
    fizzbuzz(function () {}); // function () {}
    

答案 2 :(得分:0)

  

我的问题与匿名函数的参数b有关,该函数未在其他任何地方声明或定义:这里发生了什么?   什么是b以及它为什么被使用?

为什么你说它没有被宣布?它在那里宣布。考虑一下这个简单的JavaScript函数:

function doSomething(a, b){
  //do something here;
}

在此代码中,我们正在创建一个函数,为其命名" doSomething",并为其ab声明两个参数。这就是我们在JavaScript中声明函数参数的方法。现在你的例子:

function (b) {return ...

完全相同,除了我们没有给这个函数命名,这意味着它是一个匿名函数。这是唯一的区别,但它的参数b就像任何标准函数一样被声明。所以这里没有什么特别之处,它是一个标准的函数参数,并且可以这样使用。

答案 3 :(得分:0)

也许如果我将发生的事情分解为更易读的代码,你可以看到发生了什么。

someMethod是一个将函数作为参数的方法。当像下面这样分解时,这更容易看到。

由someMethod来确定他们对该功能的处理方式。在此示例中,我正在执行传递到someMethod的函数并将其传递给this上下文。

var apple = {
  name: 'Apple',
  someMethod: function(func) {
    return func(this);
  }
};

function getName (b) {
  return b.name;
};

const name = apple.someMethod(getName); // Apple

对于您的问题:b被定义为匿名函数的第一个参数。当代码在上面分解时,这一点会更清楚地表达出来。但你也可以这样表达:

const name = apple.someMethod(function(x) { return x.name; }); // Apple

或者像这样使用ES6:

const name = apple.someMethod(x => x.name); // Apple