>웹 프론트엔드 >JS 튜토리얼 >자바스크립트에서 암시적 호출을 어떻게 사용하나요?

자바스크립트에서 암시적 호출을 어떻게 사용하나요?

亚连
亚连원래의
2018-06-06 14:27:261495검색

이 글에서는 JavaScript의 암시적 호출과 관련된 지식 포인트를 자세히 소개합니다. 이에 관심이 있는 분들은 함께 배워보세요.

서문

암묵적 호출이라고 표현하는 것이 정확한지는 모르겠습니다. 그 행동은 항상 뒤에 숨겨져 있고, 가끔씩 모습을 드러내는 데에는 별 효과가 없는 것 같습니다. 그러나 그것을 이해하는 것은 여전히 ​​​​유용합니다. 당신이 그것을 사용하지 않을 것이라고 장담합니다.

소위 암시적 호출은 단순히 일부 메서드를 자동으로 호출하는 것을 의미하며 이러한 메서드는 후크처럼 외부에서 수정되어 설정된 동작을 변경할 수 있습니다.
아래에는 최근에 본 몇 가지 암시적 호출이 나열되어 있습니다.

Sting 및 valueOf

var obj = {
   a: 1,
   toString: function () {
    console.log('toString')
    return '2'
   },
   valueOf: function () {
    console.log('valueOf')
    return 3
   }
  }
  console.log(obj == '2'); //依次输出 'valueOf' false
  console.log(String(obj));//依次输出 'toString' '2'
var obj = {
   a: 1,
   toString: function () {
    console.log('toString')
    return '2'
   },
   valueOf: function () {
    console.log('valueOf')
    return {} //修改为对象
   }
  }
  console.log(obj == '2'); //依次输出 'valueOf' 'toString' true
  console.log(Number(obj));//依次输出 'valueOf' 'toString' 2

에 데이터 유형 변환을 추가해 주셔서 감사합니다. call valueOf 반환된 값이 객체인 경우 null을 제외하고 toSting이 호출되고 반환된 값이 비교에 사용됩니다. 첫 번째 예는 3 == '2'와 동일하며 false를 반환합니다. valueOf.object의 실행으로 인해 toString을 실행하고 마지막으로 '2' == '2'와 동일하며 Number 및 String 메서드에서 Number는 먼저 valueOf를 호출한 다음 toString을 호출합니다. String 메서드에서는 그 반대입니다.

위의 두 가지 예 외에도 수치 연산과 같은 다양한 다른 연산에도 데이터 유형 변환이 존재합니다. 참조 유형이 포함된 경우 객체가 객체인 한 valueOf 또는 toString 메서드가 호출됩니다. 이 두 메서드를 상속하므로 데이터 유형 변환 동작에 영향을 미치기 위해 이 두 메서드를 다시 재정의할 수 있습니다.

DOM2 이벤트의 handlerEvent

var eventObj = {
   a: 1,
   handleEvent: function (e) {
    console.log(this, e);//返回 eventObj 和 事件对象
    alert(this.a)
   }
  }
  document.addEventListener('click', eventObj)

맞게 읽으셨습니다. addEventListener의 두 번째 매개변수도 함수 외에도 이벤트 트리거 개체의 handlerEvent 메서드가 실행될 때 eventObj를 가리킵니다. eventObj 개체

JSON 개체에 JSON 을 바인딩할 수 있습니다.

var Obj = {
   a: 10,
   toJSON: function () {
    return {
     a: 1,
     b: function () {
     },
     c: NaN,
     d: -Infinity,
     e: Infinity,
     f: /\d/,
     g: new Error(),
     h: new Date(),
     i: undefined,
     
    }
   }
  }
  console.log(JSON.stringify(Obj));
  //{"a":1,"c":null,"d":null,"e":null,"f":{},"g":{},"h":"2018-02-09T19:29:13.828Z"}

JSON stringify 메소드로 전달된 객체에 toJSON 메소드가 있는 경우, 이 메소드로 실행된 객체는 toJSON이 실행된 후 반환된 객체로 변환됩니다. 한 가지 주목할 점은 다음 코드와 같습니다

