이 객체는 함수의 확장입니다. 가장 중요한 것은 프로토타입의 도움말 문서에 구체적으로 다음과 같이 나와 있습니다. 프로토타입은 함수의 한 측면에만 문제가 있습니다. 즉, 클래스 상속에서 랩 메소드도 매우 중요합니다. 랩 메소드를 사용하여 상위 클래스와 동일한 이름의 메소드를 호출합니다. argumentNames bind bindAsEventListener curry defer delay methodize wrap
//Object 객체의 확장 메소드를 통해 Function 프로토타입 확장 Object.extend(Function.prototype, (function() { var Slice = Array.prototype.slice; //배열에 인수를 추가하고 배열을 반환, 내부 메서드 function update(array, args) { var arrayLength = array.length , length = args.length; while (length--) array[arrayLength length] = args[length]; return array; } //기본적으로 업데이트 방법과 동일하지만 다릅니다. 들어오는 매개변수 배열을 변경하고 새 배열을 반환합니다. function merge(array, args) { array = Slice.call(array, 0) return update(array, args); //함수의 매개변수를 배열로 형식화하고 function ArgumentNames() { var names = this.toString().match(/^[s(]*function[^(])을 반환합니다. *(([^)]*))/)[1] .replace(///.*?[rn]|/*(?:.|[rn])*?*//g, ' ') .replace(/s /g, '').split(',');
names.length == 1 && !names[0] [] : names; 🎜>} //실행 함수의 컨텍스트를 컨텍스트에 바인딩 functionbind(context) { if (arguments.length < 2 && Object.isUndefine(arguments[0])) return this ; var __method = this, args = Slice.call(arguments, 1); return function() { var a = merge(args,args) return __method.apply(context) , a); } } //기본적으로 바인딩과 유사합니다. 즉, 전달된 첫 번째 매개변수가 이벤트 객체여야 합니다. function binAsEventListener(context) { var __method = this, args = Slice.call(arguments, 1); return function(event) { var a = update([event || window.event], args); apply( context, a); } } //curry는 수학자의 이름입니다. 이 메소드의 기능은 아래의 구체적인 예를 보면 알 수 있습니다. function curry() { if (!arguments.length) return this var __method = this, args = Slice.call(arguments, 0) return function() { var a = merge(args, 인수); return __method.apply(this, a); } } //window.setTimeout 함수의 간단한 캡슐화 함수 (timeout) { var __method = this, args = Slice.call(arguments, 1); timeout = timeout * 1000 return window.setTimeout(function() { return __method.apply (__method, args) ; }, timeout); } //delay(0.01) function defer() { var args = update([0.01], 인수 ); return this.delay.apply(this, args); } //간단한 AOP 함수를 구현하기 위해 호출할 함수를 래핑하기 위해 래퍼 사용 function Wrap(wrapper) { var __method = this; return function() { var a = update([__method.bind(this)], 인수) return Wrapper.apply(this, a); 🎜>} } //현재 컨텍스트를 수신 호출 메소드의 첫 번째 매개변수로 표시 function methodize() { if (this._methodized) return this._methodized; var __method = this ; return this._methodized = function() { var a = update([this], 인수) return __method.apply(null, a) }; } //외부 호출 가능 함수 반환 return { argumentNames: 인수 이름, bind: 바인딩, bindAsEventListener: binAsEventListener, curry: curry, delay : 지연 , defer: defer, wrap: Wrap, methodize: methodize } })());
업데이트, 병합 메서드: 왜냐하면 내부 메서드에 대해서는 자세히 설명하지 않기 때문에
argumentNames 메서드는 소스 코드를 보면 기본적으로 이해할 수 있습니다.
는 기본적으로 정규식을 사용하여 매개변수 목록을 제안합니다. 메서드에서 공백과 일부 특수 문자를 삭제한 다음 ','를 사용하여 분할하고 마지막으로 names.length == 1을 반환하는 조건의 사용이 무엇인지 이해하지 못합니다. 시도해 봤는데 효과가 없었습니다. 아는 것이 있으면 알려주세요. 예를 살펴보겠습니다.
바인드 메서드: 먼저 전달되는 매개변수 수를 결정합니다. 최소한 하나의 컨텍스트 매개변수가 전달되어야 합니다. 바인딩() 메서드가 직접 호출되면 원래 함수 객체는 돌아왔다. 부르지 않는 것과 마찬가지다. 바인드 메소드의 프로토타입은 다음과 같습니다: bind(thisObj[, arg...]) -> 첫 번째 매개변수 뒤에는 선택적 매개변수가 올 수 있습니다. 첫 번째 매개변수를 제외한 모든 매개변수를 저장합니다. args = Slice.call(arguments, 1); var __method = this 문장은 __method 변수를 현재 함수로 설정한다는 의미입니다.
var obj = { name: '멋진 데모', fx: function() { Alert(this.name) } } window.name = '나는 정말 아름다운 창이에요!'; function runFx( f) { f() } //여기서 __method는 obj.fx와 동일합니다. var fx2 = obj.fx.bind(obj) runFx(obj.fx) ); //저는 정말 아름다운 창입니다! runFx(fx2); //멋진 데모입니다. /* runFx 함수 내에서 f()를 호출하지 않고 obj를 호출합니다. fx() 직접 외부 그러면 결과는 '좋은 데모'가 될 것입니다. 사실 다음과 같이 작성하면 var f=obj.fx;f(); '나는 정말 아름다운 창입니다!'라는 메시지도 받게 됩니다. 위의 예를 통해 컨텍스트의 개념을 볼 수 있습니다. obj.fx(); //컨텍스트는: obj f(); //컨텍스트는: window 컨텍스트는 실제로 마지막 '.' 이전의 객체임을 알 수 있습니다. 함수를 직접 호출하면 컨텍스트는 window */
마지막으로 익명 함수가 적용됩니다. 컨텍스트가 반환됩니다. 참고: var a = merge(args, 인수);의 인수와 args = Slice.call(arguments, 1);의 인수는 다릅니다. 예를 살펴보세요.
var obj = { name : '좋은 데모', fx: function() { alert(this.name 'n' $A(arguments).joi(', ')) } }; //[1,2,3] 여기에는 Slice.call(arguments, 1); 내부 인수가 있습니다. var fx2 = obj.fx.bind(obj, 1, 2 , 3); //[4,5] 여기에는 merge(args, 인수)가 있습니다. fx2(4, 5) // 적절한 이름을 경고한 다음 "1, 2, 3, 4 , 5"
bindAsEventListener 메서드: 이 메서드는 바인딩과 유사합니다. 주요 차이점은 다음 문장입니다. var a = update([event || window.event] , args); 바인딩된 함수의 첫 번째 매개변수가 이벤트 개체인지 항상 확인하세요. 예를 살펴보세요.
var F=function(){alert(Array.prototype.slice.call(arguments,0) .join(' '))}; F.curry('I').curry('am').curry('never-online').curry('http://www.never-online. net')(); //I am never -online http://www.never-online.net
지연 및 연기 방법: 기본적으로 window.setTimeout의 간단한 캡슐화입니다. 시간 단위는 초입니다.
wrap 메서드: 원래 함수를 "래핑"한 함수를 반환합니다. Function#wrap은 관점 지향 프로그래밍의 본질을 단일 메서드로 압축하여 쉽게 구축할 수 있도록 해줍니다. 이전 및 이후 동작을 지정하거나, 반환 값을 변환하거나, 심지어 원래 함수가 호출되지 않도록 방지하여 기존 함수를 삭제합니다. 이 문장의 의미는 다음과 같습니다. var a = update([__method.bind(this)], 인수); 래핑된 함수를 첫 번째 매개변수로 래핑 함수에 넣습니다. 예를 살펴보세요.
function Wrapped(){ alert('wrapped'); } //래퍼 전후에 원래 함수를 호출할 수 있습니다. AOP와 약간 비슷하죠? var Wrapper=wrapped.wrap(function(oldFunc,param){ //oldFunc() Alert(param); oldFunc(); } );
//wrapper,wrapped wrapper("wrapper")
메서드화 방법: 함수를 가져와서 래핑합니다. 호출 시 이를 원래 함수에 첫 번째 인수로 푸시하는 다른 함수에서 이 메서드는 먼저 메서드화할 메서드가 메서드화되었는지 확인하고 내부 변수 this._methodized를 통해 확인합니다. 마지막으로 methodize 함수가 반환하는 것은 실제로 this._methodized입니다. 이 문장은 var a = update([this],args); 입니다. 이것이 원래 함수의 첫 번째 매개변수로 전달되는 것을 볼 수 있습니다. 예제를 보시면 이해하실 것입니다.
// 대상 객체에 대해 // 작업을 수행하는 간단한 함수로 시작합니다. var fn = function(target, foo) { target.value = foo }; // 원본 메서드 fn(object, 'bar'); object.value //-> 'bar' //methodize를 호출한 후 첫 번째 fn 함수의 매개변수 대상은 object object.fnMethodized = fn.methodize(); object.fnMethodized('boom!') object.value //-> 🎜>