简体   繁体   中英

Make an objects methods chainable in JavaScript

I have been doing battle with this project and understand the concept but cannot get my head wrapped around how to get the end result.

Given this code:

<!doctype html>
<html>
<head>
  <title> Make an objects methods chainable </title>
  <meta charset="utf-8">
  <script>

  function modifyFunction(f) {
    return function() {
      var returnValue = f.apply(this, arguments);

       if (returnValue === undefined) {
          return this;
       } else {
          return returnValue;
       }
     };
   }

   function modifyMethod(o, m) {
   // your code here
   //the object being passed is the var o
  //the method being passed is the add or sub functions contained in the
  // var

  var methodIn = o[m]; 
  var objectIn = o;
  var numIn;

  console.log("Method In: " + methodIn);
  console.log("Object In: " + objectIn);

    if (o.hasOwnProperty(m) ) { 
     var property = o[m];   
     console.log(property);
     console.log("o has property " + m); 
     modifyFunction(this);

     if (methodIn instanceof Function) {
     //  if (this instanceof o) {

       modifyFunction(o);
       return this;
       console.log("This after modifyFunction: " + this);
       console.log("after modifyFunction " + this);

     }        
        modifyFunction(m);   
      } 

 if (!o.hasOwnProperty(m)) {
    console.log("Function not contained in Object");
 }


}  

var o = {
  num: 0,
  add: function(x) {
    this.num += x;
 },
  sub: function(x) {
    this.num -= x;
 }
};

 // We cannot chain object o(s) method because they do not return 
 //--this--
 //o.add(4).sub(2); // fail - the methods are not chainable yet!

 // Make the add method chainable.

   modifyMethod(o, "add");

   // Now we can chain the add methods
   o.add(2).add(4);
   //console.log(o.num); // o.num = 6

   // Now make the sub method chainable

   //modifyMethod(o, "sub");

   // Now we can chain both the sub and add methods

  //o.sub(1).add(3).sub(5);
  //console.log(o.num);  // o.num = 3
 </script>
</head>
<body>
</body>
</html>

The objective is to use hasOwnProperty and instanceof to check if the object being passed in has the method property being passed in, I understand this and can see the results in the console. The instanceof is supposed to check to see if the property of the object is an instance of a function, I am not too clear on this and keep getting an error message returned (function expected). If I'm understanding this correctly I need to pass the info into the modifyFunction to perform the calculations?

I see the object being passed into the function and the methods (add and sub) functions, but just cannot figure out what I need to do to make it work. I apologize in advance for this code, but can someone help me to understand how to tie "this" all together?

I have looked through all of the postings on this topic but still cannot get it through my head. Thanks!

Functions can be passed around like variables in JavaScript, but they're essentially immutable, just like strings. If I gave you this code:

a = "my string";
b = a;

...and then asked you to change a into "your string", but without any a = blocks (so, changing the actual "my string" object, and not the reference), then barring some possibly extreme JS-hacking measures, you couldn't do it. They're created, and stay the same - but usually have methods to create similar ones off the existing ones.

Similarly, since you can't "change" a function, modifyFunction isn't doing quite what you think it is, because you're not assigning the result of its call to anything. So in some ways what I'm critiquing is a terminology difference - you can't "modify" a function, BUT, you can replace its local reference with one that references the original and does what you'd like. Try replacing this part of your code; and you can remove the other instance of modifyFunction

if (methodIn instanceof Function) {
 //  if (this instanceof o) {

   o[m] = modifyFunction(m);
   return o;

}

Another issue with what you were doing that I noticed late was that you were passing the object into modifyFunction , not the method. Additionally, your function isn't being called in the correct manner to use the this keyword. It's being called from the global context, so this will probably just be window . Just change any other necessary references to this into o , and it should be fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM