Javascript에서 this
매개 변수 를 바인딩하지 않고 인수를 함수에 바인딩하는 방법은 무엇입니까?
예를 들면 :
//Example function.
var c = function(a, b, c, callback) {};
//Bind values 1, 2, and 3 to a, b, and c, leave callback unbound.
var b = c.bind(null, 1, 2, 3); //How can I do this without binding scope?
함수의 범위 (예 : 설정 this
= null) 를 바인딩해야하는 부작용을 어떻게 피할 수 있습니까?
편집하다:
혼란을 드려 죄송합니다. 인수를 바인딩 한 다음 나중에 바인딩 된 함수를 호출하고 마치 원래 함수를 호출하고 바인딩 된 인수를 전달한 것처럼 정확하게 동작하도록 할 수 있습니다.
var x = 'outside object';
var obj = {
x: 'inside object',
c: function(a, b, c, callback) {
console.log(this.x);
}
};
var b = obj.c.bind(null, 1, 2, 3);
//These should both have exact same output.
obj.c(1, 2, 3, function(){});
b(function(){});
//The following works, but I was hoping there was a better way:
var b = obj.c.bind(obj, 1, 2, 3); //Anyway to make it work without typing obj twice?
나는 이것에 아직 새롭다. 혼란을 끼쳐서 미안하다.
감사!
답변
이 작업을 수행 할 수 있지만 “이”값을 설정하는 데 사용되는 용어이므로 “바인딩”으로 생각하지 않는 것이 가장 좋습니다. 인수를 함수로 “래핑”하는 것으로 생각할 수 있습니까?
당신이하는 일은 클로저를 통해 원하는 인수가 내장 된 함수를 만드는 것입니다.
var withWrappedArguments = function(arg1, arg2)
{
return function() { ... do your stuff with arg1 and arg2 ... };
}(actualArg1Value, actualArg2Value);
바로 거기에 구문이 있기를 바랍니다. 그것이하는 일은 언제 어디서나 호출 할 수있는 withWrappedArguments ()라는 함수를 만드는 것입니다. 그곳에. 원하는 경우 호출시 추가 인수를 허용 할 수도 있습니다. 비밀은 마지막 닫는 중괄호 뒤의 괄호입니다. 이렇게하면 전달 된 값으로 외부 함수가 즉시 실행되고 나중에 호출 할 수있는 내부 함수가 생성됩니다. 전달 된 값은 함수가 생성 될 때 고정됩니다.
이것은 bind가하는 일입니다. 그러나 이렇게하면 래핑 된 인수가 단순히 지역 변수에 대한 클로저이며이 동작을 변경할 필요가 없습니다.
답변
ES6에서는 스프레드 연산자 와 함께 나머지 매개 변수 를 사용하여 쉽게 수행 할 수 있습니다 .
따라서 우리는 인수 만 바인딩되고 컨텍스트 ( )가 아니라는 점을 제외하고 bindArgs
와 같이 작동 하는 함수 를 정의 할 수 있습니다 .bind
this
Function.prototype.bindArgs =
function (...boundArgs)
{
const targetFunction = this;
return function (...args) { return targetFunction.call(this, ...boundArgs, ...args); };
};
그런 다음 지정된 함수 foo
및 객체 obj
에 대해 문
return foo.call(obj, 1, 2, 3, 4);
다음과 같다
let bar = foo.bindArgs(1, 2);
return bar.call(obj, 3, 4);
첫 번째 및 두 번째 인수 만에 바인딩되는 bar
반면 obj
호출에 지정된 컨텍스트 가 사용되고 바인딩 된 인수 뒤에 추가 인수가 추가됩니다. 반환 값은 단순히 전달됩니다.
답변
네이티브 bind
메서드 에서는 this
결과 함수 의 값이 손실됩니다. 그러나 컨텍스트에 대한 인수를 사용하지 않도록 공통 shim을 쉽게 다시 코딩 할 수 있습니다.
Function.prototype.arg = function() {
if (typeof this !== "function")
throw new TypeError("Function.prototype.arg needs to be called on a function");
var slice = Array.prototype.slice,
args = slice.call(arguments),
fn = this,
partial = function() {
return fn.apply(this, args.concat(slice.call(arguments)));
// ^^^^
};
partial.prototype = Object.create(this.prototype);
return partial;
};
답변
재미를위한 작은 구현이 하나 더 있습니다.
function bindWithoutThis(cb) {
var bindArgs = Array.prototype.slice.call(arguments, 1);
return function () {
var internalArgs = Array.prototype.slice.call(arguments, 0);
var args = Array.prototype.concat(bindArgs, internalArgs);
return cb.apply(this, args);
};
}
사용하는 방법:
function onWriteEnd(evt) {}
var myPersonalWriteEnd = bindWithoutThis(onWriteEnd, "some", "data");
답변
var b = function() {
return c(1,2,3);
};
답변
예제가 임의적이기 때문에 궁극적으로 무엇을하고 싶은지 정확히 말하기는 조금 어렵지만 부분 (또는 커링)을 살펴보고 싶을 수도 있습니다 : http://jsbin.com/ifoqoj/1/edit
Function.prototype.partial = function(){
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for ( var i = 0; i < args.length && arg < arguments.length; i++ )
if ( args[i] === undefined )
args[i] = arguments[arg++];
return fn.apply(this, args);
};
};
var c = function(a, b, c, callback) {
console.log( a, b, c, callback )
};
var b = c.partial(1, 2, 3, undefined);
b(function(){})
John Resig의 기사 링크 : http://ejohn.org/blog/partial-functions-in-javascript/
답변
마지막 으로 이것 에 대한 참조를 바인딩하고 싶을 수도 있지만 코드는 다음과 같습니다.
var c = function(a, b, c, callback) {};
var b = c.bind(null, 1, 2, 3);
이미 예를 들어 바인딩 적용 이 나중에 변경할 수 없습니다. 다음과 같은 매개 변수로 참조를 사용하는 것이 좋습니다.
var c = function(a, b, c, callback, ref) {
var self = this ? this : ref;
// Now you can use self just like this in your code
};
var b = c.bind(null, 1, 2, 3),
newRef = this, // or ref whatever you want to apply inside function c()
d = c.bind(callback, newRef);