Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 50 题:实现 (5).add(3).minus(2) 功能 #88

Open
LiuMengzhou opened this issue Apr 8, 2019 · 33 comments
Open

第 50 题:实现 (5).add(3).minus(2) 功能 #88

LiuMengzhou opened this issue Apr 8, 2019 · 33 comments

Comments

@LiuMengzhou
Copy link

Number.prototype.add = function(n) {
  return this.valueOf() + n;
};
Number.prototype.minus = function(n) {
  return this.valueOf() - n;
};

image

@zeroone001
Copy link

zeroone001 commented Apr 8, 2019

Number.prototype.add = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this + number;
};
Number.prototype.minus = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this - number;
};
console.log((5).add(3).minus(2));

扩展

Object.prototype.add
Object.prototype.minus 

也是可以的

@yeyi361936738
Copy link

yeyi361936738 commented Apr 9, 2019

Number.prototype.add =  function(n){
  return this + n
}
Number.prototype.minus =  function(n){
  return this - n
}
console.log((5).add(3).minus(2))//6

@jjeejj
Copy link
Contributor

jjeejj commented Apr 9, 2019

Number.prototype.add = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this + number;
};
Number.prototype.minus = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this - number;
};
console.log((5).add(3).minus(2));

扩展

Object.prototype.add
Object.prototype.minus 

也是可以的

这个方法,可以扩展到数字字符串类型和排除 NaN

Number.prototype.add = function (value) {
    let  number = parseFloat(value);
    if (typeof number !== 'number' || Number.isNaN(number)) {
        throw new Error('请输入数字或者数字字符串~');
    };
    return this + number;
};
Number.prototype.minus = function (value) {
    let  number = parseFloat(value);
    if (typeof number !== 'number' || Number.isNaN(number)) {
        throw new Error('请输入数字或者数字字符串~');
    }
    return this - number;
};
console.log((5).add(3).minus(2));

对于在 Object 上添加原型方法是不建议的,因为这个影响太大,会影响所有以Object 构造的对象

@noctiomg
Copy link

noctiomg commented Apr 9, 2019

首先看到题干第一反应和楼上几位一样,链式操作+给Number/Object对象添加方法。

Number.prototype.add = function(i=0){
	return this.valueOf()+i
}
Number.prototype.minus = function(i=0){
	return this.valueOf()-i
}

不知道是否是考虑的不周全,就仔细想想,感觉会有一些好玩的知识点在里面,就做了一些小实验。
在 Chrome 的 DevTools 里,我们可以做这个实验:
image
这里问题就来了——JS的经典的浮点数陷阱。
在简单地搜索之后,我在 GitHub 上搜到了一位阿里大佬的解法,然后参考了一下他的解法和楼上大佬们的解法,对我上面的答案进行了如下修正:

Number.MAX_SAFE_DIGITS = Number.MAX_SAFE_INTEGER.toString().length-2
Number.prototype.digits = function(){
	let result = (this.valueOf().toString().split('.')[1] || '').length
	return result > Number.MAX_SAFE_DIGITS ? Number.MAX_SAFE_DIGITS : result
}
Number.prototype.add = function(i=0){
	if (typeof i !== 'number') {
        	throw new Error('请输入正确的数字');
    	}
	const v = this.valueOf();
	const thisDigits = this.digits();
	const iDigits = i.digits();
	const baseNum = Math.pow(10, Math.max(thisDigits, iDigits));
	const result = (v * baseNum + i * baseNum) / baseNum;
	if(result>0){ return result > Number.MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : result }
	else{ return result < Number.MIN_SAFE_INTEGER ? Number.MIN_SAFE_INTEGER : result }
}
Number.prototype.minus = function(i=0){
	if (typeof i !== 'number') {
        	throw new Error('请输入正确的数字');
    	}
	const v = this.valueOf();
	const thisDigits = this.digits();
	const iDigits = i.digits();
	const baseNum = Math.pow(10, Math.max(thisDigits, iDigits));
	const result = (v * baseNum - i * baseNum) / baseNum;
	if(result>0){ return result > Number.MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : result }
	else{ return result < Number.MIN_SAFE_INTEGER ? Number.MIN_SAFE_INTEGER : result }
}

【大数加减:直接通过 Number 原生的安全极值来进行判断,超出则直接取安全极值】
【超级多位数的小数加减:取JS安全极值位数-2作为最高兼容小数位数】
image

这样就能相对比较完善地解决这个问题了~希望大家多多补充

@hqzh
Copy link

hqzh commented Apr 9, 2019

Number.prototype.add = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this + number;
};
Number.prototype.minus = function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this - number;
};
console.log((5).add(3).minus(2));

扩展

Object.prototype.add
Object.prototype.minus 

也是可以的

这个方法,可以扩展到数字字符串类型和排除 NaN

