>  기사  >  웹 프론트엔드  >  함수를 구현하는 function()

함수를 구현하는 function()

WBOY
WBOY원래의
2023-09-04 09:41:201233검색

함수를 구현하는 function()

함수는 코드 문의 컨테이너이며 대괄호 () 연산자를 사용하여 호출할 수 있습니다. 함수 호출 시 함수 내의 명령문을 통해 특정 값에 접근할 수 있도록 호출 시 괄호 안에 매개변수를 전달할 수 있습니다.

다음 코드에서는 new 연산자를 사용하여 addNumbers 함수 objectone의 두 가지 버전을 생성합니다. 하나는 보다 일반적인 리터럴 모드를 사용합니다. 둘 다 두 개의 매개변수가 필요합니다. 각각의 경우에 함수를 호출하여 괄호 안의 인수를 new 运算符创建 addNumbers 函数 objectone 的两个版本,另一个版本使用更常见的文字模式。两者都需要两个参数。在每种情况下,我们都调用该函数,并在括号中传递参数 () 연산자에 전달합니다.

예: Sample76.html

으아악

함수는 값을 반환하거나, 객체를 구성하거나, 단순히 코드 실행을 위한 메커니즘으로 사용되는 데 사용될 수 있습니다. JavaScript에는 함수에 대한 다양한 용도가 있지만 가장 기본적인 형태에서 함수는 실행 가능한 문의 유일한 범위입니다.


函数()매개변수

Function() 构造函数采用无限数量的参数,但 Function() 생성자가 기대하는 마지막 매개변수는 함수 본문을 구성하는 명령문이 포함된 문자열입니다. 마지막 인수 이전에 생성자에 전달된 모든 인수는 생성 중인 함수에 사용할 수 있습니다. 여러 매개변수를 쉼표로 구분된 문자열로 보낼 수도 있습니다.

아래 코드에서는 Function() 생성자의 사용과 함수 개체를 인스턴스화하는 보다 일반적인 패턴을 대조합니다.

예: Sample77.html

으아악

JavaScript는 eval()을 사용하여 함수 논리가 포함된 문자열을 구문 분석하므로 Function() 构造函数,因为 JavaScript 将使用 eval() 来解析包含函数逻辑的字符串。许多人认为 eval() 생성자를 직접 활용하는 것은 권장되지 않거나 일반적으로 권장되지 않습니다. 많은 사람들이 eval()을 불필요한 오버헤드라고 생각합니다. 사용한다면 코드 설계에 결함이 있을 가능성이 높습니다.

