> 웹 프론트엔드 > JS 튜토리얼 > JavaScript의 기능에 대한 깊은 이해

JavaScript의 기능에 대한 깊은 이해

黄舟
풀어 주다: 2017-03-02 14:56:27
원래의
1333명이 탐색했습니다.

이 글은 웹 개발자가 반드시 알아야 할 모든 JavaScript 기능에 대한 기본 지식을 제공하는 것을 목표로 합니다.

소프트웨어 개발자에게 함수는 환상의 세계가 아닙니다. 일상 활동에 코딩이 조금이라도 포함된다면 하루가 끝나면 하나 이상의 기능을 생성/수정해야 합니다.

간단히 말하면 함수는 연산을 수행하는 명령문의 집합입니다. 함수에는 일부 입력 매개변수(함수 본문에 사용됨)가 있을 수 있으며 실행 후 값을 반환할 수 있습니다.

JavaScript 함수에도 이러한 속성이 있지만 단순한 일반 함수는 아닙니다. JavaScript 함수는 객체입니다. JavaScript 개체에 대해 제가 쓴 기사를 확인해 보세요. 여기서 JavaScript의 거의 모든 것이 개체라고 언급했습니다.

객체로서 JavaScript 함수는 속성과 기타 함수(메서드)를 가질 수 있습니다. JavaScript의 일반적인 함수 정의를 살펴보겠습니다.

아아아아

맞아요. 위 기능은 단순히 블로그 방문자를 환영하는 역할이므로 거창한 내용은 없습니다. 하지만 JavaScript 함수가 어떤 모습인지 보여줍니다. 함수 정의는 function 키워드로 시작하고 그 뒤에 함수 이름, 공백 또는 매개변수가 있는 괄호가 옵니다. 실제 함수 코드(JavaScript 문)는 중괄호 { } 쌍으로 묶여 있습니다. 함수의 경우 return 문은 선택 사항입니다. JavaScript 함수는 항상 값을 반환합니다. function 본문에 return 문이 없으면 function은 정의되지 않은 값을 반환합니다.

다음 코드는 방문자 이름을 매개변수로 전달하는 함수를 호출합니다.

function myNotSoGreatFunc(visitor) {
   console.log("Welcome to Code Morning Mr. " + visitor);
}
로그인 후 복사

지금까지 우리는 함수의 아주 기본적인 특성을 이해했습니다. 이제 JavaScript 함수의 몇 가지 고급 개념을 살펴보겠습니다.

익명 함수

JavaScript 함수는 익명이 될 수 있습니다. 즉, 함수 선언에서 함수 이름을 생략할 수 있습니다. 그러나 함수는 변수에 저장되어야 합니다.

myNotSoGreatFunc("Bob Martin");
// Output: 
// Welcome to Code Morning Mr. Bob Martin.
로그인 후 복사

위 구문을 함수 표현식이라고도 합니다. addNumbers 변수를 함수명으로 사용하여 아래와 같이 함수를 호출할 수 있습니다.

var addNumbers = function (x, y) { return x + y; }
로그인 후 복사

함수 표현식은 함수를 다른 함수에 매개변수로 전달하려는 경우 매우 편리합니다. 간단한 예를 사용하여 이를 이해해 보겠습니다.

var sum = addNumbers(2, 3);
로그인 후 복사

먼저 두 개의 익명 함수를 만들었습니다. 첫 번째는 두 숫자의 덧셈을 반환하고 두 번째는 두 숫자의 곱셈을 반환합니다. 아주 간단해서 과시할 것이 없습니다. 그런 다음 함수를 첫 번째 인수로 받아들이고 그 뒤에 두 개의 숫자를 받아들이는 두 개의 인수를 받아들이는 함수 calculate를 정의합니다.

모든 함수를 첫 번째 인수로 전달하여 계산 함수를 호출할 수 있습니다.

var add = function (first, second) { return first + second };
var multiply = function (first, second) { return first * second };

function calculate(fun, a, b) {
    return fun(a, b);
}
로그인 후 복사

함수를 인수로 전달하는 것이 얼마나 쉬운지 알 수 있습니다. 이 패턴은 AJAX 호출이 완료된 후 성공 또는 실패 시나리오를 처리하기 위해 콜백 함수를 전달할 때 AJAX에서 많이 사용됩니다.

매개변수에 대한 추가 정보

