서두에
많은 서평과 독서 노트에서《JavaScript 언어 정수》는 자자주玑라고 하며, 명불허전입니다.. 물론, 이해해야 하지만
사실 개인적으로 함수화 부분은 그렇게 좋지 않다고 생각합니다. 든 예가 매우 적절하지 않으며, 이전에 이해하지 못한 것은 성공적으로 오도되었기 때문입니다. 《Head First》디자인 패턴 제 1 장《전략 패턴》 과 마찬가지로, 저자가 일부 장의 테마에서 벗어나 독자가 오도되기 쉽습니다
성명: 일단 함수화 부분에서 제공된 객체를 생성하는 함수를*"창조 함수"*라고 부르겠습니다. "생성자 함수"와 구분하기 위해.. 그다지 좋은 이름은 아니지만, 참으면서 사용합시다
일.소스 코드에서 주의할 점
쉽게 소스 코드를入手할 수 있으며, 중국어판 책의 코드와 같습니다. 자세히 살펴보니 매우 교묘한 점 하나를 발견했지만, 물론, 이해하기 쉽지 않습니다
P.S. 소스 코드에 작은 문제가 있습니다: "창조 함수"cat 의 중괄호가 일치하지 않습니다. 중국어판 54 페이지, return that; 앞에};가 부족합니다
###Object 의 프로토타입 함수 superior 내부에 매우 교묘한 점이 있습니다
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function ( ) {
return method.apply(that, arguments);
};
});
하이라이트는 마지막 문장의 arguments 로, 일견 무심해 보이지만 실제로는 의도적인 것으로, superior 로 부모 클래스 메서드를 호출할 때도 매개변수를 전달할 수 있음을 나타냅니다. 물론, 매개변수를 전달하려면 호출 방식을 수정해야 합니다. 테스트 코드는 다음과 같습니다:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
var mammal = function (spec) {
var that = {};
that.get_name = function ( ) {
return spec.name;
};
that.says = function ( ) {
return spec.saying || '';
};
return that;
};
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
that.get_name = function ( ) {
alert("cat.get_name :" + arguments.length);///
return that.says( ) + ' ' + spec.name +
' ' + that.says( ) + "[" + arguments.length + "]";
};
return that;
};
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function ( ) {
alert("superior :" + arguments.length);///
return method.apply(that, arguments);
};
});
var coolcat = function (spec) {
var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function () {
alert("coolcat.get_name :" + arguments.length);///
return 'like ' + super_get_name.apply(this, arguments) + ' baby';
};
return that;
};
var myCoolCat = coolcat({name: 'Bix'});
var name = myCoolCat.get_name(1, 2, 3);
// 'like meow Bix meow baby'
alert(name); // 'like meow Bix meow[3] baby'
P.S. 처음에는 superior 함수의 마지막 arguments 가 저자의 실수라고 생각했고, 바깥의 arguments 객체를 안쪽이 아닌 method 에 전달해야 한다고 생각했습니다. 크게 우회하여 자신이 틀렸다는 것을 발견했습니다. 도행이 부족하여 더글라스様の 의미를 순간적으로 이해하지 못했습니다..
이.함수화의 취지
함수화 부분은 서두에서취지: 프라이빗 속성을 구현하기 위해, 마지막에 언급된 "위조 방지 객체"를 생성하는 것이라고 설명했습니다
목적은 비난의 여지가 없으며, 프라이빗 속성을 구현하는 것은 매우 필요합니다. 하지만 든 예 mammal -> cat -> coolcat 은 너무도 부적절합니다. 저자는 함수화 방식으로 상속을 구현할 수 있음을 설명하고 싶었습니다
물론, 엄밀한 의미에서의 상속은 아닙니다. 함수화 방식은 커스텀 타입을 사용하지 않았기 때문에, 서브클래스 인스턴스와 부모 클래스 인스턴스의 is-a 관계에 대해 논할 여지가 없습니다
P.S. 첫 번째로 볼 때 cat 의 예가 저를 골목으로 이끌었고, 함수화는 new 를 버리고 완전히 함수로 상속을 구현하는 것이라고 생각했습니다.. 자연스럽게 골목에서越走越深해졌습니다
삼.함수화의 사상
직접 코드를 봅시다. 코드 자신이 말합니다:
/*
* 함수화의 사상:
* 1.객체 생성
* 2.프라이빗 속성 추가
* 3.공개 인터페이스 (퍼블릭 속성 추가)
* 4.해당 객체 반환
*/
/*
* method: getSuper
* @param spec 사양 설명 객체, 객체 생성에 필요한 기본 데이터 제공
* @param my "창조 함수" 간 데이터 공유 컨테이너
*/
function getSuper(spec, my){
var obj; // 반환할 객체
var my = my || {}; // 전달되지 않으면 생성
// 프라이빗 속성
var attr = spec.value; // ���양 설명 객체에서 데이터 취득
var fun = function(){
alert(attr);
}
// [옵션] 다른 "창조 함수"와 공유해야 하는 데이터를 my 에装入
// 객체 생성, 임의의 방식 사용 가능, 예: new, 리터럴, 다른 "창조 함수" 호출
obj = {
name: "SuperObject"
};
// 공개 인터페이스
obj.fun1 = fun;
// obj 반환
return obj;
}
/*
* method: getSub
* 파라미터는 위와 동일
*/
function getSub(spec, my){
var obj;
var my = my || {};
// 프라이빗 속성
var attr = spec.value + 1;
var fun = function(){
alert(attr);
}
// [옵션] 공유
// 객체 생성
obj = getSuper(spec, my); // 직접 전달 가능, 물론 수정하여 전달하거나 다른 것 전달도 가능
// 공개 인터페이스
obj.fun2 = fun;
// obj 반환
return obj;
}
// 테스트
var spec = {
value: 1
};
var sub = getSub(spec); // my 를 전달할 필요 없음, my 는 "창조 함수" 간에만 사용해야 함
sub.fun1(); // 1
sub.fun2(); // 2
P.S. 또 "객체 생성 -> 강화 -> 새로운 객체 반환" 이套路입니다. 니콜라스가 말한 더글라스가 발명한 "모듈 패턴"이 아닙니까?
사.위조 방지 객체 (지속성의 객체)
함수화 부분의 핵심은 이것입니다. 위 예의 공개 인터페이스 방식에 주의하십시오:
// 프라이빗 속성
var myFun = function(){/* ... */};
// 공개 인터페이스
obj.fun = myFun;
직접 다음을 사용하는 것이 아니라:
// 공개 인터페이스
obj.fun = function(){/* ... */};
첫 번째 방식*더 안전*합니다. 외부에서 fun 을 수정해도, 내부의 다른 myFun 을 호출하는 메서드는 계속 정상적으로 작동할 수 있기 때문입니다. 이러한 함수 객체가 소위*위조 방지 객체*입니다
완전한 정의:
위조 방지 객체의 속성은 치환 또는 삭제 가능하지만, 해당 객체의 완전성은 훼손되지 않습니다
지속성의 객체라고도 하며, 지속성 객체란 단순한 기능 함수의 집합입니다
후일담
이로써《JavaScript 언어 정수》의 학습 노트는 한 단락 마무리되었습니다. [함수화] 의 공백을 메웠으며, 학습 노트의 다른 부분은 [黯羽輕揚:《JavaScript 언어 정수》학습 노트](http://ayqy.net/blog/《JavaScript 언어 정粹》学习笔记/) 를 참조하십시오
아직 댓글이 없습니다