>웹 프론트엔드 >JS 튜토리얼 >프로토타입 열거 가능한 객체 학습_prototype

프로토타입 열거 가능한 객체 학습_prototype

PHP中文网
PHP中文网원래의
2016-05-16 18:49:511178검색

Enumerable은 Prototype 프레임워크의 초석이며 Enumerable은 단독으로 사용되지 않습니다. Prototype에서는 다른 개체가 Enumerable의 메서드를 혼합하므로 이러한 개체에 Array, Hash, ObjectRange를 적용할 수 있습니다. , DOM 및 AJAX와 관련된 일부 개체.

Enumerable은 열거, 즉 값의 컬렉션 역할을 하는 객체에 대한 유용한 메서드 세트를 제공합니다.

Enumerable은 우리가 모듈이라고 부르는 것입니다. : 독립적으로 사용하기 위한 것이 아니라 믹스인을 위한 일관된 메소드 세트: "적합"한 다른 객체에 통합

프로토타입에서 꽤 많은 객체가 이미 가장 눈에 띄는 경우에 혼합되어 있습니다. Array 및 Hash이지만 ObjectRange 및 다양한 DOM 또는 AJAX 관련 개체와 같이 덜 명확한 위치에서도 찾을 수 있습니다.

위 문장은 아마도 Enumerable이 Prototype의 초석이라는 의미일 것입니다. Enumerable은 단독으로 사용되지 않습니다. Prototype의 다른 개체는 Enumerable의 메서드를 혼합하므로 이러한 개체에는 Array, Hash, ObjectRange 및 일부 DOM, AJAX 관련 개체가 포함될 수 있습니다. .
저는 Enumerable이 C의 추상 클래스 개념과 동일하다는 것을 개인적으로 이해합니다. 다른 클래스는 이 클래스에서 상속할 수 있고 Enumerable에서 추상 메서드 "_each"를 구현하고 다른 메서드를 재정의할 수 있지만 Enumerable 자체는 인스턴스화할 수 없습니다. , 해당 하위 클래스만 인스턴스화할 수 있습니다.
Enumerable을 통해 자신만의 클래스를 작성하는 방법을 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.


var YourObject = Class.create ();
Object.extend(YourObject.prototype, Enumerable); Object.extend(YourObject.prototype, {
initialize: function() {
// 모든 생성자 인수 포함
/ / 구성 코드
},
_each: function(iterator) {
// 매 턴마다 반복자를 호출하는 반복 코드
},
// Enumerable 재정의를 포함한 다른 메서드
});


가장 중요한 것은 _each 메서드를 구현하는 것임을 알 수 있습니다. 초기화 메서드는 생성자와 동일합니다. 외부 매개변수가 필요하지 않으면 생략해도 됩니다. 아래에서는 난수 배열을 생성하는 클래스를 작성했습니다. 매우 간단하지만 불완전한 점이 많습니다.

코드를 복사하세요. 다음과 같습니다:


//RandomArray 클래스 생성
var RandomArray = Class.create();
//mixin Enumerable
Object.extend(RandomArray.prototype, Enumerable);
/ / _each 및 필수 메소드 구현
Object.extend(RandomArray.prototype, {
초기화: function(min,max,count) {
this.min=min;
this. max= max;
this._numbers=[];
this._createRandomArray()
},
_each: 함수(반복자) var index =this.count; 🎜> _createRandomArray:function(){
var index=0
while(index var random=Math.round(Math.random() *(this.max-this .min) this.min);
                                                                                    function(number){
return this._numbers.indexOf(number)!=-1 ;
}
});

var obj = new RandomArray( 4,19,5)
//alert(obj.size()); .entries());



Enumerable의 소스 코드를 살펴보고 각 메서드를 자세히 알아보세요.



코드 복사
코드는 다음과 같습니다.


var $break = { };

var Enumerable = (function() {
//각 데이터 탐색
function Each(iterator, context) {
var index = 0;
try {
this._each(function(value) {
iterator.call(context, value, index );
}) catch(e) {
if (e != $break) throw e;
}
return this;
}

//데이터를 N개의 그룹으로 나누고 각 그룹에는 숫자가 있습니다. 마지막 그룹은 숫자보다 작을 수 있습니다.
function EachSlice(number, iterator, context) {
var index = -number, Slices = [], array = this.toArray()
if ( number < 1) 배열 반환;
while ((index = number) < array.length)
slices.push(array.slice(index, index number))
return Slices.collect( iterator, context );
}

//모든 데이터가 특정 조건을 만족하는지 테스트
function all(iterator, context) {
iterator = iterator || = true;
this.each(function(value, index) {
result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
결과 반환
}

//특정 조건을 만족하는 데이터가 있는지 확인
function any(iterator, context) {
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
if (result = !!iterator.call(context, value, index) ))
throw $break;
});
return result;
}

//모든 데이터에 대해 모든 작업을 수행하고 결과 배열을 반환할 수 있습니다.
함수 수집(반복자, 컨텍스트) {
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value) , index));
return results;
}

//특정 조건을 충족하는 첫 번째 데이터를 찾아 반환합니다. 이는 Alias ​​​​와 동일합니다. find 메소드
function detector(iterator, context) {
var result;
this.each(function(value, index) {
if (iterator.call(context, value, index) ) {
result = value;
throw $break;}
})
return result;
}

//특정 조건을 만족하는 모든 항목 찾기 데이터를 반환하고 결과를 반환합니다.
function findAll(iterator, context) {
var results = []
this.each(function(value, index) {
if (iterator.call(context , value, index))
results.push(value);
});
return results;
}

//필터 조건에 따라 모든 데이터를 필터링하고 필터 조건부 데이터 충족 및 결과 반환
//filter는 문자열 또는 정규 표현식입니다.
function grep(filter, iterator, context) {
iterator = iterator
var results = [];

if (Object.isString(filter))
filter = new RegExp(RegExp.escape(filter))

this.each(function(value, index ) {
if (filter.match(value))
results.push(iterator.call(context, value, index))
})
결과 반환; >
//특정 데이터가 포함되어 있는지 확인
function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != - 1 ) return true;

varfound = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $ break;
}
});
returnfound;
}

//마지막 그룹의 요소 수가 숫자보다 작은 경우, fillWith 매개변수를 사용하세요. while(slice.length < number) Slice.push(fillWith);
return Slice;
})
}

//계속해서 누적을 달성합니다. 또는 누적 곱셈 및 기타 연산
function inject(memo, iterator, context) {
this.each(function(value, index) {
memo = iterator.call(context, memo, value, index) ;
});
remove
}

//모든 데이터에 대해 메소드 실행
function inform(method) {
var args = $A(arguments ) .slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
})
}

//데이터에서 최대값 찾기
function max(iterator, context) {
iterator = iterator || Prototype.K
this.each(function(value; , index ) {
value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value
});
결과 반환
}