var Obj1 = {
   a: 10,
   toJSON: function () {
    console.log(this === Obj1);//true
    return this
   }
  }
  console.log(JSON.stringify(Obj1));//{"a":10}
 var Obj2 = {
   a: 10,
   toJSON: function () {
    console.log(this === Obj2);//true
    return {
     a: this
    }
   }
  }
  console.log(JSON.stringify(Obj2));//报错 Maximum call stack size exceeded
.

위의 설명을 따르면 오류는 우리가 예상한 것임이 분명하지만 직접 반환하면 전혀 오류가 보고되지 않습니다. 대담하게 추측하여 toJSON에서 반환된 개체를 원본과 비교해 보는 것이 좋습니다. 동일할 경우 Promise.resolve 메소드가 객체에 전달되면 then 메소드가 즉시 실행됩니다. , 이는 새 Promise에 메서드를 추가하는 것과 동일합니다. Promise.resolve에도 이 동작이 있습니다

var obj = {
   then: function (resolve, reject) {
    setTimeout(function () {
     resolve(1000);
    }, 1000)
   }
  }
  Promise.resolve(obj).then(function (data) {
   console.log(data);// 延迟1秒左右输出 1000
  })

Object 속성 접근자 get 및 set

 var timePromise = function (time) {
    return new Promise(function (resolve) {
     setTimeout(function () {
      resolve(time);
     }, time)
    })
   }
   var timePromise1 = timePromise(1000);
   var timePromise2 = timePromise(2000);
   var timePromise3 = timePromise(3000);
   Array.prototype.then = function (resolve) {
     setTimeout(function () {
      resolve(4000);
     }, 4000)
    }
   Promise.all([timePromise1, timePromise2, timePromise3]).then(function (time) {
    console.log(time);// 等待4秒左右输出 4000
   })

상관없이 볼 수 있습니다. 어떤 연령으로 설정되어 있는지, 내 나이는 18세 이하입니다. 속성 액세스를 수행할 때 해당 객체 속성의 get set 함수가 실제로 호출됩니다. 위의 작성 방법 외에 다음과 같은 작성 방법도 있습니다

var obj = {
    _age: 100,
    get age() {
     return this._age < 18 ? this._age : 18;
    },
    set age(value) {
     this._age = value;
     console.log(`年龄设置为${value}岁`);
    }
   }
   obj.age = 1000; //年龄设置为1000岁
   obj.age = 200; //年龄设置为200岁
   console.log(obj.age);// 18
   obj.age = 2; ////年龄设置为2岁
   console.log(obj.age); // 2

이제 입력 값과 obj.age 속성 값 범위의 innerHTML 값이 함께 바인딩됩니다.

Iterator 인터페이스 Symbol.iterator

 var input = document.createElement(&#39;input&#39;);
  var span = document.createElement(&#39;span&#39;);
  document.body.appendChild(input);
  document.body.appendChild(span);
  var obj = {
   _age:&#39;&#39;
  }
  var obj = Object.defineProperty(obj, &#39;age&#39;, {
   get: function () {
    return this._age;
   },
   set: function (value) {
    this._age = value;
    input.value = value;
    span.innerHTML = value;
   }
  });
  input.onkeyup = function (e) {
   if (e.keyCode === 37 || e.keyCode === 39) {
    return;
   }
   obj.age = this.value
  }

스프레드 연산자가 호출되거나 for .. .of 객체를 통한 루핑은 Array, String, Map, Set, TypedArray와 같은 객체의 순회 인터페이스와 인수 및 NodeList와 같은 배열과 유사한 일부 객체가 기본적으로 순회 인터페이스를 갖는 반면, 일반 객체는 이 인터페이스를 배포하지 않습니다. 객체가 스프레드 연산자나 for...of 루프를 사용할 수 있기를 원하면 이 메소드를 객체에 추가하거나 인터페이스를 사용하여 원래 객체의 메소드를 다시 작성하여 동작을 변경할 수 있습니다

위 내용 이 내용은 제가 여러분을 위해 정리한 것입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다. 관련 기사:

노드 애플리케이션에서 타이밍 공격을 사용할 때 어떤 보안 취약점이 존재합니까?

vue 구성 요소 전달 개체에서 단방향 바인딩을 구현하는 방법은 무엇입니까?

Vue 구성 요소에서 TypeScript를 사용하는 방법(자세한 튜토리얼)

위 내용은 자바스크립트에서 암시적 호출을 어떻게 사용하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.