programing

화살표 함수로 '이것'을 묶을 수 있습니까?

powerit 2023. 10. 5. 23:34
반응형

화살표 함수로 '이것'을 묶을 수 있습니까?

저는 ES6에 대해 한동안 실험을 해보았는데, 조금 문제가 생겼습니다.

저는 화살표 기능을 사용하는 것을 정말 좋아하고, 사용할 수 있을 때마다 사용합니다.

하지만, 그것들을 묶을 수는 없는 것처럼 보일 것입니다!

기능은 다음과 같습니다.

var f = () => console.log(this);

함수를 바인딩할 개체는 다음과 같습니다.

var o = {'a': 42};

그리고 여기에 제가 어떻게 묶을지가 있습니다.f로.o:

var fBound = f.bind(o);

그 다음에 전화하면 돼요fBound:

fBound();

이것을 출력할 것입니다.o개체):

{'a': 42}

멋지다! 사랑스럽습니다!작동이 안 된다는 것만 빼면요.출력하는 대신o물체, 그것은 출력합니다.window물건.

그래서 알고 싶습니다: 화살표 기능을 바인딩할 수 있습니까? (만약 그렇다면 어떻게 합니까?)


위의 코드를 구글 크롬 48과 파이어폭스 43에서 테스트해보았는데 결과는 같습니다.

재결합할 수 없습니다. this화살표 함수로항상 정의된 컨텍스트로 정의됩니다.필요한 경우this의미를 가지려면 일반적인 기능을 사용해야 합니다.

ECMA스크립트 2015 스펙에서:

ArrowFunction 내의 인수, super, this 또는 new.target에 대한 참조는 사전적으로 포함된 환경에서 바인딩으로 확인해야 합니다.일반적으로 이 기능은 즉시 둘러싸는 기능의 기능 환경이 됩니다.

완성하기 위해서는 화살표 함수를 다시 묶을 수 있습니다. 단지 다음의 의미를 변경할 수 없습니다.this.

bind함수 인수에 대한 값은 여전히 있습니다.