//데이터에서 최소값 찾기
function min(iterator, context) {
iterator = Prototype.K; >var result ;
this.each(function(value, index) {
value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
return result;
}

//모든 데이터를 2개로 나누고, 첫 번째 그룹은 특정 조건을 만족하는 데이터입니다. 두 번째 그룹 조건을 충족하지 않는 데이터의 경우
function partition(iterator, context) {
iterator = iterator || Prototype.K
var trues = [], falses = []
this.each(function(value, index) {
(iterator.call(context, value, index) ?
trues : falses).push(value);
}) return [ trues, falses];

//모든 데이터의 속성 값을 가져오고 결과를 반환합니다
function pluck(property) {
var results = []
this .each(function(value) {
results.push(value[property]);
})
return results
}

//결과 찾기 특정 조건부 데이터를 만족하지 않는
function recognition(iterator, context) {
var results = []
this.each(function(value, index) {
if (!iterator. call(context, value , index))
results.push(value);
})
return results
}

//모든 데이터를 특정 항목에 따라 정렬 조건
function sortBy(iterator, context) {
return this.map(function(value, index) {
return {
value: value,
criteria: iterator.call(context, 값, 인덱스)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? - 1 : a > ; b ? 1 : 0;
}).pluck('value')

//데이터의 배열 표현 반환
function
return this.map();
}

//기본적으로 특정 작업을 수행하기 위해 두 세트의 데이터를 함께 사용합니다.
function zip() {
var iterator = Prototype.K , args = $A(인수);
if (Object.isFunction(args.last()))
iterator = args.pop()

var collections = [this].concat (args ).map($A);
return this.map(function(value, index) {
return iterator(collections.pluck(index));
}); 🎜>
function size() {
return this.toArray().length;
}

//Enumerable 객체를 나타내는 문자열 표현을 반환합니다.
function Inspection() {
return '#'
}

return {
each: Each,
eachSlice: EachSlice ,
all: 모두,
every: 모두,
any: any,
some: any,
collect: 수집,
map: 수집,
Detect: 감지,
findAll: findAll,
선택: findAll,
필터: findAll,
grep: grep,
include: include,
member: include,
inGroupsOf: inGroupsOf,
inject: 주입,
invoke: 호출,
max: max,
min: min,
partition: partition,
pluck: pluck,
reject: 거부,
sortBy: sortBy,
toArray: toArray,
항목: toArray,
zip: zip,
크기: size,
검사: 검사,
찾기: 감지
} ;
})();



Enumerable에서 제공하는 메서드를 배워보겠습니다.

all

any

collect
탐지

eachSlice
항목
find
findAll
grep
inGroupsOf
include
inject
invoke
map
max
member
min
partition
pluck
reject
select
size
sortBy
toArray
zip
all 메소드:

여부를 결정합니다. 모든 요소는 직접적으로 또는 제공된 반복기에 의한 계산을 통해 true와 부울 동일합니다.

기본적으로 Each 메소드를 호출하여 각 데이터가 반복기 조건을 충족하는지 확인하고, 그 중 하나가 조건을 충족하지 않는 경우 반복자 조건에서 $break 예외가 발생하면 이 예외는 각 메서드에서 포착됩니다. 여기서 특정 객체를 해당 부울 값으로 변환할 수 있는 '!!'의 사용법에 주의하세요.

!!{} true

!![] true

!! 'False

!!' String 'true

0 false

예를 살펴보겠습니다.

🎜> 코드 복사

코드는 다음과 같습니다.


[].all()

// -> true(빈 배열에는 false와 동일할 수 있는 요소가 없음) ) $R(1, 5).all()

// -> true([1..5]의 모든 값은 true와 동일)


[0, 1, 2].all()
// -> false(단 하나의 루프 주기만 사용: 0은 false와 동일함)

[9, 10, 15].all(함수 (n) { return n > = 10; })
// -> false(반복자는 9에서 false를 반환합니다)

$H({ 이름: 'John', 나이: 29 , 죄송합니다: false }).all (function(pair) { return pair.value; })
// -> false(죄송합니다/false 쌍은 false 값을 생성합니다)




any 메소드:

는 all 메소드와 유사하므로 자세한 내용은 설명하지 않겠습니다.



코드를 복사하세요
코드는 다음과 같습니다


[].any()
// -> false(빈 배열에는 true와 동일할 수 있는 요소가 없음)

$R(0, 2).any( )
// -> true(두 번째 루프 주기에서 1은 true와 동일)

[2, 4, 6, 8, 10].any(function(n) { return 0 == n % 3; : false, opt3: '', opt4: 'pfew!' }).any(function(pair) { return pair.value; })
// -> true (opt4/'pfew!' 덕분에) 값이 true인 쌍)



collect/map(수집 메서드 별칭) 메서드:


반복자를 적용한 결과를 반환합니다. 각 요소에 별칭을 붙입니다.

이것은 일종의 스위스 군용 칼입니다. 원래 값을 거의 모든 것으로 바꿀 수 있습니다!

이 방법을 "Swiss"라고 합니다. Army Knife" "이 메서드는 기본적으로 데이터에 대한 모든 작업을 수행할 수 있습니다. 이 메서드의 별칭은 results.push(iterator.call(context, value, index))입니다. 문장이 핵심입니다. 각 데이터에 대해 반복자를 호출하고 결과를 반환할 배열에 저장하는 것입니다. 예시를 살펴보세요.


코드를 복사하세요.

코드는 다음과 같습니다.

['Hitch', "Hiker's", 'Guide', 'To', 'The', 'Galaxy'].collect(function(s) { return s.charAt(0).toUpperCase() }) .join('')

// -> 'HHGTTG'


$R(1,5).collect(function(n) { return n * n })
// -> [1, 4, 9, 16, 25]



도움말 문서의 마지막 몇 줄에 유의하세요. 🎜>

첫 번째, 메서드 호출 시나리오: 가능한 경우 인수를 사용하여 모든 요소에 대해 동일한 메서드를 호출하고 결과 값을 사용하려고 합니다.


두 번째, 속성 가져오기 시나리오: 모든 요소에서 동일한 속성을 가져와 사용하려고 합니다.

탐지 방법:

다음을 충족하는 첫 번째 데이터를 찾습니다. 실제로 이 메소드는 find의 별칭이므로 discover와 find 호출은 동일합니다.

코드 복사

// 약간 압축된 최적의 정확한 소수 감지 방법입니다. function isPrime(n) {

if (2 > n) return false; if (0 == n % 2) return (2 == n);

for (var index = 3; n / index > index; index = 2)
if (0 == n % index) return false
return true;
// isPrime
$R(10,15).find(isPrime) // -> 11

[ 'hello' , 'world', 'this', 'is', 'nice'].find(function(s) { return s.length <= 3; })
// ->






각 메소드:


이 메소드를 호출하면 실제로 각 데이터에 대해 반복 작업을 수행합니다. . 반복자 함수에 전달되는 첫 번째 매개변수는 데이터이고, 두 번째 매개변수는 Index이며, 순회 프로세스 중에 $continue 및 $break 예외가 발생할 수 있습니다. 참고:

사용법 <span style="font-family:新宋体">$continue</span>

는 속도를 위해 Prototype 1.5 이후 릴리스에서는 더 이상 사용되지 않습니다. .

예제 보기:<span style="font-family:新宋体">$continue</span>코드 복사 코드는 다음과 같습니다.


['하나', '둘', '셋'].each(function(s) { 경고(들); });

[ 'hello', 'world'].each(function(s) , index) { Alert(index ': ' }); // 경고 -> '0: hello' 다음 '1: world'

// 주입을 사용하는 누산기

// 여기...
var result = []
$R(1,10).each(function(n) {
if (0 == n % 2) throw $continue;
if (n > 6) throw $ break
result.push(n)
}); 1, 3, 5]







eachSlice 메소드:


다수의 단순 아래의 메소드는 더 이상 설명하지 않겠습니다. 기본적으로는 동일합니다.

코드 복사

코드는 다음과 같습니다.


var 학생 = [ { 이름: '써니', 나이: 20 }, { 이름: '오드리', 나이: 21 }, { 이름: '매트', 나이: 20 }, { 이름: ' Élodie', 나이: 26 }, { 이름: 'Will', 나이: 21 }, { 이름: 'David', 나이: 23 }, { 이름: 'Julien', 나이: 22 }, { 이름: 'Thomas' , 나이: 21 }, { 이름: '세르필', 나이: 22 } ]

students.eachSlice(4, function(toon) { return toon.pluck('name'); })
// -> [ ['써니', '오드리', '맷', '에로디'],
// ['윌', '데이비드', '줄리앙', '토마스'],
// ['Serpil'] ]

//아래 첫 번째 메소드는 Array 객체
students.eachSlice(2).first()
// -> name : 'Sunny', age: 20 }, { name: 'Audrey', age: 21 }]


entries 메소드는 toArray 메소드이고, map 메소드는 toArray 메소드, map 메소드는 Collect 메소드와 동일합니다:

코드 복사 코드는 다음과 같습니다:


$R(1, 5).toArray() // - > [1, 2, 3, 4, 5]


find/findAll(select 메소드의 별칭) 메소드:

코드 복사 코드는 다음과 같습니다.


//find method
[ 'hello', 'world', 'this', 'is' , 'nice'].find(function(s) { return s.length <= 3; })
// -> 'is'
//findAll 메소드
$R(1, 10).findAll(function(n) { return 0 == n % 2; })
// -> [2, 4, 6, 8, 10] [ 'hello', 'world', 'this ', 'is', 'nice'].findAll (함수(함수) { return s.length >= 5; })
// -> ['hello', 'world']


grep 메소드:
이 메소드에서 주목해야 할 점은 함수 내에서 매개변수 필터를 정규식으로 통일한 후 정규식의 match 메소드를 호출하여 판단하기

코드 복사 코드는 다음과 같습니다:


// 어딘가에 반복되는 문자가 있는 모든 문자열을 가져옵니다
[' hello', 'world', 'this', 'is', 'cool'].grep (/(.)1/)
// -> ['hello', 'cool']
/ / 0 또는 5로 끝나는 모든 숫자 가져오기
$R(1,30).grep (/[05]$/)
// ->
// 마이너스 1
$R(1,30).grep (/[05]$/, function(n) { return n - 1; })
// -> 4, 9, 14, 19, 24, 29]
//
['hello', 'world', 'this', 'is', 'cool'] 어딘가에서 반복되는 문자가 있는 모든 문자열을 가져옵니다. grep(/(.)1/)
// -> ['hello' , 'cool']
// 0 또는 5로 끝나는 모든 숫자를 가져옵니다
$R(1,30). grep(/[05]$/)
// -> [5, 10 , 15, 20, 25, 30]
// 마이너스 1
$R(1,30). grep(/[05]$/, function(n) { return n - 1; })
// -> [4, 9, 14, 19, 24, 29]


inGroupsOf 메소드:

코드 복사 코드는 다음과 같습니다.


var Students = [ { 이름: 'Sunny', 나이: 20 }, { 이름: 'Audrey', 나이: 21 }, { 이름: 'Matt', 나이: 20 }, { 이름: 'Élodie', 나이: 26 }, { 이름: 'Will', 나이: 21 }, { 이름: '데이비드', 나이: 23 }, { 이름: '줄리앙', 나이: 22 }, { 이름: '토마스', 나이: 21 }, { 이름: '세르필', 나이: 22 } ];
//pluck 메소드는 객체의 특정 속성을 얻는 것입니다. 여기서는 name 속성을 얻습니다.
students.pluck('name').inGroupsOf(4)
// -> [ ['Sunny', 'Audrey', 'Matt', 'Élodie'],
// ['Will', 'David', 'Julien', 'Thomas'],
// ['Serpil ', null, null, null] ]


include/member(include method alias) 메소드, 여기서는 먼저 객체에 indexOf 메소드가 있는지 확인하고, 있으면 호출합니다. 이 방법을 직접 사용하세요:

코드 복사 코드는 다음과 같습니다:


$R(1,15).include(10)
// -> true
['hello', 'world'].include('HELLO')
/ / -> false
[1, 2, '3', '4' , '5'].include(3)
// -> true(== 실제 유형 무시)



삽입 방법:

코드 복사 코드는 다음과 같습니다.


$R(1,10).inject(0, function(acc, n) { return acc n; })
// -> 55(1~10의 합)
$R(2,5).inject(1, function(acc, n) { return acc * n; })
// -> 120 (팩토리얼 5)
['hello', 'world' , 'this', 'is', 'nice'].inject([], function(array, value, index) {
if (0 == index % 2) array.push(value);
반환 배열
})
// -> ['hello', 'this', 'nice']



호출 메소드:

코드 복사 코드는 다음과 같습니다.


['hello', 'world', 'cool!'].invoke('toUpperCase')
// ['HELLO', 'WORLD', 'COOL!']
['hello', 'world', 'cool!'].invoke('substring', 0, 3)
// [ 'hel', 'wor', 'coo']


최대/최소 방법:

코드 복사 코드는 다음과 같습니다:


$R(1,10).max() // -> 10
['hello', 'world', 'gizmo'].max( )
// -> '세계'
function Person(name, age) { this.name = name; this.age = age }
var john = new Person('John', 20; );
var mark = new Person('Mark', 35);
var 데이지 = new Person('Daisy', 22)
[john, mark, 데이지].max(function(person) ) { return person.age })
// -> 35



파티션 방법:

코드 복사 코드는 다음과 같습니다.


['hello', null, 42, false, true, , 17].partition()
// -> ', 42, true, 17], [null, false, 정의되지 않음]]
$R(1, 10).partition(function(n) { return 0 == n % 2; })
// -> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]
['hello', null, 42, false, true, , 17].partition( )
// -> [['hello', 42, true, 17], [null, false, 정의되지 않음]]
$R(1, 10).partition(function(n) { return 0 == n % 2;
pluck 방법:


코드 복사
코드는 다음과 같습니다.

['hello', 'world', 'this' , 'is', 'nice'].pluck( 'length') // -> [5, 5, 4, 3, 4]




거부 방법:



코드 복사
코드는 다음과 같습니다.

$R(1, 10).reject(function(n) { return 0 == n % 2; }) // -> [1, 3, 5, 7, 9]

[ 'hello', 'world', 'this', 'is', ' nice'].reject(function(s) { return s.length >= 5; })

// -> ['this', 'is', 'nice']
$R(1 , 10).reject(function(n) { return 0 == n % 2; })
// -> [1, 3, 5, 7, 9]
[ 'hello', 'world ', 'this', 'is', 'nice'].reject(function(s) { return s.length >= 5; })
// -> ['this', 'is', 'nice']



size 방식이 생략되었습니다.

sortBy 메소드:

이 메소드는 먼저 map 메소드를 통해 객체 배열을 반환한 다음 배열의 sort 메소드를 호출하고 마지막으로 객체의 value 속성을 꺼냅니다.



코드 복사
코드는 다음과 같습니다:

['hello', 'world', 'this', 'is', 'nice'].sortBy( function(s) { return s.length ; }) // -> 'is', 'this', 'nice', 'hello', 'world']

['hello', 'world ', 'this', 'is' , 'cool'].sortBy(function(s) {

var md = s.match(/[aeiouy]/g);
return null == md ? 0 : md.length;
} )
// -> [ 'world', 'this', 'is', 'hello', 'cool'] (모음 개수순으로 정렬)



zip 방식 :


코드 복사
코드는 다음과 같습니다.


var firstNames = ['Justin', 'Mislav', 'Tobie', 'Christophe']
var lastNames = ['Palmer', 'Marohnić', 'Langel', 'Porteneuve'] ;
firstNames.zip(lastNames)
// -> [['Justin', 'Palmer'], ['Mislav', 'Marohnić'], ['Tobie', 'Langel'], [ 'Christophe', 'Porteneuve']]
//이 예에서 매개변수 a가 두 배열의 해당 항목을 나타내는 배열임을 알 수 있습니다.
firstNames.zip(lastNames, function(a) { return a.join(' ') })
// -> ['Justin Palmer', 'Mislav Marohnić', 'Tobie Langel', 'Christophe Porteneuve']
//이 예를 통해 다음을 수행할 수 있습니다.
에서 여러 배열을 전달할 수 있는지 확인하세요. var city = ['Memphis', 'Zagreb', 'Montreal', 'Paris']
firstNames.zip(lastNames, city, function(p) { return p [0] ' ' p[1] ', ' p[2] })
// -> ['Justin Palmer, Memphis', 'Mislav Marohnić, Zagreb', 'Tobie Langel, Montreal', ' Christophe Porteneuve, Paris']
firstNames.zip($R(1, 100), function(a) { return a.reverse().join('. '); })
// -> ['1. 저스틴', '2. 미슬라브', '4. 크리스토프']

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