new 키워드를 사용하지 않고 Function() 构造函数而不使用 new 关键字与仅使用构造函数创建函数对象具有相同的效果(new Function('x','return x')函数(('x','返回x') 생성자를 사용하는 것은 생성자만 사용하여 함수 객체(new Function('x','return x'))를 생성하는 것과 동일한 효과가 있습니다. > function(('x','return x'))를 사용합니다.

생성자를 직접 호출하면 클로저가 생성되지 않습니다. Function()


속성 및 메서드 Function()

함수 개체에는 다음과 같은 속성이 있습니다(상속된 속성 및 메서드 제외).

속성(

): Function.prototype;

  • 原型

함수 객체 인스턴스 속성 및 메서드

함수 객체 인스턴스에는 다음과 같은 속성과 메서드가 있습니다(상속된 속성과 메서드 제외).

인스턴스 속성(

):var myFunction = function(x, y, z) {}; myFunction.length;

  • 参数
  • 构造函数
  • 长度
인스턴스 메소드(

): var myFunction = function(x, y, z) {}; myFunction.toString();

  • apply()
  • call()
  • toString()

함수는 항상 값을 반환합니다

단순히 코드문을 실행하는 함수를 만드는 것도 가능하지만, 함수가 값을 반환하는 것도 일반적입니다. 다음 예에서는

함수에서 문자열을 반환합니다. sayHi

예: Sample78.html

으아악

함수에서 반환 값을 지정하지 않으면 명시적으로 값을 반환하지 않고 "yelp" 문자열을 콘솔에 기록하는

함수를 반환합니다. undefined。在以下示例中,我们调用 yelp

예: Sample79.html

으아악

여기서 기억해야 할 개념은 반환할 값을 명시적으로 제공하지 않더라도 모든 함수는 값을 반환한다는 것입니다. 반환 값을 지정하지 않으면 반환 값은

입니다. undefined


함수는 일급 시민입니다(구문뿐 아니라 값도 마찬가지입니다)

JavaScript에서 함수는 객체입니다. 이는 함수가 변수, 배열 또는 객체에 저장될 수 있음을 의미합니다. 또한 함수는 함수에 전달되거나 함수에서 반환될 수 있습니다. 함수는 객체이기 때문에 속성을 갖습니다. 이러한 모든 요소는 JavaScript에서 함수를 일급 시민으로 만듭니다.

예: Sample80.html

으아악

함수는 객체이므로 값이라는 점을 깨닫는 것이 중요합니다. JavaScript의 다른 표현식처럼 전달되거나 향상될 수 있습니다.


함수에 매개변수 전달

매개변수는 함수를 호출할 때 함수 범위에 값을 전달하는 도구입니다. 아래 예에서는

를 호출합니다. 두 개의 매개변수를 사용하도록 미리 정의했으므로 해당 범위 내에서 두 개의 추가 값을 사용할 수 있습니다. addFunction()

예: Sample81.html

으아악

일부 다른 프로그래밍 언어와는 달리 JavaScript에서는 매개변수를 허용하도록 함수가 정의된 경우에도 매개변수를 생략하는 것이 완전히 합법적입니다. 누락된 매개변수에는

값만 할당됩니다. 물론, 해당 매개변수 값을 생략할 경우 해당 기능이 제대로 동작하지 않을 수 있습니다. undefined

함수에 예상치 못한 매개변수(함수 생성 시 정의되지 않은 매개변수)를 전달해도 오류가 발생하지 않습니다. 그리고 이러한 매개변수는 모든 함수에서 사용할 수 있는

개체에서 액세스할 수 있습니다. arguments


thisarguments 值可用于所有函数

在所有函数的范围和主体内,thisarguments 值可用。

arguments 对象是一个类似数组的对象,包含传递给函数的所有参数。在下面的代码中,即使我们在定义函数时放弃指定参数,我们也可以依赖传递给函数的 arguments 数组来访问在调用时发送的参数。

示例:sample82.html

<!DOCTYPE html><html lang="en"><body><script>

	var add = function () {
		return arguments[0] + arguments[1];
	};

	console.log(add(4, 4)); // Returns 8.

</script></body></html>

this 关键字,传递给所有函数,是对包含该函数的对象的引用。正如您所期望的,对象中包含的作为属性(方法)的函数可以使用 this 来获取对父对象的引用。当函数定义在全局作用域时,this 的值为全局对象。查看以下代码并确保您了解 this 返回的内容。

示例:sample83.html

<!DOCTYPE html><html lang="en"><body><script>

	var myObject1 = {
		name: 'myObject1',
		myMethod: function () { console.log(this); }
	};

	myObject1.myMethod(); // Logs 'myObject1'.

	var myObject2 = function () { console.log(this); };

	myObject2(); // Logs window.

</script></body></html>

arguments.callee 属性

arguments 对象有一个名为 callee 的属性,它是对当前正在执行的函数的引用。此属性可用于从函数范围内引用该函数 (arguments.callee)a 自引用。在下面的代码中,我们使用此属性来获取对调用函数的引用。

示例:sample84.html

<!DOCTYPE html><html lang="en"><body><script>

	var foo = function foo() {
		console.log(arguments.callee); // Logs foo()
		// callee could be used to invoke recursively the foo function (arguments.callee())
	} ();

</script></body></html>

当需要递归调用函数时,这非常有用。


函数实例 length 属性和 arguments.length

arguments 对象具有唯一的 length 属性。虽然您可能认为这个 length 属性将为您提供已定义参数的数量,但它实际上提供了在调用期间发送到函数的参数数量。

示例:sample85.html

<!DOCTYPE html><html lang="en"><body><script>

	var myFunction = function (z, s, d) {
		return arguments.length;
	};

	console.log(myFunction()); // Logs 0 because no parameters were passed to the function.

</script></body></html>

使用所有 Function() 实例的 length 属性,我们实际上可以获取函数期望的参数总数。

示例:sample86.html

<!DOCTYPE html><html lang="en"><body><script>

	var myFunction = function (z, s, d, e, r, m, q) {
		return myFunction.length;
	};

	console.log(myFunction()); // Logs 7.

</script></body></html>

arguments.length 属性在 JavaScript 1.4 中已弃用,但可以从函数对象的 length 属性访问发送到函数的参数数量。接下来,您可以通过利用 callee 属性来首先获取对正在调用的函数的引用 (arguments.callee.length) 来获取长度值。


重新定义函数参数

函数参数可以直接在函数内部重新定义,也可以使用 arguments 数组。看一下这段代码:

示例:sample87.html

<!DOCTYPE html><html lang="en"><body><script>

	var foo = false;
	var bar = false;

	var myFunction = function (foo, bar) {
		arguments[0] = true;
		bar = true;
		console.log(arguments[0], bar); // Logs true true.
	}

	myFunction();

</script></body></html>

请注意,我可以使用 arguments 索引或直接为参数重新分配新值来重新定义 bar 参数的值。


在函数完成之前返回函数(取消函数执行)

通过使用带或不带值的 return 关键字,可以在调用期间随时取消函数。在下面的示例中,如果参数未定义或不是数字,我们将取消 add 函数。

示例:sample88.html

<!DOCTYPE html><html lang="en"><body><script>

	var add = function (x, y) {
		// If the parameters are not numbers, return error.
		if (typeof x !== 'number' || typeof y !== 'number') { return 'pass in numbers'; }
		return x + y;
	}
	console.log(add(3, 3)); // Logs 6.
	console.log(add('2', '2')); // Logs 'pass in numbers'.

</script></body></html>

这里要讲的概念是,您可以在函数执行过程中的任何时刻使用 return 关键字来取消函数的执行。


定义函数(语句、表达式或构造函数)

函数可以用三种不同的方式定义:函数构造函数、函数语句或函数表达式。在下面的示例中,我演示了每种变体。

示例:sample89.html

<!DOCTYPE html><html lang="en"><body><script>

	/* Function constructor: The last parameter is the function logic, 
	everything before it is a parameter. */
	var addConstructor = new Function('x', 'y', 'return x + y');

	// Function statement.
	function addStatement(x, y) {
		return x + y;
	}

	// Function expression.
	var addExpression = function (x, y) {
		return x + y;
	};

	console.log(addConstructor(2, 2), addStatement(2, 2), addExpression(2, 2)); // Logs '4 4 4'.

</script></body></html>

有人说函数还有第四种类型的定义,称为“命名函数表达式”。命名函数表达式只是一个包含名称的函数表达式(例如, var add = function add(x, y) {return x+y})。


调用函数(函数、方法、构造函数或 call()apply())

使用四种不同的场景或模式调用函数。

  • 作为函数
  • 作为一种方法
  • 作为构造函数
  • 使用 apply()call()

在下面的示例中,我们将检查每种调用模式。

示例:sample90.html

<!DOCTYPE html><html lang="en"><body><script>

	// Function pattern.
	var myFunction = function () { return 'foo' };
	console.log(myFunction()); // Logs 'foo'.

	// Method pattern.
	var myObject = { myFunction: function () { return 'bar'; } }
	console.log(myObject.myFunction()); // Logs 'bar'.

	// Constructor pattern.
	var Cody = function () {
		this.living = true;
		this.age = 33;
		this.gender = 'male';
		this.getGender = function () { return this.gender; };
	}
	var cody = new Cody(); // Invoke via the Cody constructor.
	console.log(cody); // Logs the cody object and properties.

	// apply() and call() pattern.
	var greet = {
		runGreet: function () {
			console.log(this.name, arguments[0], arguments[1]);
		}
	}

	var cody = { name: 'cody' };
	var lisa = { name: 'lisa' };

	// Invoke the runGreet function as if it were inside of the cody object.
	greet.runGreet.call(cody, 'foo', 'bar'); // Logs 'cody foo bar'.

	// Invoke the runGreet function as if it were inside of the lisa object.
	greet.runGreet.apply(lisa, ['foo', 'bar']); // Logs 'lisa foo bar'.

	/* Notice the difference between call() and apply() in how parameters are sent to the function being invoked. */

</script></body></html>

确保您了解所有四种调用模式,因为您将遇到的代码可能包含其中任何一种。


匿名函数

匿名函数是没有给出标识符的函数。匿名函数主要用于将函数作为参数传递给另一个函数。

示例:sample91.html

<!DOCTYPE html><html lang="en"><body><script>

	// function(){console.log('hi');}; // Anonymous function, but no way to invoke it.

	// Create a function that can invoke our anonymous function.
	var sayHi = function (f) {
		f(); // Invoke the anonymous function.
	}

	// Pass an anonymous function as a parameter.
	sayHi(function () { console.log('hi'); }); // Logs 'hi'.

</script></body></html>

自调用函数表达式

函数表达式(实际上是除从 Function() 构造函数创建的函数之外的任何函数)可以在定义后使用括号运算符立即调用。在以下示例中,我们创建 sayWord() 函数表达式,然后立即调用该函数。这被认为是一个自调用函数。

示例:sample92.html

<!DOCTYPE html><html lang="en"><body><script>

	var sayWord = function () { console.log('Word 2 yo mo!'); } (); // Logs 'Word 2 yo mo!'

</script></body></html>

自调用匿名函数语句

可以创建自调用的匿名函数语句。这称为自调用匿名函数。在下面的示例中,我们创建了几个立即调用的匿名函数。

示例:sample93.html

<!DOCTYPE html><html lang="en"><body><script>

	// Most commonly used/seen in the wild.
	(function (msg) {
		console.log(msg);
	})('Hi');

	// Slightly different, but achieving the same thing:
	(function (msg) {
		console.log(msg)
	} ('Hi'));

	// The shortest possible solution.
	!function sayHi(msg) { console.log(msg); } ('Hi');

	// FYI, this does NOT work!
	// function sayHi() {console.log('hi');}();

</script></body></html>

根据 ECMAScript 标准,如果要立即调用函数,则需要在函数两边加上括号(或将函数转换为表达式的任何内容)。


函数可以嵌套

函数可以无限期地嵌套在其他函数中。在下面的代码示例中,我们将 goo 函数封装在 bar 函数内部,该函数位于 foo 函数内部。

示例:sample94.html

<!DOCTYPE html><html lang="en"><body><script>

	var foo = function () {
		var bar = function () {
			var goo = function () {
				console.log(this); // Logs reference to head window object.
			} ();
		} ();
	} ();

</script></body></html>

这里的简单概念是函数可以嵌套,并且嵌套的深度没有限制。

请记住,嵌套函数的 this 的值将是 JavaScript 1.5、ECMA-262 第 3 版中的头对象(Web 浏览器中的 window 对象)。


将函数传递给函数以及从函数返回函数

如前所述,函数是 JavaScript 中的一等公民。由于函数是一个值,并且函数可以传递任何类型的值,因此函数可以传递给函数。接受和/或返回其他函数的函数有时称为“高阶函数”。

在下面的代码中,我们将一个匿名函数传递给 foo 函数,然后立即从 foo 函数返回。变量 bar 所指向的正是这个匿名函数,因为 foo 接受并返回匿名函数。

示例:sample95.html

<!DOCTYPE html><html lang="en"><body><script>

	// Functions can be sent to, and sent back from, functions.
	var foo = function (f) {
		return f;
	}

	var bar = foo(function () { console.log('Hi'); });

	bar(); // Logs 'Hi'.

</script></body></html>

因此,当调用 bar 时,它会调用传递给 foo() 函数的匿名函数,然后从 foo() 函数传回并从 bar 引用多变的。所有这些都是为了展示函数可以像任何其他值一样传递的事实。


在定义函数语句之前调用函数语句(又名函数提升)

函数语句可以在执行期间在其实际定义之前调用。这有点奇怪,但您应该意识到这一点,以便您可以利用它,或者至少知道当您遇到它时会发生什么。在下面的示例中,我在定义 sayYo()sum() 函数语句之前调用它们。

示例:sample96.html

<!DOCTYPE html><html lang="en"><body><script>

	// Example 1
	var speak = function () {
		sayYo(); // sayYo() has not been defined yet, but it can still be invoked, logs 'yo'.
		function sayYo() { console.log('Yo'); }
	} (); // Invoke

	// Example 2
	console.log(sum(2, 2)); // Invoke sum(), which is not defined yet, but can still be invoked.
	function sum(x, y) { return x + y; }

</script></body></html>

发生这种情况是因为在代码运行之前,函数语句被解释并添加到执行堆栈/上下文中。确保您在使用函数语句时意识到这一点。

定义为函数表达式的函数不会被提升。仅提升函数语句。


函数可以调用自身(又名递归)

函数调用自身是完全合法的。事实上,这经常被用在众所周知的编码模式中。在下面的代码中,我们启动 countDownFrom 函数,然后该函数通过函数名称 countDownFrom 调用自身。本质上,这会创建一个从 5 倒数到 0 的循环。

示例:sample97.html

<!DOCTYPE html><html lang="en"><body><script>

	var countDownFrom = function countDownFrom(num) {
		console.log(num);
		num--; // Change the parameter value.
		if (num < 0) { return false; } // If num < 0 return function with no recursion.
		// Could have also done arguments.callee(num) if it was an anonymous function.
		countDownFrom(num);
	};

	countDownFrom(5); // Kick off the function, which logs separately 5, 4, 3, 2, 1, 0.

</script></body></html>

您应该意识到,函数调用自身(也称为递归)或重复执行此操作是很自然的。


结论

函数是 JavaScript 最常用的方面之一,希望您现在对如何使用它们有了更好的了解。

위 내용은 함수를 구현하는 function()의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.