Vietnam

    Nodejs.vn

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Tags
    • Groups
    • Search

    Kiểm soát thừa kế trong JS

    Hỏi Đáp
    0
    9
    1840
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      achung0147 last edited by achung0147

      Em có 1 cái object A . Bây giờ em muốn kiểm soát sao cho khi tạo một đối tượng A mới có tên là B thì cái New Object B này sẽ không thể thừa kế 1 số thuộc tính mà bên A có cũng như không thể truy cập được các dữ liệu trong A(một số thuộc tính và dữ liệu được ẩn - ở chế độ private mà bên ngoài không thể truy cập).

      var A = (function(data){
          this.getData = function(){
              return data;
          }
          this.getData2 = function(){
              return Math.random();
          }
          return this;
      }).call(A,6);
      var B = new A();
      B.getData2() //=> Làm ntn để object B không thể thừa kế cái getData2 này
      A.getData2() //=> Và chỉ có thể gọi function từ object A
      B.getData() //=> Làm ntn để cái này không return về 6,kiểu như trong B không được thừa hưởng cái biến data này vậy
      

      Vấn đề thứ 2 là em muốn hỏi về việc cấp quyền truy cập vào object :

      var obj1 = (function(){
           var data = 6;
           var rt = function(){ 
           }
           rt.back = function(){
               return data;
           }
          return rt;
      })();
      var obj2 = (function(){
          var data = obj1.back(); // Làm ntn để obj2 có thể có được quyền truy cập vào dữ liệu bên trong closure của obj1
          return {back_data:data}; // Must return 6
      })();
      var obj3 = (function(){
          var data = obj1.back(); // Còn obj3 thì không
          return {back_data:data};//Unwanted return 6
      })();
      

      Rất mong được giải đáp thắc mắc ! Cảm ơn mọi người ~~~

      Vũ hidemanvn P 3 Replies Last reply Reply Quote 0
      • Vũ
        Vũ Global Moderator @achung0147 last edited by

        @achung0147 Ý tưởng của bạn phức tạp quá, mình chưa nhìn thấy nó kế thừa ở chỗ nào 😃

        Như tình huống 1 của bạn thì B chỉ là thể hiện của A thôi. Bạn xem lại định nghĩa và các ví dụ về kế thừa trong JavaScript ở đây nhé

        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

        Tech-nông
        Email: [email protected]
        Profile: about.me/vunb
        Github: github.com/vunb
        Twitter: twitter.com/nhubaovu

        1 Reply Last reply Reply Quote 0
        • hidemanvn
          hidemanvn @achung0147 last edited by

          @achung0147 thực sự thì có thể làm đc nhưng ko nên. Ví dụ:

          var assert = require('assert');
          log = console.log;
          
          var A = (function() {
          	var _A = function(data) {
          		this.data = data;
          	}
          	_A.getData = function() {
          		return this.data;
          	}
          	_A.getRandom = function() {
          		return Math.random();
          	}
          	_A.prototype.hello = function(){
          		log('hello from B');
          	}
          
          	return _A;
          })();
          
          var B = new A();
          // assert 
          assert(B.getData == undefined, 'B.getData is inherited'); 
          assert(A.getData instanceof Function,'A.getData is not a Function'); 
          assert(B.getRandom == undefined ,'B.getRandom is inherited'); 
          assert(B.hello  instanceof Function,'B.hello is not a Function'); 
          
          // log test
          // A.hello(); // Error 
          // B.getData(); // Error 
          // B.getRandom(); // Error 
          log(A.getRandom());
          B.hello();
          
          

          Mình nghĩ bạn nên viết function riêng rẽ, khi cần thì import vào đối tượng thì hay hơn.

          1 Reply Last reply Reply Quote 0
          • N
            Nam Nguyen26 last edited by

            Bạn xem qua về "Closure" trong Js, private function có thể được viết như sau

            function wrapper {
            var a = function a () { }
            var b = function b () { }
            return { b }
            }

            ... function a sẽ là private

            1 Reply Last reply Reply Quote 0
            • P
              Phuc Phan66 @achung0147 last edited by Phuc Phan66

              @achung0147 Bạn nên diễn tả ý tưởng bằng lời thì hơn:
              Ý 1: Cần tạo đối tượng A có nhiệm vụ tạo ra đối tượng B và có những thuộc tính và phương thức B sẽ không được thừa hưởng từ A.
              Ý 2: Cần tạo ra đối tượng A chứa dữ liệu và cấp quyền truy cập cho các đối tượng khác. Ví dụ B được truy cập còn C không.
              Có phải ý bạn vậy không?

              A 1 Reply Last reply Reply Quote 0
              • A
                achung0147 @Phuc Phan66 last edited by

                @Phuc-Phan66 đúng rồi ạ

                1 Reply Last reply Reply Quote 0
                • P
                  Phuc Phan66 last edited by Phuc Phan66

                  @achung0147
                  Có đoạn mã cần chú ý giả sử chạy trong Global thì nó thế này.

                  var A = (function(data) {
                  	// Cái "this" ở trong này chính là  Global nếu ở chế độ strict mode sẽ là null hoặc undefined.
                  
                      this.getData = function() {
                          return data;
                      }
                      this.getData2 = function() {
                          return Math.random();
                      }
                      return this;
                  }).call(A, 6)
                  //Bạn đã chạy nó
                  

                  tương tự mã của @hidemanvn nếu không may gọi hàm:

                  A("number");    //sẽ xuất hiện (Global).data = 'number'; có thể nó không bao giờ được gọi
                  

                  Có thể mình không hiểu hoặc hiểu nhầm ý của bạn chỉ là đề xuất một số mã nhỏ.
                  Cái này sửa một chút mã thứ hai của bạn:

                  var obj1 = (function() {
                      var data = 6;
                      var rt = function() {}
                      rt.back = function() {
                          var callName = arguments.callee.caller.name;
                          if (callName == "createTypeObj2") {
                              return data;
                          }
                          if (callName !== "createTypeObj2") {
                              return "Không phải 6";
                  
                          }
                      }
                      return rt;
                  })();
                  
                  function createTypeObj2() {
                      var data = obj1.back(); // Làm ntn để obj2 có thể có được quyền truy cập vào dữ liệu bên trong closure của obj1
                      return {
                          back_data: data
                      }; // Must return 6
                  };
                  
                  function createTypeObj3() {
                      var data = obj1.back(); // Còn obj3 thì không
                      return {
                          back_data: data
                      }; //Unwanted return 6
                  };
                  var obj2 = createTypeObj2();
                  var obj3 = createTypeObj3();
                  
                  /*Test*/
                  console.log(obj2);   // {back_data: 6}
                  console.log(obj3);	 // {back_data: "Không phải 6"}
                  
                  hidemanvn 1 Reply Last reply Reply Quote 0
                  • P
                    Phuc Phan66 last edited by Phuc Phan66

                    Về ý thứ nhất của ban:
                    //=> Làm ntn để object B không thể thừa kế cái getData2 này
                    Bạn đừng viết constructor và prototypes có nó.
                    //=> getData2 Và chỉ có thể gọi function từ object A
                    Bạn đừng viết constructor và prototypes có nó.
                    Mà tạo trực tiếp là A.getData2 = xyz..;
                    //=> Làm ntn để cái này không return về 6,kiểu như trong B không được thừa hưởng cái biến data này vậy
                    Bạn phải thiết lập nó return cái bạn muốn.
                    //Tránh việc "this" vô tình tham chiếu Global nên thêm một đoạn mã kiểu như thế này cho constructor :

                    function A() {
                        if (!(this instanceof A))
                            return new A();
                    }
                    
                    1 Reply Last reply Reply Quote 0
                    • hidemanvn
                      hidemanvn @Phuc Phan66 last edited by

                      @Phuc-Phan66 mình viết ví dụ vậy thôi chứ thực tế làm việc thì chẳng bao giờ mình để hàm nó ngoài vòng global đâu. Mình gặp trường hợp này thì mình chia nhỏ function hoặc xác định object con rồi import vào object.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post