((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()

여기서 해보세요: http://jsbin.com/motihanopi/edit?js,console

MDN에서:

화살표 함수 식을 함수 식에 비해 구문이 짧으며 이 값을 어휘적으로 바인딩합니다(자체 인수, 인수, 슈퍼 또는 new.target을 바인딩하지 않음).화살표 함수는 항상 익명입니다.

값을 다음에 바인딩할 수 없음을 의미합니다.this네가 원하는 대로

설명:슈타인 드 비트

사용할수없습니다bind값을 바꾸다this화살표 함수 안에그러나 이전 화살표 기능과 동일한 작업을 수행하는 새로운 일반 기능을 생성한 후 사용할 수 있습니다.call아니면bind다시this평소처럼.

우리는 a를 사용합니다.eval여기로 전화하여 전달한 화살표 기능을 일반 기능으로 다시 만든 다음 사용합니다.call그것을 다른 것으로 호출하다this:

코드 : 나

const func = v => console.log(this);
const obj = {value: 10};

function arrowBindOld(context, fn) {
  let arrowFn;
  (function() {
    arrowFn = eval(fn.toString());
    arrowFn();
  }).call(context);
}
arrowBindOld(obj, func);

갱신하다

const f = v => console.log(this, v);
const o = {value: 10};

/* new */
function arrowBind(context, fn) {
  const arrowFnString = fn.toString();
  return (function() {
    return eval(arrowFnString);
  }).call(context);
}
const fBound = arrowBind(o, f);
fBound(10);

/* use prototype */
Function.prototype.arrowBind = function(context) {
  const arrowFnString = this.toString();
  return (function() {
    return eval(arrowFnString);
  }).call(context);
}
const fBoundProto = f.arrowBind(o);
fBoundProto(20);

수년간 js 개발자들은 컨텍스트 바인딩과 씨름하며 그 이유를 물었습니다.this과 javascript되었습니다, context binding다의 의 차이로 이 있었습니다.thisthis대부분의 다른 OOP 언어에서.

이 모든 것이 저로 하여금 왜, 왜, 왜! 왜 화살표 함수를 다시 묶고 싶지 않냐고 묻게 합니다.이러한 품을 되도록 입니다.bind아니면call또는 기능의 범위를 유지하기 위한 다른 방법.

TL;DR

아니요, 화살표 함수는 재결합할 수 없습니다.

간단히 말해, 화살표 함수를 바인딩할 는 없지만 다음 내용을 읽습니다.

에 를 해 보십시오.this콘솔에서 다음을(를)

const myFunc = ()=> console.log(this);

따라서 이에 대한 빠른 해결책은 일반 기능을 사용하는 것이므로 다음과 같이 변경합니다.

function myFunc() {console.log(this)};

를 수 .bind아니면call아니면apply:

const bindedFunc = myFunc.bind(this);

만일의 경우를 대비해 전화를 걸어 봅니다.bind.

bindedFunc();

를 .eval()강력하게 권장하지 않는 방법으로 말입니다.

자바스크립트에서 ES6 화살표 기능이 정말로 "이것"을 해결합니까?

이 합니다.thisbind, call, apply기능들.

그것은 아주 좋은 예를 들어 설명하고 있습니다.

이 일을 실행합니다.node v4 것,되는"

this.test = "attached to the module";
var foo = { test: "attached to an object" };
foo.method = function(name, cb){ 
    // bind the value of "this" on the method 
    // to try and force it to be what you want 
    this[name] = cb.bind(this); };
foo.method("bar", () => { console.log(this.test); });
foo.bar(); 

이것이 더 나은 해결책이라고 생각합니다.

var f = (vm=this) => console.log(vm);

며칠 전에도 똑같은 질문을 했습니다.

수 .this이미 바인딩되어 있습니다.

이 범위를 ES6 = > 함수 연산자에 바인딩하는 것

아마도 이 예는 당신에게 도움이 될 것입니다.

let bob = {
   _name: "Bob",
   _friends: ["stackoverflow"],
   printFriends:(x)=> {
      x._friends.forEach((f)=> {
         console.log(x._name + " knows " + f);
      });
   }
}

bob.printFriends = (bob.printFriends).bind(null,bob);
bob.printFriends();

오브젝트를 화살표 함수에 묶는 것은 불가능한 것입니다. 절대 절대로 말하지 마세요. 해킹은 효과가 있을지도 모른다고 생각했습니다.

function arrowToRegularFn(callback) {
    let _callback = callback
    const stringifiedCallback = callback.toString()
    const isArrowFn = !stringifiedCallback.trim().startsWith("function")
    if (isArrowFn) {
        const isParamsInParantheses = stringifiedCallback.trim().startsWith("(")
        const [fnParams, ...fnBody] = stringifiedCallback.split("=>")
        _callback = eval("(function" + (!isParamsInParantheses ? "(" : "") + fnParams + (!isParamsInParantheses ? ")" : "") + "{" + fnBody.join("=>") + "})")
    }
    return _callback
}

// test cases

// our object to bind
const quiver = { score: 0 }

let arrow, regular;

// test - 1
arrow = () => this.score++
regular = arrowToRegularFn(arrow).bind(quiver)
regular()
console.log(quiver.score) // 1

// test - 2
arrow = (x, y) => this.score = x + y
regular = arrowToRegularFn(arrow).bind(quiver)
regular(1, 2)
console.log(quiver.score) // 3

// test - 3
arrow = (x, y) => { this.score = x + y }
regular = arrowToRegularFn(arrow).bind(quiver)
regular(3, 4)
console.log(quiver.score) // 7

// test - 4
arrow = function(x, y) { this.score = x + y }
regular = arrowToRegularFn(arrow).bind(quiver)
regular(5, 6)
console.log(quiver.score) // 11

일반 바인딩:

tag.on("Initialized", function(tag) {
   nodeValueChanged(tag, currentNode)
}.bind(currentNode))

화살표 함수 바인딩:

tag.on("Initialized", (tag => { nodeValueChanged(tag, currentNode) }).bind(currentNode))

가 .this어디서 부르는지에 관계없이 가장 가까운 비 arrow 기능을 기반으로 합니다.화살표가 아닌 상위 항목이 없으면 항상 전역 개체를 참조합니다.

호출/바인드/적용을 사용하여 화살표 함수를 호출하는 동안에는 전달 중인 개체를 가리키지 않습니다.

var obj = {a:1};
var  add=(b)=>{
return this.a + b;
// basically here this.a will be undefined as it's trying to find in one level up which is parents of this function that is window.
}

add.call(obj,2);

그래서 지나가는 물체가 화살표 기능에서 작동하지 않는 것입니다.

언급URL : https://stackoverflow.com/questions/33308121/can-you-bind-this-in-an-arrow-function

반응형