上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

闭包练习(ClosurePractices)

[复制链接]
  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2022-7-13 22:27:37 | 显示全部楼层 | 阅读模式

    练习要求

    Closures, Scope, and Execution Context
    Challenge 1
    Create a function createFunction that creates and returns a function. When that created function is called, it should print "hello". When you think you completed createFunction, un-comment out those lines in the code and run it to see if it works.
    Challenge 2
    Create a function createFunctionPrinter that accepts one input and returns a function. When that created function is called, it should print out the input that was used when the function was created.
    Challenge 3
    Examine the code for the outer function. Notice that we are returning a function and that function is using variables that are outside of its scope.
    Uncomment those lines of code. Try to deduce the output before executing. Now we are going to create a function addByX that returns a function that will add an input by x.
    Challenge 4
    Write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.
    Challenge 5
    Write a function after that takes the number of times the callback needs to be called before being executed as the first parameter and the callback as the second parameter.
    Challenge 6
    Write a function delay that accepts a callback as the first parameter and the wait in milliseconds before allowing the callback to be invoked as the second parameter. Any additional arguments after wait are provided to func when it is invoked. HINT: research setTimeout();
    Challenge 7
    Write a function rollCall that accepts an array of names and returns a function. The first time the returned function is invoked, it should log the first name to the console. The second time it is invoked, it should log the second name to the console, and so on, until all names have been called. Once all names have been called, it should log 'Everyone accounted for'.
    Challenge 8
    Create a function saveOutput that accepts a function (that will accept one argument), and a string (that will act as a password). saveOutput will then return a function that behaves exactly like the passed-in function, except for when the password string is passed in as an argument. When this happens, the returned function will return an object with all previously passed-in arguments as keys, and the corresponding outputs as values.
    Challenge 9
    Create a function cycleIterator that accepts an array, and returns a function. The returned function will accept zero arguments. When first invoked, the returned function will return the first element of the array. When invoked a second time, the returned function will return the second element of the array, and so forth. After returning the last element of the array, the next invocation will return the first element of the array again, and continue on with the second after that, and so forth.
    Challenge 10
    Create a function defineFirstArg that accepts a function and an argument. Also, the function being passed in will accept at least one argument. defineFirstArg will return a new function that invokes the passed-in function with the passed-in argument as the passed-in function's first argument. Additional arguments needed by the passed-in function will need to be passed into the returned function.
    Challenge 11
    Create a function dateStamp that accepts a function and returns a function. The returned function will accept however many arguments the passed-in function accepts, and return an object with a date key that contains a timestamp with the time of invocation, and an output key that contains the result from invoking the passed-in function. HINT: You may need to research how to access information on Date objects.
    Challenge 12
    Create a function censor that accepts no arguments. censor will return a function that will accept either two strings, or one string. When two strings are given, the returned function will hold onto the two strings as a pair, for future use. When one string is given, the returned function will return the same string, except all instances of first strings (of saved pairs) will be replaced with their corresponding second strings (of those saved pairs).
    Challenge 13
    There's no such thing as private properties on a JavaScript object! But, maybe there are? Implement a function createSecretHolder(secret) which accepts any value as secret and returns an object with ONLY two methods. getSecret() which returns the secret setSecret() which sets the secret
    Challenge 14
    Write a function, callTimes, that returns a new function. The new function should return the number of times it’s been called.
    Challenge 15
    Create a function roulette that accepts a number (let us call it n), and returns a function. The returned function will take no arguments, and will return the string 'spin' the first n - 1 number of times it is invoked. On the very next invocation (the nth invocation), the returned function will return the string 'win'. On every invocation after that, the returned function returns the string 'pick a number to play again'.
    Challenge 16
    Create a function average that accepts no arguments, and returns a function (that will accept either a number as its lone argument, or no arguments at all). When the returned function is invoked with a number, the output should be average of all the numbers have ever been passed into that function (duplicate numbers count just like any other number). When the returned function is invoked with no arguments, the current average is outputted. If the returned function is invoked with no arguments before any numbers are passed in, then it should return 0.
    Challenge 17
    Create a function makeFuncTester that accepts an array (of two-element sub-arrays), and returns a function (that will accept a callback). The returned function should return true if the first elements (of each sub-array) being passed into the callback all yield the corresponding second elements (of the same sub-array). Otherwise, the returned function should return false.
    Challenge 18
    Create a function makeHistory that accepts a number (which will serve as a limit), and returns a function (that will accept a string). The returned function will save a history of the most recent "limit" number of strings passed into the returned function (one per invocation only). Every time a string is passed into the function, the function should return that same string with the word 'done' after it (separated by a space). However, if the string 'undo' is passed into the function, then the function should delete the last action saved in the history, and return that deleted string with the word 'undone' after (separated by a space). If 'undo' is passed into the function and the function's history is empty, then the function should return the string 'nothing to undo'.
    Challenge 19
    Inspect the commented out test cases carefully if you need help to understand these instructions.
    
    Create a function blackjack that accepts an array (which will contain numbers ranging from 1 through 11), and returns a DEALER function. The DEALER function will take two arguments (both numbers), and then return yet ANOTHER function, which we will call the PLAYER function.
    On the FIRST invocation of the PLAYER function, it will return the sum of the two numbers passed into the DEALER function.
    
    On the SECOND invocation of the PLAYER function, it will return either:
    
    the first number in the array that was passed into blackjack PLUS the sum of the two numbers passed in as arguments into the DEALER function, IF that sum is 21 or below, OR
    the string 'bust' if that sum is over 21.
    
    If it is 'bust', then every invocation of the PLAYER function AFTER THAT will return the string 'you are done!' (but unlike 'bust', the 'you are done!' output will NOT use a number in the array). If it is NOT 'bust', then the next invocation of the PLAYER function will return either:
    
    the most recent sum plus the next number in the array (a new sum) if that new sum is 21 or less, OR
    the string 'bust' if the new sum is over 21.
    
    And again, if it is 'bust', then every subsequent invocation of the PLAYER function will return the string 'you are done!'. Otherwise, it can continue on to give the next sum with the next number in the array, and so forth.
    You may assume that the given array is long enough to give a 'bust' before running out of numbers.
    
    BONUS: Implement blackjack so the DEALER function can return more PLAYER functions that will each continue to take the next number in the array after the previous PLAYER function left off. You will just need to make sure the array has enough numbers for all the PLAYER functions.

    练习模板

    // CHALLENGE 1
    function createFunction() {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const function1 = createFunction();
    // function1(); // => should console.log('hello');
    
    // CHALLENGE 2
    function createFunctionPrinter(input) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const printSample = createFunctionPrinter('sample');
    // printSample(); // => should console.log('sample');
    // const printHello = createFunctionPrinter('hello');
    // printHello(); // => should console.log('hello');
    
    // CHALLENGE 3
    function outer() {
      let counter = 0; // this variable is outside incrementCounter's scope
      function incrementCounter () {
        counter ++;
        console.log('counter', counter);
      }
      return incrementCounter;
    }
    
    const willCounter = outer();
    const jasCounter = outer();
    
    // Uncomment each of these lines one by one.
    // Before your do, guess what will be logged from each function call.
    
    // /*** Uncomment these to check your work! ***/
    // willCounter();
    // willCounter();
    // willCounter();
    
    // jasCounter();
    // willCounter();
    
    function addByX(x) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const addByTwo = addByX(2);
    // addByTwo(1); // => should return 3
    // addByTwo(2); // => should return 4
    // addByTwo(3); // => should return 5
    
    // const addByThree = addByX(3);
    // addByThree(1); // => should return 4
    // addByThree(2); // => should return 5
    
    // const addByFour = addByX(4);
    // addByFour(4); // => should return 8
    // addByFour(5); // => should return 9
    
    // CHALLENGE 4
    function once(func) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const onceFunc = once(addByTwo);
    // console.log(onceFunc(4));  // => should log 6
    // console.log(onceFunc(10));  // => should log 6
    // console.log(onceFunc(9001));  // => should log 6
    
    // CHALLENGE 5
    function after(count, func) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const called = function() { console.log('hello') };
    // const afterCalled = after(3, called);
    // afterCalled(); // => nothing is printed
    // afterCalled(); // => nothing is printed
    // afterCalled(); // => 'hello' is printed
    
    // CHALLENGE 6
    function delay(func, wait) {
    
    }
    
    // CHALLENGE 7
    function rollCall(names) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const rollCaller = rollCall(['Victoria', 'Juan', 'Ruth'])
    // rollCaller() // => should log 'Victoria'
    // rollCaller() // => should log 'Juan'
    // rollCaller() // => should log 'Ruth'
    // rollCaller() // => should log 'Everyone accounted for'
    
    // CHALLENGE 8
    function saveOutput(func, magicWord) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const multiplyBy2 = function(num) { return num * 2; };
    // const multBy2AndLog = saveOutput(multiplyBy2, 'boo');
    // console.log(multBy2AndLog(2)); // => should log 4
    // console.log(multBy2AndLog(9)); // => should log 18
    // console.log(multBy2AndLog('boo')); // => should log { 2: 4, 9: 18 }
    
    // CHALLENGE 9
    function cycleIterator(array) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const threeDayWeekend = ['Fri', 'Sat', 'Sun'];
    // const getDay = cycleIterator(threeDayWeekend);
    // console.log(getDay()); // => should log 'Fri'
    // console.log(getDay()); // => should log 'Sat'
    // console.log(getDay()); // => should log 'Sun'
    // console.log(getDay()); // => should log 'Fri'
    
    // CHALLENGE 10
    function defineFirstArg(func, arg) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const subtract = function(big, small) { return big - small; };
    // const subFrom20 = defineFirstArg(subtract, 20);
    // console.log(subFrom20(5)); // => should log 15
    
    // CHALLENGE 11
    function dateStamp(func) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const stampedMultBy2 = dateStamp(n => n * 2);
    // console.log(stampedMultBy2(4)); // => should log { date: (today's date), output: 8 }
    // console.log(stampedMultBy2(6)); // => should log { date: (today's date), output: 12 }
    
    // CHALLENGE 12
    function censor() {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const changeScene = censor();
    // changeScene('dogs', 'cats');
    // changeScene('quick', 'slow');
    // console.log(changeScene('The quick, brown fox jumps over the lazy dogs.')); // => should log 'The slow, brown fox jumps over the lazy cats.'
    
    // CHALLENGE 13
    function createSecretHolder(secret) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // obj = createSecretHolder(5)
    // obj.getSecret() // => returns 5
    // obj.setSecret(2)
    // obj.getSecret() // => returns 2
    
    // CHALLENGE 14
    function callTimes() {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // let myNewFunc1 = callTimes();
    // let myNewFunc2 = callTimes();
    // myNewFunc1(); // => 1
    // myNewFunc1(); // => 2
    // myNewFunc2(); // => 1
    // myNewFunc2(); // => 2
    
    // CHALLENGE 15
    function roulette(num) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const play = roulette(3);
    // console.log(play()); // => should log 'spin'
    // console.log(play()); // => should log 'spin'
    // console.log(play()); // => should log 'win'
    // console.log(play()); // => should log 'pick a number to play again'
    // console.log(play()); // => should log 'pick a number to play again'
    
    // CHALLENGE 16
    function average() {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const avgSoFar = average();
    // console.log(avgSoFar()); // => should log 0
    // console.log(avgSoFar(4)); // => should log 4
    // console.log(avgSoFar(8)); // => should log 6
    // console.log(avgSoFar()); // => should log 6
    // console.log(avgSoFar(12)); // => should log 8
    // console.log(avgSoFar()); // => should log 8
    
    // CHALLENGE 17
    function makeFuncTester(arrOfTests) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const capLastTestCases = [];
    // capLastTestCases.push(['hello', 'hellO']);
    // capLastTestCases.push(['goodbye', 'goodbyE']);
    // capLastTestCases.push(['howdy', 'howdY']);
    // const shouldCapitalizeLast = makeFuncTester(capLastTestCases);
    // const capLastAttempt1 = str => str.toUpperCase();
    // const capLastAttempt2 = str => str.slice(0, -1) + str.slice(-1).toUpperCase();
    // console.log(shouldCapitalizeLast(capLastAttempt1)); // => should log false
    // console.log(shouldCapitalizeLast(capLastAttempt2)); // => should log true
    
    // CHALLENGE 18
    function makeHistory(limit) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    // const myActions = makeHistory(2);
    // console.log(myActions('jump')); // => should log 'jump done'
    // console.log(myActions('undo')); // => should log 'jump undone'
    // console.log(myActions('walk')); // => should log 'walk done'
    // console.log(myActions('code')); // => should log 'code done'
    // console.log(myActions('pose')); // => should log 'pose done'
    // console.log(myActions('undo')); // => should log 'pose undone'
    // console.log(myActions('undo')); // => should log 'code undone'
    // console.log(myActions('undo')); // => should log 'nothing to undo'
    
    // CHALLENGE 19
    function blackjack(array) {
    
    }
    
    // /*** Uncomment these to check your work! ***/
    
    // /*** DEALER ***/
    // const deal = blackjack([2, 6, 1, 7, 11, 4, 6, 3, 9, 8, 9, 3, 10, 4, 5, 3, 7, 4, 9, 6, 10, 11]);
    
    // /*** PLAYER 1 ***/
    // const i_like_to_live_dangerously = deal(4, 5);
    // console.log(i_like_to_live_dangerously()); // => should log 9
    // console.log(i_like_to_live_dangerously()); // => should log 11
    // console.log(i_like_to_live_dangerously()); // => should log 17
    // console.log(i_like_to_live_dangerously()); // => should log 18
    // console.log(i_like_to_live_dangerously()); // => should log 'bust'
    // console.log(i_like_to_live_dangerously()); // => should log 'you are done!'
    // console.log(i_like_to_live_dangerously()); // => should log 'you are done!'
    
    // /*** BELOW LINES ARE FOR THE BONUS ***/
    
    // /*** PLAYER 2 ***/
    // const i_TOO_like_to_live_dangerously = deal(2, 2);
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 4
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 15
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 19
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 'bust'
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 'you are done!
    // console.log(i_TOO_like_to_live_dangerously()); // => should log 'you are done!
    
    // /*** PLAYER 3 ***/
    // const i_ALSO_like_to_live_dangerously = deal(3, 7);
    // console.log(i_ALSO_like_to_live_dangerously()); // => should log 10
    // console.log(i_ALSO_like_to_live_dangerously()); // => should log 13
    // console.log(i_ALSO_like_to_live_dangerously()); // => should log 'bust'
    // console.log(i_ALSO_like_to_live_dangerously()); // => should log 'you are done!
    // console.log(i_ALSO_like_to_live_dangerously()); // => should log 'you are done!
    

    我的答案

    // CHALLENGE 1
    function createFunction() {
      return function(){
        console.log('hello');
      }
      }
    
      // /*** Uncomment these to check your work! ***/
      const function1 = createFunction();
      function1(); // => should console.log('hello');
    
      // CHALLENGE 2
      function createFunctionPrinter(input) {
       return function(){
        console.log(input);
      }
      }
    
      // /*** Uncomment these to check your work! ***/
      const printSample = createFunctionPrinter('sample');
      printSample(); // => should console.log('sample');
      const printHello = createFunctionPrinter('hello');
      printHello(); // => should console.log('hello');
    
      // CHALLENGE 3
      function outer() {
        let counter = 0; // this variable is outside incrementCounter's scope
        function incrementCounter () {
          counter ++;
          console.log('counter', counter);
        }
        return incrementCounter;
      }
    
      const willCounter = outer();
      const jasCounter = outer();
    
      // Uncomment each of these lines one by one.
      // Before your do, guess what will be logged from each function call.
    
      // /*** Uncomment these to check your work! ***/
      willCounter();
      willCounter();
      willCounter();
    
      jasCounter();
      willCounter();
    
      function addByX(x) {
        return function(y){
          console.log(y+x)
          return y+x
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const addByTwo = addByX(2);
      addByTwo(1); // => should return 3
      addByTwo(2); // => should return 4
      addByTwo(3); // => should return 5
    
      const addByThree = addByX(3);
      addByThree(1); // => should return 4
      addByThree(2); // => should return 5
    
      const addByFour = addByX(4);
      addByFour(4); // => should return 8
      addByFour(5); // => should return 9
    
      // CHALLENGE 4
      function once(func) {
         let count=0 
         let once=null
         return function(add){
           const value= ++count>1 ?  once  : (once=func.call(null,add))
           return value
         }
      }
    
      /*** Uncomment these to check your work! ***/
      const onceFunc = once(addByTwo);
      console.log(onceFunc(4));  // => should log 6
      console.log(onceFunc(10));  // => should log 6
      console.log(onceFunc(9001));  // => should log 6
    
      // CHALLENGE 5
      function after(count, func) {
        let times=0
        return function(){
          if(++times<count) console.log("nothing")
          else{
            func.call(null)
          }
        }
      }
    
      /*** Uncomment these to check your work! ***/
      const called = function() { console.log('hello') };
      const afterCalled = after(3, called);
      afterCalled(); // => nothing is printed
      afterCalled(); // => nothing is printed
      afterCalled(); // => 'hello' is printed
    
      // CHALLENGE 6
      function delay(func, wait) {
         return function(){
           setTimeout(func,wait)
         }
      }
      const  after5sOutput= delay(()=>console.log(111),5000)
    
      after5sOutput()
    
      // CHALLENGE 7
      function rollCall(names) {
        let index=0
        return function(){
          if(index<names.length){
            console.log(names[index++])
    
          }else{
            console.log("Everyone accounted for")
          }
        }
    
      }
    
      // /*** Uncomment these to check your work! ***/
      const rollCaller = rollCall(['Victoria', 'Juan', 'Ruth'])
      rollCaller() // => should log 'Victoria'
      rollCaller() // => should log 'Juan'
      rollCaller() // => should log 'Ruth'
      rollCaller() // => should log 'Everyone accounted for'
    
      // CHALLENGE 8
      function saveOutput(func, magicWord) {
           let obj={}
           let pwd=magicWord
           return function(x){
             if(x!==magicWord){
               obj[x]=func(x)
               return obj[x]
             }else{
               return obj
             }
           }
    
      }
    
      // /*** Uncomment these to check your work! ***/
      const multiplyBy2 = function(num) { return num * 2; };
      const multBy2AndLog = saveOutput(multiplyBy2, 'boo');
      console.log(multBy2AndLog(2)); // => should log 4
      console.log(multBy2AndLog(9)); // => should log 18
      console.log(multBy2AndLog('boo')); // => should log { 2: 4, 9: 18 }
    
      // CHALLENGE 9
      function cycleIterator(array) {
        let index=0
        let len=array.length
        return function(){
           return array[ index++ % len ]
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const threeDayWeekend = ['Fri', 'Sat', 'Sun'];
      const getDay = cycleIterator(threeDayWeekend);
      console.log(getDay()); // => should log 'Fri'
      console.log(getDay()); // => should log 'Sat'
      console.log(getDay()); // => should log 'Sun'
      console.log(getDay()); // => should log 'Fri'
      console.log(getDay()); // => should log 'Sat'
      console.log(getDay()); // => should log 'Sun'
      console.log(getDay()); // => should log 'Fri'
    
      // CHALLENGE 10
      function defineFirstArg(func, arg) {
        return function(...secondAndafter){
          return func.bind(null,arg).apply(null,secondAndafter)
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const subtract = function(big, small) { return big - small; };
      const subtract1 = function(big, mid,small) { return big -mid- small; };
      const subFrom20 = defineFirstArg(subtract, 20);
      const sub1From100 = defineFirstArg(subtract1,100)
      console.log(subFrom20(5)); // => should log 15
      console.log(sub1From100(30,30));
    
      // CHALLENGE 11
      function dateStamp(func) {
         return function(x){
           return {date:+new Date(),output:func(x)}
    
         }
      }
    
      // /*** Uncomment these to check your work! ***/
      const stampedMultBy2 = dateStamp(n => n * 2);
      console.log(stampedMultBy2(4)); // => should log { date: (today's date), output: 8 }
      console.log(stampedMultBy2(6)); // => should log { date: (today's date), output: 12 }
    
      // CHALLENGE 12
      function censor() {
        let strReplacerMap=new Map()
        return function change(...args){
            if(args.length==2) strReplacerMap.set(args[0],args[1])
            else{
              let s=args[0]
              for(let [oldval ,newval] of strReplacerMap){
                  s=s.replace(oldval,newval)
              }
              return s
            }  
    
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const changeScene = censor();
      changeScene('dogs', 'cats');
      changeScene('quick', 'slow');
      console.log(changeScene('The quick, brown fox jumps over the lazy dogs.')); // => should log 'The slow, brown fox jumps over the lazy cats.'
    
      // CHALLENGE 13
      function createSecretHolder(secret) {
    
        let secr=secret
    
        function getSecret(){
            return secr
    
          }
        function setSecret(s){
          secr=s
        }
    
        return {
          getSecret,
          setSecret}
    
      }
    
      // /*** Uncomment these to check your work! ***/
      let obj = createSecretHolder(5)
      console.log(obj.getSecret()) // => returns 5
      obj.setSecret(2)
      console.log(obj.getSecret()) // => returns 2
    
      // CHALLENGE 14
      function callTimes() {
        let times=0
        return function(){
          return ++times
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      let myNewFunc1 = callTimes();
      let myNewFunc2 = callTimes();
      console.log(myNewFunc1()) // => 1
      console.log(myNewFunc1()) // => 2
      console.log(myNewFunc2()) // => 1
      console.log(myNewFunc2()) // => 2
    
      // CHALLENGE 15
      function roulette(num) {
        let times=0
        return  function(){
          ++times
          if(times<num){
            return "spin"
          }else if(times==num){
            return 'win'
          }else{
            return 'pick a number to play again'
          }
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const play = roulette(3);
      console.log(play()); // => should log 'spin'
      console.log(play()); // => should log 'spin'
      console.log(play()); // => should log 'win'
      console.log(play()); // => should log 'pick a number to play again'
      console.log(play()); // => should log 'pick a number to play again'
    
      // CHALLENGE 16
      function average() {
         let arr=[]
        return function(x){
          if(x){
            arr.push(x)
          }
        if(arr.length===0) return 0
         return (arr.reduce((prev,cur)=>prev+cur,0) ) / arr.length
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const avgSoFar = average();
      console.log(avgSoFar()); // => should log 0
      console.log(avgSoFar(4)); // => should log 4
      console.log(avgSoFar(8)); // => should log 6
      console.log(avgSoFar()); // => should log 6
      console.log(avgSoFar(12)); // => should log 8
      console.log(avgSoFar()); // => should log 8
    
      // CHALLENGE 17
      function makeFuncTester(arrOfTests) {
    
        return function(callback){
            const arr=JSON.parse(JSON.stringify(arrOfTests))
            const res= arr.map(([str1,str2])=>[callback(str1),str2])
            return  res.every(([str1,str2])=>str1===str2)
    
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const capLastTestCases = [];
      capLastTestCases.push(['hello', 'hellO']);
      capLastTestCases.push(['goodbye', 'goodbyE']);
      capLastTestCases.push(['howdy', 'howdY']);
      const shouldCapitalizeLast = makeFuncTester(capLastTestCases);
      const capLastAttempt1 = str => str.toUpperCase();
      const capLastAttempt2 = str => str.slice(0, -1) + str.slice(-1).toUpperCase();
      console.log(shouldCapitalizeLast(capLastAttempt1)); // => should log false
      console.log(shouldCapitalizeLast(capLastAttempt2)); // => should log true
    
      // CHALLENGE 18
      function makeHistory(limit) {
         let historyRecords=[]
        return function(str){
          if(str!='undo'){
            let len=historyRecords.length
            if(len<limit){
              historyRecords.push(str)
              return   historyRecords[historyRecords.length-1]+" done"
            }else{
              historyRecords.shift()
              historyRecords.push(str)
              return   historyRecords[historyRecords.length-1]+" done"
            }
          }else{
            if(historyRecords.length===0) return "nothing to undo"
            const val=historyRecords.pop()
            return val+" undone"
          }
        }
      }
    
      // /*** Uncomment these to check your work! ***/
      const myActions = makeHistory(2);
      console.log(myActions('jump')); // => should log 'jump done'
      console.log(myActions('undo')); // => should log 'jump undone'
      console.log(myActions('walk')); // => should log 'walk done'
      console.log(myActions('code')); // => should log 'code done'
      console.log(myActions('pose')); // => should log 'pose done'
      console.log(myActions('undo')); // => should log 'pose undone'
      console.log(myActions('undo')); // => should log 'code undone'
      console.log(myActions('undo')); // => should log 'nothing to undo'
    
      // CHALLENGE 19
      function blackjack(array) {
        let index=0
        return function dealer(num1,num2){
             let times=0
             let state='normal'
             let sum=0
           return function player(){
             if(++times==1&&(num1 + num2 )<=21) {
               sum=num1 + num2 
               return  sum
             }else{
               if(state=="bust")  return "you are done!"
                if(state=='normal'&& (sum=array[index++]+sum) <=21 ){
                  return sum
                }else if(sum>21){
                 return  state="bust"
    
                } 
    
             }
    
           }
        } 
      }
    
      // /*** Uncomment these to check your work! ***/
    
      // /*** DEALER ***/
      const deal = blackjack([2, 6, 1, 7, 11, 4, 6, 3, 9, 8, 9, 3, 10, 4, 5, 3, 7, 4, 9, 6, 10, 11]);
    
      // /*** PLAYER 1 ***/
      const i_like_to_live_dangerously = deal(4, 5);
      console.log(i_like_to_live_dangerously()); // => should log 9
      console.log(i_like_to_live_dangerously()); // => should log 11
      console.log(i_like_to_live_dangerously()); // => should log 17
      console.log(i_like_to_live_dangerously()); // => should log 18
      console.log(i_like_to_live_dangerously()); // => should log 'bust'
      console.log(i_like_to_live_dangerously()); // => should log 'you are done!'
      console.log(i_like_to_live_dangerously()); // => should log 'you are done!'
    
      // /*** BELOW LINES ARE FOR THE BONUS ***/
    
      // /*** PLAYER 2 ***/
      const i_TOO_like_to_live_dangerously = deal(2, 2);
      console.log(i_TOO_like_to_live_dangerously()); // => should log 4
      console.log(i_TOO_like_to_live_dangerously()); // => should log 15
      console.log(i_TOO_like_to_live_dangerously()); // => should log 19
      console.log(i_TOO_like_to_live_dangerously()); // => should log 'bust'
      console.log(i_TOO_like_to_live_dangerously()); // => should log 'you are done!
      console.log(i_TOO_like_to_live_dangerously()); // => should log 'you are done!
    
      // /*** PLAYER 3 ***/
      const i_ALSO_like_to_live_dangerously = deal(3, 7);
      console.log(i_ALSO_like_to_live_dangerously()); // => should log 10
      console.log(i_ALSO_like_to_live_dangerously()); // => should log 13
      console.log(i_ALSO_like_to_live_dangerously()); // => should log 'bust'
      console.log(i_ALSO_like_to_live_dangerously()); // => should log 'you are done!
      console.log(i_ALSO_like_to_live_dangerously()); // => should log 'you are done!
    

    我是根据要求机翻之后再作答的,后面倒数两题机翻后还是有点看不太懂,但是满足模板x需要的输出,哥哥们要是有意见可以提,也可以踊跃参与,分享不同的解答方法

    附上练习网站的链接地址

    CS Bin

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2022-7-13 22:32:07 | 显示全部楼层
    练习要求发的格式好像有些问题,建议哥哥还是直接上网站练习,如果真心不会不妨看看我的参考下思路(本人菜鸡,不喜勿喷)

    下面分享有关这个的教程,英文视频有字幕
    https://www.aliyundrive.com/s/HrgXSN3ycDE
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-13 10:14
  • 签到天数: 211 天

    [LV.7]常住居民III

    294

    主题

    3906

    回帖

    3826

    积分

    管理员

    积分
    3826

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2022-7-13 23:03:49 | 显示全部楼层
    修改了

    ```js

    这样开头就好
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-7-14 01:56:04 | 显示全部楼层
    感觉哥哥可以拆成小篇章每天练一点~
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2022-7-14 09:40:04 | 显示全部楼层

    我发出去应该改不了,下次试试,问下哥哥markdown是本身就支持这种带语言的代码块吗
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2022-7-14 09:41:07 | 显示全部楼层
    李恒道 发表于 2022-7-14 01:56
    感觉哥哥可以拆成小篇章每天练一点~

    好的,后面如果还有别的部分,我可以拆出一小块拿出来分享
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-13 10:14
  • 签到天数: 211 天

    [LV.7]常住居民III

    294

    主题

    3906

    回帖

    3826

    积分

    管理员

    积分
    3826

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2022-7-14 09:41:44 | 显示全部楼层
    rubinTime 发表于 2022-7-14 09:40
    我发出去应该改不了,下次试试,问下哥哥markdown是本身就支持这种带语言的代码块吗 ...

    是的 这是markdown的语法
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 23:59
  • 签到天数: 634 天

    [LV.9]以坛为家II

    30

    主题

    535

    回帖

    1408

    积分

    荣誉开发者

    积分
    1408

    荣誉开发者新人进步奖油中2周年生态建设者新人报道挑战者 lv2油中3周年喜迎中秋

    发表于 2022-7-15 10:21:35 | 显示全部楼层
    李恒道 发表于 2022-7-14 01:56
    感觉哥哥可以拆成小篇章每天练一点~

    话说哥哥油猴脚本开发指南里一篇关于闭包的都没
    是不是油猴对闭包就束手无策了?
    如果是这样的话,那各大网站尤其是那种网课网站为什么反脚本为什么不把代码都放进闭包里面去呢?
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-7-15 20:36:10 | 显示全部楼层
    steven026 发表于 2022-7-15 10:21
    话说哥哥油猴脚本开发指南里一篇关于闭包的都没
    是不是油猴对闭包就束手无策了?
    如果是这样的话,那各 ...

    后期会聊的
    主要就是通过基础函数劫持来拿一些闭包的东西

    一般来说webpack4可以通过初始化调用的时候进行call劫持拿到webpack__require秒杀打包的闭包问题
    5暂时没找到特别好的办法
    针对框架的解决方案基本可以秒杀大部分网站和网课脚本了
    比如对jq的劫持,对vue2的劫持,对react的劫持
    如果你要反脚本
    基本要做到强混淆+不使用框架/魔改框架+针对打包工具做一定的修改
    能达成这些的成本实在太高了
    包括对后期的维护以及整体开发人员的平均水平以及心智负担都是一个极大的挑战

    点评

    期待哥哥的教程  发表于 2022-7-15 22:50
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    862

    回帖

    1361

    积分

    荣誉开发者

    积分
    1361

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-7-15 21:13:13 | 显示全部楼层
    steven026 发表于 2022-7-15 10:21
    话说哥哥油猴脚本开发指南里一篇关于闭包的都没
    是不是油猴对闭包就束手无策了?
    如果是这样的话,那各 ...

    给你举个简单的例子:
    1. (function() {
    2.     function getType(item) {
    3.         const str = Object.prototype.toString.call(item);
    4.         return str.slice(8, -1).toLowerCase();
    5.     }
    6.     const obj = {
    7.         password: '1234'
    8.     };
    9.     if (getType(obj) === 'object') {
    10.         //...
    11.     }
    12. })();
    复制代码

    这个getType只是个判断类型的函数,但因为他用到了call,只需对call针对性劫持就可以在外部把obj暴露出来:
    1. const funcCall = Function.prototype.call;
    2. Function.prototype.call = function() {
    3.     if ('password' in arguments[0]) {
    4.         console.log(arguments[0]);
    5.     }
    6.     return funcCall.apply(this, arguments);
    7. };
    复制代码

    不只针对call,还可以针对Object.defineproperty,你要做数据绑定就很难绕开这些基础函数,这种劫持是防不胜防的。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表