[JavaScript] toString妙用

题目:
函数add可以实现连续的加法运算
函数add语法如下:

add(num1)(num2)(num3)…; 

使用举例如下:

add(10)(10) = 20
add(10)(20)(50) = 80
add(10)(20)(50)(100) = 180

请使用js代码实现函数add

答案:

function add(n){
    var sum=n,
        fn=function(x){
            sum+=x;
            return fn;
        };
        
    fn.toString=function(){
        return sum;
    };
    
    return fn;
}

alert(add(1)(2)+add(1)(2)(3));  //9

解释:
fn是一个function,类型为Object,
+会默认调用fn的toString方法,
这个toString方法不一定返回一个字符串,
本例中返回了一个数字。

规范:
Ecmascript 2015 P36
7.1 Type Conversion
The ECMAScript language implicitly performs automatic type conversion as needed.
To clarify the semantics of certain constructs it is useful to define a set of conversion abstract operations. The conversion abstract operations are polymorphic; they can accept a value of any ECMAScript language type or of a Completion Record value. But no other specification types are used with these operations.

Ecmascript 2015 P42
7.1.12 ToString (argument)
The abstract operation ToString converts argument to a value of type String according to Table 12:

Table 12 — ToString Conversions

Completion Record:
If argument is an abrupt completion, return argument.
Otherwise return ToString(argument.[[value]]).

Undefined:
Return "undefined".

Null :
Return "null".

Boolean :
If argument is true, return "true".
If argument is false, return "false".

Number :
See 7.1.12.1.

String :
Return argument.

Symbol :
Throw a TypeError exception.

Object :
Apply the following steps:

  1. Let primValue be ToPrimitive(argument, hint String).
  2. Return ToString(primValue).

Ecmascript 2015 P36
7.1.1 ToPrimitive (input, [, PreferredType])
The abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. The abstract operation ToPrimitive converts its input argument to a non-Object type. If an object is capable of converting to more than one primitive type, it may use the optional hint PreferredType to favour that type.
Conversion occurs according to Table 9:

Table 9 — ToPrimitive Conversions
Completion Record :
If input is an abrupt completion, return input.
Otherwise return ToPrimitive(input.[[value]]) also passing the optional hint PreferredType.

Undefined :
Return input.

Null :
Return input.

Boolean :
Return input.

Number :
Return input.

String :
Return input.

Symbol :
Return input.

Object :
Perform the steps following this table.

When Type(input) is Object, the following steps are taken:

  1. If PreferredType was not passed, let hint be "default".
  2. Else if PreferredType is hint String, let hint be "string".
  3. Else PreferredType is hint Number, let hint be "number".
  4. Let exoticToPrim be GetMethod(input , @@toPrimitive).
  5. ReturnIfAbrupt(exoticToPrim).
  6. If exoticToPrim is not undefined, then
    a. Let result be Call(exoticToPrim, input , «hint»).
    b. ReturnIfAbrupt(result).
    c. If Type(result) is not Object, return result.
    d. Throw a TypeError exception.
  7. If hint is "default", let hint be "number".
  8. Return OrdinaryToPrimitive(input ,hint ).

When the abstract operation OrdinaryToPrimitive is called with arguments O and hint, the following steps are taken:

  1. Assert: Type(O) is Object
  2. Assert: Type(hint) is String and it s value is either "string" or "number".
  3. If hint is "string", then
    a. Let methodNames be «"toString", "valueOf"».
  4. Else,
    a. Let methodNames be «"valueOf", "toString"».
  5. For each name in methodNames in List order, do
    a. Let method be Get( O, name).
    b. ReturnIfAbrupt(method).
    c. If IsCallable( method) is true, then
    i. Let result be Call(method, O).
    ii. ReturnIfAbrupt(result).
    iii. If Type(result) is not Object, return result.
  6. Throw a TypeError exception.

**NOTE **
When ToPrimitive is called with no hint, then it generally behaves as if the hint were Number. However, objects may over-ride this behaviour by defining a @@toPrimitive method. Of the objects defined in this specification only Date objects (see 20.3.4.45) and Symbol objects (see 19.4.3.4) over-ride the default ToPrimitive behaviour.
Date objects treat no hint as if the hint were String.

Ecmascript 2015 P169
12.7.3 The Addition operator ( + )
NOTE
The addition operator either performs string concatenation or numeric addition.

Runtime Semantics: Evaluation 12.7.3.1
AdditiveExpression : AdditiveExpression + MultiplicativeExpression

  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be GetValue(lref ).
  3. ReturnIfAbrupt(lval ).
  4. Let rref be the result of evaluating MultiplicativeExpression.
  5. Let rval be GetValue(rref).
  6. ReturnIfAbrupt(rval).
  7. Let lprim be ToPrimitive(lval ).
  8. ReturnIfAbrupt(lprim).
  9. Let rprim be ToPrimitive( rval).
  10. ReturnIfAbrupt(rprim).
  11. If Type(lprim) is String or Type(rprim) is String, then
    a. Let lstr be ToString(lprim).
    b. ReturnIfAbrupt(lstr).
    c. Let rstr be ToString(rprim).
    d. ReturnIfAbrupt(rstr).
    e. Return the String that is the result of concatenating lstr and rstr.
  12. Let lnum be ToNumber(lprim).
  13. ReturnIfAbrupt(lnum).
  14. Let rnum be ToNumber(rprim).
  15. ReturnIfAbrupt(rnum).
  16. Return the result of applying the addition operation to lnum and rnum. See the Note below 12.7.5.

NOTE 1
No hint is provided in the calls to ToPrimitive in steps 7 and 9. All standard objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Exotic objects may handle the absence of a hint in some other manner.

NOTE 2
Step 11 differs from step 5 of the Abstract Relational Comparison algorithm (7.2.11), by using the logical-or operation instead of the logical-and operation.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa阅读 8,925评论 0 6
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,769评论 0 33
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 七 我一向对生死离别没有特别的感触,但是在小学的最后一次六一儿童节,却让我对这个地方产生了深深的眷恋,因为一个人,...
    春深君阅读 285评论 0 0
  • 这”缘”字,我是浓墨朴拙之笔:完成!有浓墨也有走笔飞白跃初。结构相互亲合呼应,天趣意成。左部”纟”用篆意...
    欣平气和阅读 764评论 0 0