JavaScript는 함수 매개변수를 전달하거나 액세스할 때 매우 유연합니다. 함수 매개변수를 조작할 수 있는 방법을 살펴보겠습니다.

매개변수 누락

함수 호출 시 함수에 필요한 것보다 적거나 많은 매개변수가 있을 수 있습니다. 선언된 것보다 적은 수의 인수를 사용하여 함수를 호출하면 누락된 인수가 정의되지 않음으로 설정됩니다.

var sum = calculate(add, 2, 3); // sum = 5
var multiplication = calculate(multiply, 2, 3); // multiplication = 6
로그인 후 복사

인수 객체

모든 JavaScript 함수에는 함수 호출 중에 전달된 인수 배열인 arguments이라는 특수 객체가 있습니다. 이 객체는 개별 매개변수에 액세스하거나 함수에 전달된 매개변수의 총 개수를 얻는 데 사용할 수 있습니다.

function callMe(a, b, c) {
   console.log("c is " + typeof c);
}

callMe("Code", "Morning"); 
// Output: "c is undefined"
callMe("Learn", "JavaScript", "Functions"); 
// Output: "c is string"
로그인 후 복사

이 함수는 매개변수가 전달되지 않는다고 가정하지만 앞서 말했듯이 JavaScript 함수에 매개변수를 원하는 만큼 전달할 수 있습니다. 이 함수를 다음과 같이 호출할 수 있습니다.

function callMe() {
   var i;
   for (i = 0; i < arguments.length; i++) {
      console.log(arguments[i]);
   }
   console.log("Total arguments passed: " + arguments.length);
}
로그인 후 복사

각 인수는 arguments 객체의 배열 항목으로 액세스할 수 있습니다. 함수에 전달된 arguments의 총 개수는 인수.길이 속성에서 확인할 수 있습니다.

기본 매개변수

C++ 또는 C#프로그래머이신가요? 기본 매개변수를 사용하는 함수를 본 적이 있나요? 아마도 당신은 그렇다고 대답할 것입니다! ECMAScript 6은 JavaScript의 이러한 기능을 제공합니다. 즉, 기본 매개변수를 사용하여 함수를 정의할 수 있습니다.

callMe("Code", "Morning", "Mr. Programmer");
// Output":
// Code
// Morning
// Mr. Programmer
// Total arguments passed: 3
로그인 후 복사

블로그 방문자에게 정중하게 인사하는 기능입니다. nameprofession 두 개의 매개변수가 있으며 메시지 상자에 환영 메시지를 표시합니다. 호출 중에 인수가 전달되지 않으면(또는 "정의되지 않음") 두 번째 인수가 기본값을 사용합니다.

function greetMyVisitors(name, profession = "The cool programmer") {
    alert("Welcome Mr. " + name + ", " + profession);
}
로그인 후 복사

중첩 함수

함수 내부에는 하나 이상의 함수가 포함될 수 있습니다. 내부 함수에는 내부적으로 다시 함수가 포함될 수 있습니다. 다음 작업을 살펴보겠습니다.

function wakeUpAndCode() {
   function wakeUp() {
      console.log("I just woke up");
   }

   function code() {
      console.log("I am ready to code now");
   }

   wakeUp();
   code();
}

wakeUpAndCode();

// Output:
// I just woke up
// I am ready to code now
로그인 후 복사

函数wakeUpAndCode包含两个内部函数wakeUp和code。当调用wakeUpAndCode时,函数主体开始执行函数主体。在外部函数中只有两个可执行语句,调用wakeUpcode的方法。调用wakeUp将执行内部wakeUp函数,这将写入string“I just woke up”到控制台。调用code将会写入“I am ready to code now”string到控制台。

内部函数可以访问所有外部函数的变量和参数。内部函数是函数内部某种private实现,并且不能从外部函数以外被调用。内部函数的使用生成了JavaScript闭包,这个我将另起一篇文章讨论。

立即执行函数表达式(IIFE,发音iffy)

IIFE是被立即调用执行的匿名函数表达式。IIFE看上去像这样:

(function() {
   // Your awesome code here
}());
로그인 후 복사

所有你要做的就是创建一个匿名函数,在函数定义后马上放一对圆括号以调用函数,最后将所有代码封装在另一对圆括号中。最外层的括号将它里面的所有一切转变成一个表达式,因为括号不能包含JavaScript语句。函数定义后面的圆括号则立即调用函数。

