2013-07-15 2 views
10

저는 closure를 사용하여 private 및 public 메서드를 사용하여 객체를 만듭니다.JavaScript에서 개인 기능을 상속받을 수 있습니까?

var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    var _privateSaySize = function() { 
     return 'I am a ' + size + ' dog.'; 
    } 

    Dog.prototype.publicSaySize = function() { 
     return _privateSaySize(); 
    } 

    return Dog; 
})(); 

을하지만 지금은 오직 개인의 기능을 가진 개체를하고 싶은 그 다른 객체에 의해 상속됩니다 - 그것은 다음과 같습니다. 그러나 자바 스크립트에서 이것이 가능한가?

+1

이 함수는 무엇입니까? Dog = (function() {})()'? – Amberlamps

+2

'private' 멤버는 OOP를 지원하는 _any_ 언어로 정의 된 클래스 안에서 _only_ 볼 수 있습니다. 나는 네가하려는 일을 못 얻는다. – Leri

+0

일반적으로는 아니지만 '비공개 기능'은 'notSoPrivateSaySize = new Dog()'를 통해 쉽게 접근 할 수 있습니다.publicSaySize();' – Bergi

답변

1

다른 인스턴스의 개인 상태를 상속 받기를 원하십니까? JavaScript에서이 작업을 수행 할 수 있습니다. 다음과 같이

var Dog = (function() { 
    function Dog() { 
     if (this instanceof Dog) { 
      // constructor code 
     } else return Object.create(private); 
    } 

    var public = Dog.prototype, private = Object.create(public, { 
     size: { 
      value: "big" 
     } 
    }); 

    public.saySize = weakBind(function (private) { 
     return "I am a " + private.size + " dog."; 
    }, public, private); 

    return Dog; 
}()); 

지금 당신은 개를 만들 수 있습니다 다음과 같이

function weakBind(functable, prototype, state) { 
    return function() { 
     return functable.apply(this, Object.getPrototypeOf(this) === prototype ? 
      [state].concat(Array.prototype.slice.call(arguments)) : arguments); 
    }; 
} 

이제 우리는 우리의 기본 클래스를 생성 할 수 있습니다 : 처음에 우리는 유틸리티 함수를 정의 할 필요가

var dog = new Dog; 
alert(dog.saySize()); // I am a big dog. 
alert(dog.size);  // undefined 

을 우리 다음과 같이 개인 상태를 상속 할 수 있습니다.

var Chihuahua = (function() { 
    function Chihuahua() { 
     Dog.call(this); 
    } 

    var private = Dog(); 

    Object.defineProperty(private, { 
     size: { 
      value: "small" 
     } 
    }); 

    var public = Chihuahua.prototype = Object.create(Dog.prototype); 

    public.saySize = weakBind(public.saySize, public, private); 

    return Chihuahua; 
}()); 
다음과 같이 (210)

이제 치와와를 만들 수 있습니다

var chi = new Chihuahua; 
alert(chi.saySize()); // I am a small dog. 
alert(chi.size);   // undefined 

데모를 참조하십시오 http://jsfiddle.net/b3Eyn/

참고 :가 난 그냥 자바 스크립트에서 개인 상태를 상속 할 수 있다는 표시하려면이 대답을 썼다. 그러나 나는이 패턴을 사용하지 말 것을 권고합니다. 코드를 잘 디자인하면 처음부터 개인 상태를 상속받을 필요가 없습니다.

8

아니요, 할 수 없습니다.

JavaScript 상속은 프로토 타입 기반이므로 프로토 타입의 메서드 만 "확장"할 수 있습니다.

+0

동의 함. 많은 JS 개발자들이 퍼블릭 메소드에 앞에 공백을 두어 언더 스코어를 붙임으로써 퍼블릭 API의 보호를 받거나 공개 API의 일부가 아닌 것을 알리는 것만으로도 타협 할 필요는 없습니다. 개발자는 원할 경우 수정할 수 있지만 자체 위험이 있습니다. 솔직히 말하면 JS에서 공개적으로 액세스 할 수있는 객체의 보안을 유지하는 것은 상당히 쓸모없는 일입니다. 라이브러리를 사용하는 모든 사람이 공용 기능을 덮어 쓰거나 공유 객체/프로토 타입을 스크래치 할 수 있기 때문입니다. 두통의 가치가없는 것 같습니다. –

2

종류 ... Bergi가 지적했듯이 액세스는 범위로 정의됩니다. 따라서 상속자를 부모의 직속으로 정의하면 대략 원하는 것을 얻을 수 있습니다.

var BarkingDog; 
var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    var _privateSaySize = function() { 
     return 'I am a ' + size + ' dog.'; 
    }; 

    Dog.prototype.publicSaySize = function() { 
     return _privateSaySize(); 
    }; 

    BarkingDog = (function() { 
     function BarkingDog() {} 

     var say = 'woof'; 

     BarkingDog.prototype = new Dog(); 

     BarkingDog.prototype.bark = function() { 
      return _privateSaySize() + ' ' + say; 
     }; 

     return BarkingDog; 

    })(); 

    return Dog; 
})(); 

var myDog = new BarkingDog(); 
console.log(myDog.bark()); 
console.log(myDog.publicSaySize()); 

당신이 생각 ...하고 싶은 이유를 확실하지 : D 자바 스크립트에서

5

변수 (함수)의 개인 정보 보호는 기능 범위를 통해 이루어집니다. 클로저 범위에서 내 보낸 경우에만 외부에서 액세스 할 수 있습니다. 다른 방법은 없습니다.

메서드가 private 함수에 액세스 할 수있는 개체를 만들려면 동일한 범위에두면됩니다. 객체가 다른 객체에서 상속받은 객체인지 여부는 관계가 없습니다.

function Dog() {} 
function Dalmatian() {} 
Dalmation.prototype = Object.create(Dog.prototype); 
Dalmation.prototype.size = "big"; 
function Dackel() {} 
Dackel.prototype = Object.create(Dog.prototype); 
Dackel.prototype.size = "small"; 

(function() { 
    // private function 
    function say(s) { 
     console.log("I'm a "+s+" dog"); 
    } 
    // both accessible from the Dog and Dackel public methods 
    Dog.prototype.saySize = function() { 
     say(this.size || "normal"); 
    }; 
    Dackel.prototype.saySize = function() { 
     say(this.size + " but loud"); 
    }; 
})(); 
new Dog().saySize(); 
new Dalmatian().saySize(); 
new Dackel().saySize(); 
0

도트 표기법을 사용하지 않아도됩니다. 그러나 그것은 진정으로 사적인 것이 아닙니다.

var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    Dog.prototype['-privateSaySize'] = function() { 
     return 'I am a ' + size + ' dog.'; 
    } 

    Dog.prototype.publicSaySize = function() { 
     return this['-privateSaySize'](); 
    } 

    return Dog; 
})() 
+0

속성의 "내부"를 나타 내기 위해 밑줄'_'은 빼기가 아니라 사용됩니다. 그런 식으로 대괄호 표기법을 피할 수 있습니다 ... – Bergi

+0

@Bergi 그게 핵심입니다. 점 표기법을 사용할 수 없기 때문에 빼기를 사용 했으므로 대괄호 표기법을 사용하는 경우에만 사용할 수 있습니다. – boskop

+0

그게 어떻게 도움이됩니까? 프라이버시를 나타 내기 위해 [관례는 밑줄을 사용하는 것입니다] (http://stackoverflow.com/q/4484424/1048572). 대괄호 표기법은 아무 것도 변경하지 않습니다. – Bergi

관련 문제