많은 기존 언어(C/C++/Java/C# 등)에서 함수는 언어 키워드를 사용하여 함수를 선언한 다음 함수를 전달해야 하는 경우에만 호출할 수 있습니다. 매개변수로 값을 다른 함수에 할당하거나, 지역변수에 할당하거나, 반환값으로 사용하려면 함수포인터, 델리게이트 등 특별한 메소드를 거쳐야 합니다.
JavaScript 세계에서 함수는 전통적인 함수(선언 및 호출)를 사용하는 모든 방법을 가질 뿐만 아니라 값을 할당하고 매개변수를 전달하고 간단한 값처럼 반환할 수도 있습니다. 일류 함수라고 부를 수도 있습니다. 뿐만 아니라 JavaScript의 함수는 클래스의 생성자 역할도 하며 Function 클래스의 인스턴스이기도 합니다. 이러한 다중 ID는 JavaScript 기능을 매우 중요하게 만듭니다.
1. 입문용 자바스크립트 함수
다른 언어와 마찬가지로 자바스크립트 함수도 먼저 선언하고 사용하는 원칙을 따릅니다. 함수 이름은 문자, 숫자, 밑줄 또는 $만 포함할 수 있으며 숫자로 시작할 수 없습니다. 함수를 선언하는 두 가지 일반적인 방법이 있습니다:
코드는 다음과 같습니다:
// 直接声明函数myfunc function myfunc(/* arguments */) { } // 把匿名函数赋值给本地变量myfunc var myfunc = function(/* arguments */) { }
위의 두 가지 함수 선언 방법에는 미묘한 차이가 있습니다. 첫 번째 방법은 선언될 때 이름이 지정된 함수입니다. 호출되기 전, 호출 후에 실행되지 않는 위치(예: return 문 뒤 또는 절대 참이 아닌 분기)도 전체 범위에서 액세스할 수 있습니다. 두 번째 방법은 익명 함수를 할당하는 것입니다. 엄밀히 말하면 이것은 함수 선언이 아니라 함수 표현식입니다. 이 함수는 할당 전에는 어떤 코드에서도 액세스할 수 없습니다. 즉, 호출하기 전에 할당을 완료해야 합니다. 그렇지 않으면 호출할 때 오류가 발생합니다. "TypeError: 정의되지 않음은 함수가 아닙니다." 예:
코드는 다음과 같습니다:
myfunc1(); // 能够正常调用,因为myfunc1采用直接声明的方式 function myfunc1() { } myfunc2(); // 出错 TypeError: undefined is not a function var myfunc2 = function() { };
함수의 기본 호출 방법은 한 쌍의 괄호를 사용하는 전통적인 언어의 방법과 동일합니다: myfunc(). JavaScript 함수는 직접 또는 간접 재귀 호출도 지원합니다. 예를 들어 클래식 Fibonacci 함수는 다음과 같이 JavaScript로 구현될 수 있습니다.
코드는 다음과 같습니다.
function fib(n) { if (n == 1 || n == 2) { return 1; } else { return fib(n - 2) + fib(n - 1); } }
JavaScript의 함수는 가변 길이 매개변수를 처리할 수 있습니다. 함수 내의 인수라는 지역 변수는 호출 시 전달된 모든 매개변수를 포함하는 배열과 유사한 객체입니다. 길이 속성은 매개변수 수를 나타냅니다. 예:
코드는 다음과 같습니다.
function test() { alert(arguments.length); } test(1); // 1 test(1, 'a'); // 2 test(true, [], {}); // 3 利用arguments可以实现类似C语言printf的功能,也可以用来实现方法的多态。
2. 고급 JavaScript 함수
2.1 익명 함수 및 중첩 함수
JavaScript에서는 이름 없이 an이라는 함수를 선언할 수 있습니다. 익명 함수(Anonymouse) 함수). 동시에 JavaScript에서는 중첩 함수라고 하는 함수 내부에서 함수를 선언할 수도 있습니다. 중첩 함수의 범위는 전체 상위 함수입니다.
이전 함수 선언 섹션에서는 익명 함수와 중첩 함수의 사용을 살펴보았습니다. 익명 함수에는 이름이 없으므로 컨텍스트를 오염시키는 새 변수를 도입하지 않고 새 변수 범위를 가져오므로 익명입니다. 지구 환경 오염을 방지하기 위해 기능이 자주 사용됩니다.
자바스크립트 런타임에는 특별한 전역 환경(전역 개체)이 있습니다. 이 개체는 전역 함수와 변수를 저장하며, 실제 개발에서는 실수로 전역 개체를 입력하는 경우 여러 타사 라이브러리를 사용하는 경우가 많습니다. 중복된 변수나 함수 선언은 코드 실행에 혼란을 야기합니다. 예를 들어, 두 개의 js 파일이 차례로 도입되고 각각은 내부 사용을 위해 자체 함수 로그를 정의하며 두 번째로 도입된 함수는 첫 번째 정의를 덮어쓰며 후속 실행에서 로그 함수를 호출하면 문제가 발생하지 않을 수 있습니다. 오류를 유발합니다. 이때 익명 함수를 사용하여 전체 js에서 로직을 래핑하면 이 오류를 피할 수 있습니다. 이 방법은 대부분의 오픈 소스 js 라이브러리에서 사용되었습니다.
코드는 다음과 같습니다.
(function() { // 匿名函数 function log(msg) { console.log(msg); } // 其他代码 }()); // 立即执行
위 코드는 간단한 예입니다. 로그 함수의 범위는 이 익명 함수로 제한되며 익명 함수는 한 쌍의 괄호()로 둘러싸여 있습니다. 함수 표현식 표현식의 값은 함수이며 그 뒤에는 함수가 즉시 실행될 것임을 나타내는 한 쌍의 괄호가 있어 원래 코드가 정상적으로 실행될 수 있습니다. 그러나 이렇게 선언된 함수, var를 통해 선언된 변수 등은 내부적이므로 익명 함수가 아닌 다른 코드에서는 접근할 수 없습니다. 일부 기능을 인터페이스로 노출해야 하는 경우에는 여러 가지 방법이 있습니다.
코드는 다음과 같습니다.
var mylib = (function(global) { function log(msg) { console.log(msg); } log1 = log; // 法一:利用没有var的变量声明的默认行为,在log1成为全局变量(不推荐) global.log2 = log; // 法二:直接在全局对象上添加log2属性,赋值为log函数(推荐) return { // 法三:通过匿名函数返回值得到一系列接口函数集合对象,赋值给全局变量mylib(推荐) log: log }; }(window));
2.2 고차 함수(High-order Function)
함수가 다음과 같은 경우 매개변수나 반환값으로 사용되는 경우를 고차함수라고 합니다. 자바스크립트에서 함수를 고차함수로 사용할 수 있는 것도 첫 번째 유형의 함수입니다. 아래에서는 이 두 가지 사용 방법을 각각 분석해 보겠습니다.
代码如下:
function negative(n) { return -n; // 取n的相反值 } function square(n) { return n*n; // n的平方 } function process(nums, callback) { var result = []; for(var i = 0, length = nums.length; i < length; i++) { result[i] = callback(nums[i]); // 对数组nums中的所有元素传递给callback进行处理,将返回值作为结果保存 } return result; } var nums = [-3, -2, -1, 0, 1, 2, 3, 4]; var n_neg = process(nums, negative); // n_neg = [3, 2, 1, 0, -1, -2, -3, -4]; var n_square = process(nums, square); // n_square = [9, 4, 1, 0, 1, 4, 9, 16];
以上代码展示了把函数作为参数传入另一个函数process调用的示例,在process函数的实现中,把callback作为一个黑盒子看待,负责把参数传给它,然后获取返回值,在调用之前并不清楚callback的具体实现。只有当执行到20行和22行时,callback才被分别代表negative或square,分别对每个元素进行取相反值或平方值的操作。
代码如下:
function generator() { var i = 0; return function() { return i++; }; } var gen1 = generator(); // 得到一个自然数生成器 var gen2 = generator(); // 得到另一个自然数生成器 var r1 = gen1(); // r1 = 0 var r2 = gen1(); // r2 = 1 var r3 = gen2(); // r3 = 0 var r4 = gen2(); // r4 = 1
上面的代码展示了把函数作为返回值的示例,generator是一个自然数生成器函数,返回值是一个自然数生成函数。每次调用generator时都会把一个匿名函数作为结果返回,这个匿名函数在被实际调用时依次返回每个自然数。在generator里的变量i在每次调用这个匿名函数时都会自增1,这其实就是一个闭包。下面我们来介绍一下闭包.
2.3 闭包(Closure)
闭包(Closure)并不是一个新鲜的概念,很多函数式语言中都使用了闭包。在JavaScript中,当你在内嵌函数中使用外部函数作用域内的变量时,就是使用了闭包。用一个常用的类比来解释闭包和类(Class)的关系:类是带函数的数据,闭包是带数据的函数。
闭包中使用的变量有一个特性,就是它们不在父函数返回时释放,而是随着闭包生命周期的结束而结束。比如像上一节中generator的例子,gen1和gen2分别使用了相互独立的变量i(在gen1的i自增1的时候,gen2的i并不受影响,反之亦然),只要gen1或gen2这两个变量没有被JavaScript引擎垃圾回收,他们各自的变量i就不会被释放。在JavaScript编程中,不知不觉就会使用到闭包,闭包的这个特性在带来易用的同时,也容易带来类似内存泄露的问题。例如:
代码如下:
var elem = document.getElementById('test'); elem.addEventListener('click', function() { alert('You clicked ' + elem.tagName); });
这段代码的作用是点击一个结点时显示它的标签名称,它把一个匿名函数注册为一个DOM结点的click事件处理函数,函数内引用了一个DOM对象elem,就形成了闭包。这就会产生一个循环引用,即:DOM->闭包->DOM->闭包...DOM对象在闭包释放之前不会被释放;而闭包作为DOM对象的事件处理函数存在,所以在DOM对象释放前闭包不会释放,即使DOM对象在DOM tree中删除,由于这个循环引用的存在,DOM对象和闭包都不会被释放。可以用下面的方法可以避免这种内存泄露:
代码如下:
var elem = document.getElementById('test'); elem.addEventListener('click', function() { alert('You clicked ' + this.tagName); // 不再直接引用elem变量 });
上面这段代码中用this代替elem(在DOM事件处理函数中this指针指向DOM元素本身),让JS运行时不再认为这个函数中使用了父类的变量,因此不再形成闭包。
闭包还会带来很多类似的内存泄露问题,只有在写代码的时候着重注意一下闭包,尽量避免此类的问题产生。
2.4 类构造函数
JavaScript的函数同时作为类的构造函数,因此只要声明一个函数就可以使用new关键字创建类的实例。
代码如下:
function Person(name) { this.name = name; this.toString = function() { return 'Hello, ' + this.name + '!'; }; } var p = new Person('Ghostheaven');
alert(p); // Hello, Ghostheaven! 在以上实例中Person函数作为类的构造函数使用,此时this指向新创建的实例对象,可以为实例增加属性和方法,关于详细的面向对象的JavaScript编程可以参考这篇文章。这里我想要说的是,JavaScript函数作为类构造函数使用时的返回值问题。
代码如下:
function MyClass(name) { this.name = name; return name; // 构造函数的返回值? } var obj1 = new MyClass('foo'); var obj2 = MyClass('foo'); var obj3 = new MyClass({}); var obj4 = MyClass({});
上面的构造函数比较特别,有返回语句,那么obj1~obj4分别指向什么对象呢?实际结果是这样的:
复制代码 代码如下:
obj1 = MyClass对象 obj2 = 'foo' obj3 = {} obj4 = {}
具体原因这篇文章有解释,本文不再赘述,由于带返回值的构造函数会产生奇怪的结果,因此不要在构造函数中调用有返回值的返回语句(空return可以)。
三、JavaScript函数妖怪级
欢迎来到妖怪级函数授课区,在这里会交给你如何淡定自如地面对老怪。。。
3.1 Function类
在JavaScript运行时中有一个内建的类叫做Function,用function关键字声明一个函数其实是创建Function类对象的一种简写形式,所有的函数都拥有Function类所有的方法,例如call、apply、bind等等,可以通过instanceof关键字来验证这个说法。
既然Function是一个类,那么它的构造函数就是Function(它本身也是Function类的对象),应该可以通过new关键字来生成一个函数对象。第一个妖怪来了,那就是如何用Function类构造一个函数。Function的语法如下:
代码如下:
new Function ([arg1[, arg2[, ... argN]],] functionBody)
其中arg1, arg2, ... argN是字符串,代表参数名称,functionBody也是字符串,表示函数体,前面的参数名称是可多可少的,Function的构造函数会把最后一个参数当做函数体,前面的都当做参数处理。
代码如下:
var func1 = new Function('name', 'return "Hello, " + name + "!";'); func1('Ghostheaven'); // Hello, Ghostheaven!
以上方法就通过Function构造了一个函数,这个函数跟其他用function关键字声明的函数一模一样。
看到这儿,很多人可能会问为什么需要这样一个妖怪呢?“存在的即是合理的”,Function类有它独特的用途,你可以利用它动态地生成各种函数逻辑,或者代替eval函数的功能,而且能保持当前环境不会被污染*。
3.2 自更新函数(Self-update Function)
在很多语言中,函数一旦声明过就不能再次声明同名函数,否则会产生语法错误,而在JavaScript中的函数不仅可以重复声明,而且还可以自己更新自己。自己吃自己的妖怪来了!
代码如下:
function selfUpdate() { window.selfUpdate = function() { alert('second run!'); }; alert('first run!'); } selfUpdate(); // first run! selfUpdate(); // second run! 这种函数可以用于只运行一次的逻辑,在第一次运行之后就整个替换成一段新的逻辑。
小结
JavaScript的函数灰常强大,在漂亮地解决很多问题的同时,也带来很多负面问题。妖怪级别的函数使用方法通常是一些鲜为人知的用法,除非特别必要不要轻易使用,否则会造成代码阅读困难,影响团队开发效率。
* 在新的ECMAScript中引入了严格模式,在严格模式下eval函数受到了很大的限制,也能够保证环境不被污染
위 내용은 JavaScript 함수에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구

드림위버 CS6
시각적 웹 개발 도구

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