IIFE块中定义的任何变量或函数对块而言是本地的,并且不能被这个范围以外的任何代码改变。

看看IIFE的这个例子。此函数没有调用也会自动执行。

(function() {
   console.log("I run on my own.");
}());
로그인 후 복사

只需在plunker中复制并粘贴代码,看看在浏览器控制台中的输出。如果你不知道去哪里找浏览器控制台,那么只要在浏览器窗口中按下F12就会出现开发者工具。跳转console选项卡以查看console.log语句的所有输出。

IIFE是一个在代码中创建局部范围的很好方法。它们可以帮助你保护变量和函数,以避免被应用程序的其他部分更改或覆盖。JavaScript中IIFE的其他优势?它们是如何解决全局范围污染问题的?欢迎点击查看我关于立即执行函数表达式的文章。

构造函数

函数可以充当构造器的角色,并且可以使用构造函数来创建新的对象。这是使JavaScript面向对象的特点之一。使用构造函数的好处是,你将能够通过预定义的属性和方法,创造尽可能多的对象。如果你由此关联到其他语言中的类和对象,那么你做的对。

让我们创建一个带有一些属性和方法的构造函数Programmer。你可以假设它在你最喜欢的语言中是一个类。

function Programmer(name, company, expertise) {
   this.name = name;
   this.company = company;
   this.expertise = expertise;

   this.writeCode = function() {
      console.log("Writing some public static thing..");
   }

   this.makeSkypeCall = function() {
      console.log("Making skype call..");
   }

   this.doSalsa = function() {
      console.log("I&#39;m a programmer, I can only do Gangnam style..");
   }

   this.canWriteJavaScript = function() {
      return expertise === "JavaScript";
   }
}
로그인 후 복사

函数有三个参数,并创建了一个具有三个属性和四种方法的对象。我不认为上面的代码需要任何解释。此外,我可以创建任意数量程序员对象。

var javaProgrammer = new Programmer("Mohit Srivastava", "Infosys", "Java");
var dotnetProgrammer = new Programmer("Atul Mishra", "Prowareness", ".NET");
로그인 후 복사

虽然也可以创建一个使用对象文本语法带有相同属性和方法的对象,但我们需要多次编写相同的代码,这可不是什么伟大的实践。如果你知道编程DRY原则,那么你就不会不赞同我。构造函数使得可以一次定义对象,并创建真正的实例,无论什么时候你想要。

警告!

始终使用new关键字来从构造器创建新的对象。忘记了new而像这个创建一个实例->

var jsProgrammer = Programmer("Douglas Crockford", "Yahoo", "JavaScript")
로그인 후 복사

最终将添加所有属性和方法到全局的window对象,哇哦,这将是太可怕了。原因是,除非明确指定,否则“this”指向全局的window对象。使用new 设置“this”上下文到被创建的当前对象。

然而,有一种变通方法可以来克服这个问题。你可以改变构造函数的实现以使域安全,然后在创建新的对象时,你就可以愉快地忽略new 关键字了。请参见以下修改了的构造函数代码。为了便于查看,我已删除了一些方法。

function Programmer(name, company, expertise) {
   if(!(this instanceof Programmer)) {
      return new Programmer(name, company, expertise);
   }

   this.name = name;
   this.company = company;
   this.expertise = expertise;

   this.writeCode = function() {
      console.log("Writing some public static thing..");
   }
}
로그인 후 복사

if 条件检查了this 对象是否是Programmer的一个实例。如果不是,它会创建一个新的Programmer对象,并通过再次调用构造器返回相同的内容。

注意:你无法在不使用’new’关键字的情况下,在Strict模式下从构造器创建一个新的对象。Strict模式强制一些编码准则,并且在你写的东西不安全的情况下会抛出错误。要启用Strict模式,你只需要添加在你的代码开头添加字符串 ‘use strict’。在Strict模式下运行代码是一个良好的实践。

&#39;use strict&#39;
 function doSomething() { ... }
 ....
 ....
로그인 후 복사

在这篇文章中,我几乎已经涵盖了有关函数的所有内容。函数被认为是JavaScript中的一等公民。理解函数可能是最重要的事情,如果你想掌握JavaScript的话。

欢迎各位指正。

위 내용은 JavaScript의 기능에 대한 심층적인 이해 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