JavaScript에서 확장 메서드를 작성하려면 어떻게해야합니까?
JS로 몇 가지 확장 메서드를 작성해야합니다. C #에서이 작업을 수행하는 방법을 알고 있습니다. 예:
public static string SayHi(this Object name)
{
return "Hi " + name + "!";
}
다음에 의해 호출됩니다.
string firstName = "Bob";
string hi = firstName.SayHi();
JavaScript에서 이와 같은 작업을 어떻게 수행합니까?
자바 스크립트는 C #의 확장 메서드에 대한 정확한 아날로그가 없습니다. JavaScript와 C #은 완전히 다른 언어입니다.
가장 유사한 것은 모든 문자열 객체의 프로토 타입 객체를 수정하는 것입니다 : String.prototype
. 일반적으로, 가장 좋은 방법은 없습니다 당신이 통제하지 않는 다른 코드와 결합을 의미 라이브러리 코드의 개체 내장의 프로토 타입을 수정할 수 있습니다. (애플리케이션에 포함 된 다른 코드를 제어하는 애플리케이션에서 수행하는 것은 괜찮습니다.)
당신이 경우에 할 수 는 A 내장이있는 만들기 위해 (지금까지) 최선의 프로토 타입 수정 비 열거 사용하여 속성을 Object.defineProperty
(이전 그러니까 기본적으로, ES5 +를 현대의 자바 스크립트 환경, 그리고 IE8¹ 이상). 다른 문자열 메서드의 열거 가능성, 쓰기 가능성 및 구성 가능성을 일치 시키려면 다음과 같습니다.
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
return "Hi " + this + "!";
},
writable: true,
configurable: true
});
(기본값은 enumerable
입니다 false
.)
더 이상 사용되지 않는 환경을 지원해야하는 경우 String.prototype
, 특히에 대해 열거 가능한 속성을 만드는 작업에서 벗어날 수 있습니다.
// Don't do this if you can use `Object.defineProperty`
String.prototype.SayHi = function SayHi() {
return "Hi " + this + "!";
};
그것은 좋은 생각이 아니지만 당신은 그것을 피할 수 있습니다. 또는로 그렇게하지 마십시오 . 여기에 열거 가능한 속성을 만드는 것은 Bad Thing ™입니다.Array.prototype
Object.prototype
세부:
JavaScript는 프로토 타입 언어입니다. 이는 모든 객체가 프로토 타입 객체에 의해 뒷받침된다는 것을 의미 합니다 . JavaScript에서 해당 프로토 타입은 다음 네 가지 방법 중 하나로 지정됩니다.
- 바이 생성자 함수 오브젝트 (예를 들면,
new Foo
포함 된 객체를 생성Foo.prototype
의 프로토 타입) - 바이
Object.create
ES5에서 추가 기능 (2009) - 에 의해
__proto__
접근 자 속성 (ES2015 +, 전용 웹 브라우저에서,이 표준화되기 전에 일부 환경에 존재) 또는Object.setPrototypeOf
(ES2015 +) - 메소드를 호출하기 때문에 원시 객체를 생성 할 때 JavaScript 엔진에 의해 ( "프로모션"이라고도 함)
따라서 귀하의 예제에서는 firstName
문자열 프리미티브이므로 String
메서드를 호출 할 때마다 인스턴스로 승격 되며 해당 String
인스턴스의 프로토 타입은 String.prototype
. 따라서 함수 String.prototype
를 참조 하는 속성을 추가 SayHi
하면 해당 함수를 모든 String
인스턴스에서 사용할 수 있습니다 (그리고 승격되기 때문에 문자열 프리미티브에서도 효과적으로 사용할 수 있음 ).
예:
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
return "Hi " + this + "!";
},
writable: true,
configurable: true
});
console.log("Charlie".SayHi());
이 확장 메서드와 C # 확장 메서드에는 몇 가지 주요 차이점이 있습니다.
( DougR 이 주석에서 지적했듯이) C #의 확장 메서드 는
null
reference에서 호출 할 수 있습니다 .string
확장 메서드 가있는 경우이 코드 :string s = null; s.YourExtensionMethod();
works. That isn't true with JavaScript;
null
is its own type, and any property reference onnull
throws an error. (And even if it didn't, there's no prototype to extend for the Null type.)(As ChrisW pointed out in a comment) C#'s extension methods aren't global. They're only accessible if the namespace they're defined in is used by the code using the extension method. (They're really syntactic sugar for static calls, which is why they work on
null
.) That isn't true in JavaScript: If you change the prototype of a built-in, that change is seen by all code in the entire realm you do that in (a realm is the global environment and its associated intrinsic objects, etc.). So if you do this in a web page, all code you load on that page sees the change. If you do this in a Node.js module, all code loaded in the same realm as that module will see the change. In both cases, that's why you don't do this in library code. (Web workers and Node.js worker threads are loaded in their own realm, so they have a different global environment and different intrinsics than the main thread. But that realm is still shared with any modules they load.)
¹ IE8 does have Object.defineProperty
, but it only works on DOM objects, not JavaScript objects. String.prototype
is a JavaScript object.
참고URL : https://stackoverflow.com/questions/9354298/how-do-i-write-an-extension-method-in-javascript
'Nice programing' 카테고리의 다른 글
Xcode 실행 스크립트 빌드 단계 "설치할 때만 스크립트 실행"옵션 (0) | 2020.11.01 |
---|---|
텍스트 입력 기록 비활성화 (0) | 2020.11.01 |
Ruby의 % q / % Q 인용 방법의 사용 사례는 무엇입니까? (0) | 2020.11.01 |
SQL Server에서 사용자 정의 테이블 유형 변경 (0) | 2020.11.01 |
조건부 이동이 분기 예측 실패에 취약하지 않은 이유는 무엇입니까? (0) | 2020.11.01 |