Number.prototype.add = function (value) {
    let  number = parseFloat(value);
    if (typeof number !== 'number' || Number.isNaN(number)) {
        throw new Error('请输入数字或者数字字符串~');
    };
    return this + number;
};
Number.prototype.minus = function (value) {
    let  number = parseFloat(value);
    if (typeof number !== 'number' || Number.isNaN(number)) {
        throw new Error('请输入数字或者数字字符串~');
    }
    return this - number;
};
console.log((5).add(3).minus(2));

对于在 Object 上添加原型方法是不建议的,因为这个影响太大,会影响所有以Object 构造的对象

function MyNumber(){
MyNumber.prototype= new Number().__proto__
MyNumber.prototype.add =  function (number) {
    if (typeof number !== 'number') {
        throw new Error('请输入数字~');
    }
    return this + number;
};
}

@pengcc
Copy link

pengcc commented Apr 9, 2019

// 辅助函数当然也可以写到方法里去,但是要重复写
// get decimal places
const getDeimalPlaces = (num) => {
	const _num = parseFloat(num);
	if (Number.isNaN(_num)) {
		throw('This is not a Number!');
	}
	const _strArr = _num.toString().split('.');
	
	return _strArr.length > 1 ? _strArr[1].length : 0;
}

const getMaxDecimalPlaces = (x, y) => Math.max(getDeimalPlaces(x), getDeimalPlaces(y));

const calculateFloatSafely = (num, decimalPlaces) => parseFloat(num.toFixed(decimalPlaces));

Number.prototype.add = function (num) {
	const DECIMAL_PLACES = getMaxDecimalPlaces(this, num);
	return calculateFloatSafely((this + num), DECIMAL_PLACES);
}

Number.prototype.minus = function (num) {
	const DECIMAL_PLACES = getMaxDecimalPlaces(this, num);
	return calculateFloatSafely((this - num), DECIMAL_PLACES);
}

// usage
console.log((5).add(3).minus(2)); // 6
console.log((5.08).add(3.12).minus(2.1)); // 6.1
console.log((10.021).add(3.58).minus(2.102));// 11.499

@FanShiDe
Copy link

Number.prototype.add = function(num) {
	return this + num;
};
Number.prototype.minus = function(num) {
	return this - num;
}

@bran-nie
Copy link

bran-nie commented Apr 10, 2019

let myFun = {
    add(number) {
        if (typeof number !== 'number') {
            throw new Error('请输入数字')
    	}
    	return this + number
    },
    minus(number) {
        if (typeof number !== 'number') {
            throw new Error('请输入数字')
    	}
    	return this - number
    }
}

// 挂载到原型上
Object.assign(Number.prototype, myFun)

;(5).add(3).minus(2)
// 6

让一让,我分享一个比较简便、便于维护的方法。🙈
将需要增加到Number原型上的方法,集中到一个对象里面,再用assign进行合并。

不过望大佬指出不同意见,本人小白一个

@Hillkinsh
Copy link

Function.prototype.method = function (name, fn) {
this.prototype[name] = fn;
return this
}
Number.method('add', function (a) {
return this + a
})
Number.method('minus', function (a) {
return this - a
})

@IAMSBLOL
Copy link

Number.prototype.add=function(x){ return this+x}
Number.prototype.minus=function(x){return this-x}

@mongonice
Copy link

mongonice commented Jul 24, 2019

Number.prototype.add = function (num) {
    return this + num
}
Number.prototype.minus = function (num) {
    return this - num
}

console.log((5).add(3).minus(2))   // 6

@safarishi
Copy link

Number.prototype.add = function(n) {
  return this.valueOf() + n;
};
Number.prototype.minus = function(n) {
  return this.valueOf() - n;
};

image

how to realize in typescript ?

@zzNire
Copy link

zzNire commented Aug 9, 2019

我的一个疑惑

为什么 8.add(1) 不行,而 8['add'](1)以及(8).add(1)可以

上面代码中,调用方法之所以写成8['add'],而不是8.add,是因为数值后面的点,会被解释为小数点,而不是点运算符。

将数值放在圆括号中,数字就会自动转化为基本包装类型,就可以使用点运算符调用方法了。

参考

@webbobola
Copy link

webbobola commented Aug 30, 2019

	class MyNumber extends Number {
			constructor(e) {
				super(e);
			}
			add(n=0) {
				if(typeof n !== "number") {
					throw new Error("Please enter the correct data type")
				}
				return new MyNumber(this+n);
			}
			minus(n=0) {
				if(typeof n !== "number") {
					throw new Error("Please enter the correct data type")
				}
				return new MyNumber(this-n);
			}
		}
                  var a=new MyNumber (10);
		console.log(a.minus(-1).add(2))

@aeolusheath
Copy link

 Number.prototype.add = function(num) {
   return this + num
 }
 Number.prototype.minus = function(num) {
   return this - num
 }

5.add(3)报错,因为js引擎将5.识别为一个数字,一个数字+add(3)报错。
5add(3)是报同样的错。

