JavaScript】手写一个方法,实现add(1)(2)(3)结果为1+2+3=6

2020-11-25 19:07发布

4条回答
无需指教
2楼 · 2020-11-26 08:34

LinkedList的原理是链表,所以定义节点,节点要有前驱后继和内容,其add、remove、get都是基于链表的遍历

 

package com.ykq;/** * 自己实现一个LinkedList * @author RSA * */public class MyLinkedList { //保存链的第一个和最后一个,就能遍历整条链 private Node first; private Node last; //list元素个数 private int size;  //list新加节点 public void add(Object obj) {  if (first == null) {   //第一个节点为空,则链为空,则创建新节点作为头尾节点   Node n = new Node(null, obj, null);   first = n;   last = n;  } else {   //直接往last后增加节点(指定last的后继,和新节点的前驱,再将新节点指定为last)   Node n = new Node(last, obj, null);   last.setNext(n);   last = n;  }  size++; }  //在指定下标插入新节点,原理找到该节点,然后更新相关节点前驱后继关系 public void add(int i, Object obj) {  rangeCheck(i);    Node newNode = new Node(null, obj, null);    Node temp = node(i);  temp.getPrevious().setNext(newNode);  newNode.setPrevious(temp.getPrevious());  temp.setPrevious(newNode);  newNode.setNext(temp);  size++; }    //获取list的第i个元素 private Object get(int i) {  rangeCheck(i);    //这里提供2种方式找到目标节点,1使用循环,2使用递归  Node temp = node(i);  return temp.getObj();    //return get(i, first);递归 } /*private Object get(int i, Node n) {  if (i == 0) {   return n.getObj();  } else {   return get(--i, (Node) n.getNext());  } }*/  //移除指定下标的元素 public void remove(int i) {  rangeCheck(i);    Node temp = node(i);    //将被移除节点的前后节点关联起来  temp.getPrevious().setNext(temp.getNext());  temp.getNext().setPrevious(temp.getPrevious());  size--; }  //找到指定下标的节点并返回 private Node node(int i) {  Node temp = first;  if (first != null) {   for (int j = 0; j < i; j++) {    temp = temp.getNext();   }  }  return temp; }  //范围判断 private void rangeCheck(int index) {  //size是当前已存数据的长度,比某位元素下标多1。所以在比较时减1。为什么不需要判断index<0> size-1) {   try {    throw new IllegalArgumentException("下标不合法");   } catch (Exception e) {    e.printStackTrace();   }  } } //获取list长度 public int size() {  return size; }  public static void main(String[] args) {  MyLinkedList list = new MyLinkedList();  //以下三行,测试普通add  list.add("0");  list.add("1");  list.add("2");  System.out.println(list.size());  System.out.println(list.get(1));  //测试移除下标为1的元素,结果list为0、2  list.remove(1);  //测试在下标1插入3,结果为0、3、2  list.add(1,"3"); }}

 


我是大脸猫
3楼 · 2020-11-27 18:18
add(2, 3)

add(2, 3) 没什么好说,就是函数内两个参数相加。

function add(x, y) {
  return x + y}add(2, 3) // 5

但是你这样写是没有扩展性的,如果让你实现add(2, 3, 4)的话就要修改函数了。
所以,arguments了解一下。
arguments 是对应于传递给函数的参数,它是一个类数组对象。
你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数的条目,第一个条目的索引从0开始。
arguments对象不是一个 Array。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop方法。但是它可以被转换为一个真正的Array
var args = Array.prototype.slice.call(arguments)
实现:

function add () {
  var res = 0
  for (var i = 0; i < arguments.length; i++) {
    res = res + arguments[i]
  }
  return res}add(1, 2, 3) // 6
add(2)(3)

看到add(2)(3)的时候就觉得这肯定是需要返回一个函数的,返回的函数也就是add(2),于是思来想去加上各种尝试想到了一个笨办法。

function add(x) {
  let res = 0
  res = res + x  return function (y) {
    res = res + y    return res  }}add(2)(3) // 5

这个办法是把函数的参数相加作为结果返回,并没有延伸性,如果想要得到add(2)(3)(4)的值,这段代码就不能用了,代码要改成如下

function add(x) {
  let res = 0
  res = res + x  return function (y) {
    res = res + y    return function (z) {
      res = res + z      return res    }
  }}add(2)(3)(4) // 9

很明显这么写是没有尽头的,仔细观察上面的代码,我们可以发现有重复的部分,函数add不断的返回函数,然后进行参数相加。

function add(x) {
  let res = 0
  res = res + x  return function temp(y) {
    res = res + y    return temp  }}

但是console.log(add(1)(2)(3))执行后发现返回的结果是一个函数,并不是我们想要的总和。
那么怎么把结果输出呢?

第一种方法

利用我们上面学习的arguments,判断参数输入,如果没有参数输入的话,就返回总和,而不是返回函数。

function add(x) {
  let res = 0
  res = res + x  return function temp(y) {
    if (arguments.length === 0) {
      return res    } else {
      res = res + y      return temp    }
  }}

由于最后返回的是一个函数,所以调用的时候要这么调用
add(1)(2)(3)() // 6

第二种方法

第二种方法就是重写add函数的toStringvalueOf方法

function add(x) {
  let res = 0
  res = res + x  var temp =  function (y) {
    res = res + y    return temp  }
  temp.toString = temp.valueOf = function() {
    return res  }
  return temp}add(1)(2)(3) // 6



作者:Molly6943
链接:https://www.jianshu.com/p/2a556b3cd335
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


soumus
4楼 · 2020-11-29 20:10

1.想要实现add()()这样调用方式,add()方法的返回值务必是一个函数,

function add(){

      function sum(){

                return sum//需要支持多次调用,sum需要返回本身   

        }

       return sum;

}

2.如何实现累加,这个时候需要使用到toString方法,当return sum的时候会尝试调用toString方法

function add(a){

            function sum(b){

                a =   a+b;

                return sum;

            }

            sum.toString = function(){

                return a;

            }

            return sum;

        }


        console.log(add(1)(2)(3))


挺好的
5楼 · 2020-11-30 07:58
package com.ykq;/** * 自己实现一个LinkedList * @author RSA * */public class MyLinkedList { //保存链的第一个和最后一个,就能遍历整条链 private Node first; private Node last; //list元素个数 private int size;  //list新加节点 public void add(Object obj) {  if (first == null) {   //第一个节点为空,则链为空,则创建新节点作为头尾节点   Node n = new Node(null, obj, null);   first = n;   last = n;  } else {   //直接往last后增加节点(指定last的后继,和新节点的前驱,再将新节点指定为last)   Node n = new Node(last, obj, null);   last.setNext(n);   last = n;  }  size++; }  //在指定下标插入新节点,原理找到该节点,然后更新相关节点前驱后继关系 public void add(int i, Object obj) {  rangeCheck(i);    Node newNode = new Node(null, obj, null);    Node temp = node(i);  temp.getPrevious().setNext(newNode);  newNode.setPrevious(temp.getPrevious());  temp.setPrevious(newNode);  newNode.setNext(temp);  size++; }    //获取list的第i个元素 private Object get(int i) {  rangeCheck(i);    //这里提供2种方式找到目标节点,1使用循环,2使用递归  Node temp = node(i);  return temp.getObj();    //return get(i, first);递归 } /*private Object get(int i, Node n) {  if (i == 0) {   return n.getObj();  } else {   return get(--i, (Node) n.getNext());  } }*/  //移除指定下标的元素 public void remove(int i) {  rangeCheck(i);    Node temp = node(i);    //将被移除节点的前后节点关联起来  temp.getPrevious().setNext(temp.getNext());  temp.getNext().setPrevious(temp.getPrevious());  size--; }  //找到指定下标的节点并返回 private Node node(int i) {  Node temp = first;  if (first != null) {   for (int j = 0; j < i; j++) {    temp = temp.getNext();   }  }  return temp; }  //范围判断 private void rangeCheck(int index) {  //size是当前已存数据的长度,比某位元素下标多1。所以在比较时减1。为什么不需要判断index<0> size-1) {   try {    throw new IllegalArgumentException("下标不合法");   } catch (Exception e) {    e.printStackTrace();   }  } } //获取list长度 public int size() {  return size; }  public static void main(String[] args) {  MyLinkedList list = new MyLinkedList();  //以下三行,测试普通add  list.add("0");  list.add("1");  list.add("2");  System.out.println(list.size());  System.out.println(list.get(1));  //测试移除下标为1的元素,结果list为0、2  list.remove(1);  //测试在下标1插入3,结果为0、3、2  list.add(1,"3"); }}


相关问题推荐

  • 回答 8

    向一个对象数组里面添加新的属性var arry= [{a:11,b:22,c:33,d:44},{a:11,b:0,c:0,d:44},{a:11,b:22,c:99,d:99}];var arry2=[];arry.map(((item, index)=> {arry2.push(Object.assign({},item,{mess1:item.c,mess2:item.d}))}))cons...

  • 回答 2

    我觉得getTopWindow() 应该是他自己写的函数 mask  应该是getTopWindow()函数中 return 出的一个什么玩意show()  jQuery的显示

  • 回答 9

    如图所示

  • 回答 12

    1、原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链 2、 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链...

  • 回答 6

    使用VS code对JS进行Debug,需要安装一个插件,这个插件是根据你所使用的浏览器来的,不同浏览器对应插件不同,以下是插件对应情况,下载完相应的插件以后还要下载一个live server在浏览器下查看你界面运行效果,记得在到设置里修改下live server的端口号,然...

  • 回答 8
    已采纳

    没有基础,是可以学Java的,在网上也能找到很多免费的视频、学习资料等资源,只不过想要光靠自己摸索学透Java并不容易,最好是找一个比较靠谱的有实训的培训机构。不过,我给你点建议:1.脑子里要有编程思维,2.学习态度要有,3.了解了基本概念后,从图形界面...

  • 回答 7

    假设文本框的id=text1js:document.getElementById(text1).value = 测试;//即可

  • 回答 2

    这两个事件都是在js原生开发时经常会用到的,比如需要对页面dom进行动态处理,这时就需要用到DOMContentLoaded和[removed]事件,大家都知道,就是在dom构建完毕后,才可以对dom元素进行操作,否则会获取不到相应的dom元素,但是DOMContentLoaded和[removed]还...

  • 回答 11

    基本概念CookieCookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限制为4KB左右。它的主要用途有保存登录信息,比如你登录某个网站市场可以看到记住密码,这通常就是通过在 Cookie 中存入一段辨别用户身份的数据来实现的。localStoragelocalStor...

  • 回答 2

    在vscode 头疼的问题是 用浏览器查看网页!会是以文件夹的方式打开的!  我遇到这个问题 我还重新配置了Apache    ! 但是现在可以解决:使用vscode  ==================== 打开cmd   : 在cmd 控制台中输入  :   1.运行cnpm install live-server...

  • 回答 1

    在进行对象之间的合并的时候,就会使用到extend方法进行合并语法结构:$.extend(true,{},对象1,对象2...)但是这里需要考虑一个问题,如果对象间有相同的属性名,就会涉及到哪一个对象和哪一个对象的值覆盖合并的问题,如果对象中的属性值还是一个对象的话,那...

  • 回答 5
    已采纳

    先说下要实现什么功能,比如:限制图片大小不能超过30K,宽高为121x75上面需求提了,然后我直接把代码给你放出来,可以照着下面代码敲一遍试试就知道怎么限制图片宽高了 $(#picFile4).on(change,function(){ var imgFile = this.files[0]; va...

  • 回答 3

    用python爬取近30天百度指数代码均转载,如下:#1.登录url = ‘http://index.baidu.com/’driver = webdriver.Chrome(executable_path=‘C:/Program Files(x86)/Google/Chrome/Application/chromedriver.exe’)driver.get(url)cookieList = [......

  • 回答 7

    基本类型基本类型分为以下六种:string(字符串)boolean(布尔值)number(数字)symbol(符号)null(空值)undefined(未定义)注意:string 、number 、boolean 和 null  undefined 这五种类型统称为原始类型(Primitive),表示不能再细分下去的基本类...

  • 回答 11

    实体类中添加时间转换注解(注意时区问题)12345/**  * 开始时间  */ @JsonFormat(pattern = yyyy-MM-dd HH:mm:ss, timezone=GMT+8) private Date startTime;

  • 回答 5

    实例中包含加、减、乘、除四种运算,由于先乘和除的优先级别高,所以乘和除将首先被运算,接下来是加和减运算。乘和除优先级相同,所以左边的乘法将被先执行,然后是除法,接下来按从左到右的顺序进行加减运算...

没有解决我的问题,去提问