JavaScript의 여러 대출 방법에 대한 자세한 설명(그래픽 튜토리얼)

亚连
풀어 주다: 2018-05-19 16:11:17
원래의
1344명이 탐색했습니다.

자바스크립트의 메소드 차용에 대한 자세한 소개를 살펴보겠습니다. 참고: 이 기사에서는 call(), apply() 및 바인딩() 사용에 대한 관련 지식과 이들 간의 차이점을 숙지했다고 가정합니다. JavaScript로 대출하는 방법을 알려드릴 수 있습니다.

머리말

call(), apply(), 바인딩() 메소드를 통해 다른 객체로부터 메소드를 상속받지 않고도 쉽게 빌릴 수 있습니다.

JavaScript에서 메서드 대여

JavaScript에서는 개체 자체나 프로토타입에 반드시 정의할 필요가 없는 다른 개체의 함수나 메서드를 재사용하는 것이 가능한 경우가 있습니다. call(), apply() 및 바인딩() 메소드를 통해 다른 객체를 상속받지 않고도 다른 객체의 메소드를 쉽게 빌릴 수 있습니다. 이는 전문 JavaScript 개발자가 사용하는 일반적인 접근 방식입니다.

프로토타입 메서드

JavaScript에서는 문자열, 숫자, 부울과 같은 불변의 기본 데이터 유형을 제외하고 거의 모든 데이터가 객체입니다. 배열은 순서가 지정된 시퀀스를 순회하고 변환하는 데 적합한 개체입니다. 해당 프로토타입에는 슬라이스, 조인, 푸시 및 팝과 같은 유용한 메서드가 있습니다.

일반적인 예는 객체와 배열이 모두 목록 유형 데이터 구조인 경우 객체가 배열에서 메서드를 "빌려올" 수 있다는 것입니다. 가장 일반적으로 차용되는 메서드는 Array.prototype.slice입니다. Array.prototype.slice

function myFunc() {
 
  // error, arguments is an array like object, not a real array
  arguments.sort();
 
  // "borrow" the Array method slice from its prototype, which takes an array like object (key:value)
  // and returns a real array
  var args = Array.prototype.slice.call(arguments);
 
  // args is now a real Array, so can use the sort() method from Array
  args.sort();
 
}
 
myFunc('bananas', 'cherries', 'apples');
로그인 후 복사

借用方法之所以可行,是因为 call 和 apply 方法允许在不同上下文中调用函数,这也是重用已有功能而不必继承其它对象的好方法。实际上,数组在原型中定义了很多常用方法,比如 join 和 filter 也是:

// takes a string "abc" and produces "a|b|c
Array.prototype.join.call('abc', '|');
 
// takes a string and removes all non vowels
Array.prototype.filter.call('abcdefghijk', function(val) {
  return ['a', 'e', 'i', 'o', 'u'].indexOf(val) !== -1;
}).join('');
로그인 후 복사

可以看出,不仅对象可以借用数组的方法,字符串也可以。但是因为泛型方法是在原型上定义的,每次想要借用方法时都必须使用 String.prototype Array.prototype。这样写很啰嗦,很快就会令人生厌。更有效的方法是使用字面量来达到同样的目的。

使用字面量借用方法

字面量是一种遵循JavaScript规则的语法结构,MDN 这样解释:

在JavaScript中,使用字面量可以代表值。它们是固定值,不是变量,就是在脚本中按字面给出的。
字面量可以简写原型方法:

[].slice.call(arguments);
[].join.call('abc', '|');
''.toUpperCase.call(['lowercase', 'words', 'in', 'a', 'sentence']).split(',');
로그인 후 복사

这样看上去没有那么冗长了,但是必须直接在 [] 和 "" 上操作以借用方法,仍然有点丑。可以利用变量保存对字面量和方法的引用,这样写起来更简便些:

var slice = [].slice;
slice.call(arguments);
var join = [].join;
join.call('abc', '|');
 
var toUpperCase = ''.toUpperCase;
toUpperCase.call(['lowercase', 'words', 'in', 'a', 'sentence']).split(',');
로그인 후 복사

有了借用方法的引用,我们就可以轻松地使用 call() 调用它了,这样也可以重用代码。秉着减少冗余的原则,我们来看看可否借用方法却不用每次调用都要写 call() 或者 apply():

var slice = Function.prototype.call.bind(Array.prototype.slice);
slice(arguments);
 
var join = Function.prototype.call.bind(Array.prototype.join);
join('abc', '|');
 
var toUpperCase = Function.prototype.call.bind(String.prototype.toUpperCase);
toUpperCase(['lowercase', 'words', 'in', 'a', 'sentence']).split(',');
로그인 후 복사

如你所见,现在可以使用 Function.prototype.call.bind 来静态绑定从不同原型“借来的”方法了。但是 var slice = Function.prototype.call.bind(Array.prototype.slice) 这句话实际是如何起作用的呢?

理解 Function.prototype.call.bind

Function.prototype.call.bind 乍一看有些复杂,但是理解它是如何起作用的会非常有益。

Function.prototype.call 是一种引用,可以“call”函数并将设置其“this”值以在函数中使用。
注意“bind”返回一个存有其“this”值的新函数。因此 .bind(Array.prototype.slice)

var scoreCalculator = {
  getSum: function(results) {
    var score = 0;
    for (var i = 0, len = results.length; i < len; i++) {
      score = score + results[i];
    }
    return score;
  },
  getScore: function() {
    return scoreCalculator.getSum(this.results) / this.handicap;
  }
};
var player1 = {
  results: [69, 50, 76],
  handicap: 8
};
 
var player2 = {
  results: [23, 4, 58],
  handicap: 5
};
 
var score = Function.prototype.call.bind(scoreCalculator.getScore);
 
// Score: 24.375
console.log(&#39;Score: &#39; + score(player1));
 
// Score: 17
console.log(&#39;Score: &#39; + score(player2));
로그인 후 복사

메소드 대여는 호출 및 적용 메소드를 통해 다양한 컨텍스트에서 함수를 호출할 수 있기 때문에 작동하며, 이는 다른 객체에서 상속하지 않고도 기존 기능을 재사용할 수 있는 좋은 방법이기도 합니다. 실제로 배열은 프로토타입에서 조인 및 필터와 같은 많은 일반적인 메서드를 정의합니다.

rrreee객체는 배열의 메서드뿐만 아니라 문자열도 빌릴 수 있다는 것을 알 수 있습니다. 하지만 일반 메서드는 프로토타입에 정의되어 있으므로 메서드를 빌릴 때마다 String.prototype 또는 Array.prototype을 사용해야 합니다. 이런 식으로 글을 쓰는 것은 장황하고 금방 지루해질 수 있습니다. 보다 효율적인 방법은 동일한 목적을 달성하기 위해 리터럴을 사용하는 것입니다.

리터럴 차용 방법 사용

Literal은 JavaScript 규칙을 따르는 구문 구조입니다. MDN은 이를 다음과 같이 설명합니다.

JavaScript에서 리터럴을 사용하면 값을 나타낼 수 있습니다. 이는 변수이거나 스크립트에 문자 그대로 제공되는 고정 값입니다.

리터럴은 프로토타입 메서드를 축약할 수 있습니다.

rrreee

별로 장황해 보이지는 않지만 메서드를 빌리려면 [] 및 ""에 직접 작업해야 하는 것은 여전히 ​​약간 보기 흉합니다. 변수를 사용하여 리터럴 및 메소드에 대한 참조를 저장할 수 있으므로 작성이 더 쉽습니다.

rrreee

빌린 메소드에 대한 참조를 사용하면 call()을 사용하여 쉽게 호출할 수 있으며 재사용도 가능합니다. 암호. 중복성을 줄이는 원칙에 따라 호출될 때마다 call() 또는 apply()를 작성하지 않고도 메서드를 빌릴 수 있는지 살펴보겠습니다.

rrreee🎜🎜🎜보다시피 이제 함수 .prototype.call.bind 는 다른 프로토타입에서 "빌려온" 메서드를 정적으로 바인딩합니다. 그런데 var Slice = Function.prototype.call.bind(Array.prototype.slice) 문장이 실제로 어떻게 작동할까요? 🎜🎜🎜Function.prototype.call.bind 이해 🎜🎜🎜Function.prototype.call.bind는 처음에는 복잡해 보일 수 있지만 작동 방식을 이해하면 매우 유익할 수 있습니다. 🎜🎜Function.prototype.call 은 함수를 "호출"하고 함수에서 사용할 "this" 값을 설정하는 참조입니다. 🎜"bind"는 "this" 값을 사용하여 새 함수를 반환합니다. 따라서 .bind(Array.prototype.slice) 에서 반환된 새 함수의 "this"는 항상 Array.prototype.slice 함수입니다. 🎜🎜🎜요약하자면, 🎜새 함수는 "call" 함수를 호출하고 "this"는 "slice" 함수를 호출합니다. Slice()를 호출하면 이전에 정규화된 메서드를 가리킵니다. 🎜🎜🎜🎜🎜사용자 정의 개체의 방법🎜🎜🎜🎜상속은 훌륭하지만 일반적으로 개발자는 일부 개체나 모듈 간의 공통 기능을 재사용하려고 할 때 상속을 사용합니다. 코드 재사용을 위해서만 상속을 사용할 필요는 없습니다. 대부분의 경우 간단한 메소드 차용은 복잡하기 때문입니다. 🎜🎜이전에는 네이티브 메소드 차용에 대해서만 논의했지만 어떤 메소드든지 차용이 가능합니다. 예를 들어 다음 코드는 포인트 게임에서 플레이어 점수를 계산할 수 있습니다. 🎜🎜🎜rrreee🎜🎜🎜위의 예는 매우 무뚝뚝하지만 기본 메서드와 마찬가지로 사용자 정의 메서드도 쉽게 빌릴 수 있음을 알 수 있습니다. 🎜🎜🎜요약🎜🎜🎜Call, Bind 및 Apply는 함수 호출 방식을 변경할 수 있으며 함수를 빌릴 때 자주 사용됩니다. 대부분의 개발자는 기본 메서드를 차용하는 데 익숙하지만 사용자 지정 메서드를 차용하는 경우는 적습니다. 🎜🎜위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다. 🎜🎜관련 기사: 🎜🎜🎜js에 내장된 Math의 속성과 메서드에 대해 자세히 이야기해 보세요(한 눈에 알 수 있음)🎜🎜🎜

JavaScript를 사용하여 패턴 일치의 문자열 메서드 구현

javascript 자세한 설명(그래픽 튜토리얼)

위 내용은 JavaScript의 여러 대출 방법에 대한 자세한 설명(그래픽 튜토리얼)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