@ScholatLouis
Copy link

```js
 Number.prototype.add = function(num) {
   return this + num
 }
 Number.prototype.minus = function(num) {
   return this - num
 }

5.add(3)报错,因为js引擎将5.识别为一个数字,一个数字+add(3)报错。
5add(3)是报同样的错。

5..add(3)就可以了

@huatten
Copy link

huatten commented Nov 21, 2019

~function () {
  function verify(n) {
    n = Number(n)
    return isNaN(n) ? 0 : n;
  }
  function add(n) {
    n = verify(n)
    return this + n;
  }
  function minus(n) {
    n = verify(n)
    return this - n;
  }
  ["add", "minus"].forEach(item => {
    Number.prototype[item] = eval(item)
  })
}()

(5).add(2).minus(3)    // 4

@yygmind
Copy link
Contributor

yygmind commented Dec 16, 2019

例: 5 + 3 - 2,结果为 6

@blade254353074
Copy link

Number.prototype.add = function(i = 0){
	return parseFloat((this + i).toPrecision(12))
}
Number.prototype.minus = function(i = 0){
	return parseFloat((this - i).toPrecision(12))
}

2.1.minus(1.9) // 0.2

@arixse
Copy link

arixse commented May 4, 2020

思路:将addminus方法挂在到Number的原型上面,并且在每个函数中返回Number类型的结果

Number.prototype.add = function(num) {
      return Number(this + num)
}
Number.prototype.minus = function(num) {
      return Number(this - num)
} 

@fariellany
Copy link

let myFun = {
    add(number) {
        if (typeof number !== 'number') {
            throw new Error('请输入数字')
    	}
    	return this + number
    },
    minus(number) {
        if (typeof number !== 'number') {
            throw new Error('请输入数字')
    	}
    	return this - number
    }
}

// 挂载到原型上
Object.assign(Number.prototype, myFun)

;(5).add(3).minus(2)
// 6

让一让,我分享一个比较简便、便于维护的方法。🙈
将需要增加到Number原型上的方法,集中到一个对象里面,再用assign进行合并。

不过望大佬指出不同意见,本人小白一个

牛皮

@long-joan
Copy link

Number.prototype.add = function(n){return this.toString()*1 + n}
Number.prototype.minus = function(n){return this.toString()*1 - n}
console.log((5).add(3).minus(2))

@SnailOwO
Copy link

Number.prototype.add = function(n){return this.toString()*1 + n}
Number.prototype.minus = function(n){return this.toString()*1 - n}
console.log((5).add(3).minus(2))

你这和调用valueOf有啥区别...

@SnailOwO
Copy link

想问下,(5)为啥就变成Number Object了,真的有点好奇js那是怎么处理的

@SnailOwO
Copy link

想问下,(5)为啥就变成Number Object了,真的有点好奇js那是怎么处理的
明白了...(5) === Number(5)

@libin1991
Copy link

image

@blank1u
Copy link

blank1u commented Nov 29, 2020

Number.prototype.add = function (val) {
    return this + val
}

Number.prototype.minus = function (val) {
    return this - val
}

@jiangmingwen
Copy link

jiangmingwen commented Feb 2, 2021


class Num  {
    num = 0
    constructor(num){
        this.num = num
    }

    add(count){
        this.num += count
        return this
    }

    minus(count){
        this.num -= count 
        return this
    }

}
console.log(new Num(5).add(3).minus(2).num )

@lianglei777
Copy link

为什么我将function改成箭头函数,就不对了??

企业微信截图_cc297912-663b-46fd-91bd-8003bf59c722

@zizifn
Copy link

zizifn commented Dec 29, 2021


class Num  {
    num = 0
    constructor(num){
        this.num = num
    }

    add(count){
        this.num += count
        return this
    }

    minus(count){
        this.num -= count 
        return this
    }

}
console.log(new Num(5).add(3).minus(2).num )

看到其他答案,都改number 原型链,就不怕该出bug啊。这可是动了基本类型啊。。

@Dylan0916
Copy link

Dylan0916 commented Apr 5, 2022

为什么我将function改成箭头函数,就不对了??

企业微信截图_cc297912-663b-46fd-91bd-8003bf59c722

因你例子的 arrow function 的 this 会指向 window,所以 add 是回传 window.valueOf() - n,为 NaN,自然在 call minus 时会炸掉

@XW666
Copy link

XW666 commented Aug 18, 2022

 class MyNumber {
    constructor(num) {
      this.num = num
    }
    add(count) {
      let m = count + this.num
      return new MyNumber(m)
    }
    minus(count) {
      let m = this.num - count
      return new MyNumber(m)
    }
  }
  let m = new MyNumber(2)
  console.log('MyNumber', m.add(3).minus(1))

@ScholatLouis
Copy link

ScholatLouis commented Aug 18, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests