Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Rules of JavaScript operators and conversion of implicit types

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "JavaScript operator rules and implicit type conversion". In the operation process of actual cases, many people will encounter such difficulties. Next, let Xiaobian lead you to learn how to deal with these situations! I hope you can read carefully and learn something!

implicit type conversion

In JavaScript, when we perform comparison operations or addition, subtraction, multiplication and division operations, JavaScript's implicit type conversion mechanism is often triggered; this part is also often confusing. For example, the console.log operation in browsers often converts any value to a string and displays it, while mathematical operations convert values to numeric types first (except for Date objects) and then operate on.

Let's first look at a few typical sets of operator results in JavaScript, hoping that after reading this section, we can reasonably explain each entry:

//Compare [] == ! [] // true NaN !== NaN // true 1 == true // true 2 == true // false "2" == true // flase null > 0 // false null

< 0 // false null == 0 // false null >

= 0 // true //addition true + 1 // 1 undefined + 1 // NaN let obj = {};{} + 1 // 1, where {} is treated as code block { 1 + 1 } + 1 // 1 obj + 1 // [object Object]1 {} + {} // Chrome displays "[object Object][object Object]", Firefox displays NaN [] + {} // [object Object] [] + a // [object Object] + [] //equivalent to + " => 0 {} + [] // 0 a + [] // [object Object] [2,3] + [1,2] // '2,31, 2' [2] + 1 // ' 2 - 1 ' [2] + (-1) // "2-1" //Subtraction or other operations, string concatenation is not possible, so NaN [2] - 1 // 1 [2,3] - 1 // NaN {} - 1 // -1 is returned in the wrong string format

conversion between primitive types

JavaScript primitive types include numeric types, string types, Boolean types, and null types; and the conversion functions between primitive types we commonly use are String, Number, and Boolean:

// String let value = true; console.log(typeof value); // boolean value = String(value); // now value is a string "true" console.log(typeof value); // string // Number let str = "123"; console.log(typeof str); // string let num = Number(str); // becomes a number 123 console.log(typeof num); // number let age = Number("an arbitrary string instead of a number"); console.log(age); // NaN, conversion failed // Boolean console.log( Boolean(1) ); // true console.log( Boolean(0) ); // false console.log( Boolean("hello") ); // true console.log( Boolean("") ); // false

Finally, we can get the following JavaScript primitive type conversion table (including examples of compound type to primitive type conversion):

在比较运算与加法运算中,都会涉及到将运算符两侧的操作对象转化为原始对象的步骤;而 JavaScript 中这种转化实际上都是由 ToPrimitive 函数执行的。实际上,当某个对象出现在了需要原始类型才能进行操作的上下文时,JavaScript 会自动调用 ToPrimitive 函数将对象转化为原始类型;譬如上文介绍的 alert 函数、数学运算符、作为对象的键都是典型场景,该函数的签名如下:

ToPrimitive(input, PreferredType?)

为了更好地理解其工作原理,我们可以用 JavaScript 进行简单地实现:

var ToPrimitive = function(obj,preferredType){ var APIs = { typeOf: function(obj){ return Object.prototype.toString.call(obj).slice(8,-1); }, isPrimitive: function(obj){ var _this = this, types = ['Null','Undefined','String','Boolean','Number']; return types.indexOf(_this.typeOf(obj)) !== -1; } }; // 如果 obj 本身已经是原始对象,则直接返回 if(APIs.isPrimitive(obj)) {return obj;} // 对于 Date 类型,会优先使用其 toString 方法;否则优先使用 valueOf 方法 preferredType = (preferredType === 'String' || APIs.typeOf(obj) === 'Date' ) ? 'String' : 'Number'; if(preferredType==='Number'){ if(APIs.isPrimitive(obj.valueOf())) { return obj.valueOf()}; if(APIs.isPrimitive(obj.toString())) { return obj.toString()}; }else{ if(APIs.isPrimitive(obj.toString())) { return obj.toString()}; if(APIs.isPrimitive(obj.valueOf())) { return obj.valueOf()}; } throw new TypeError('TypeError'); }

我们可以简单覆写某个对象的 valueOf 方法,即可以发现其运算结果发生了变化:

let obj = { valueOf:() => { return 0; } } obj + 1 // 1

如果我们强制将某个对象的 valueOf 与 toString 方法都覆写为返回值为对象的方法,则会直接抛出异常。

obj = { valueOf: function () { console.log("valueOf"); return {}; // not a primitive }, toString: function () { console.log("toString"); return {}; // not a primitive } } obj + 1 // error Uncaught TypeError: Cannot convert object to primitive value at :1:5

值得一提的是对于数值类型的 valueOf() 函数的调用结果仍为数组,因此数组类型的隐式类型转换结果是字符串。而在 ES6 中引入 Symbol 类型之后,JavaScript 会优先调用对象的 [Symbol.toPrimitive] 方法来将该对象转化为原始类型,那么方法的调用顺序就变为了:

当 obj[Symbol.toPrimitive](preferredType) 方法存在时,优先调用该方法;

如果 preferredType 参数为 String,则依次尝试 obj.toString() 与 obj.valueOf() ;

如果 preferredType 参数为 Number 或者默认值,则依次尝试 obj.valueOf() 与 obj.toString() 。

而 [Symbol.toPrimitive] 方法的签名为:

obj[Symbol.toPrimitive] = function(hint) { // return a primitive value // hint = one of "string", "number", "default" }

我们同样可以通过覆写该方法来修改对象的运算表现:

user = { name: "John", money: 1000, [Symbol.toPrimitive](hint) { console.log(`hint: ${hint}`); return hint == "string" ? `{name: "${this.name}"}` : this.money; } }; // conversions demo: console.log(user); // hint: string -> {name: "John"} console.log(+user); // hint: number -> 1000 console.log(user + 500); // hint: default -> 1500

比较运算

JavaScript 为我们提供了严格比较与类型转换比较两种模式,严格比较(===)只会在操作符两侧的操作对象类型一致,并且内容一致时才会返回为 true,否则返回 false。而更为广泛使用的 == 操作符则会首先将操作对象转化为相同类型,再进行比较。对于 = 0 为 true 的这种比较结果,在 ECMAScript 中还规定,如果

< 为 false,则 >

= is true.

addition operation

For addition operations, JavaScript first converts the objects on either side of the operator to Primitive types; then JavaScript performs implicit type conversions before performing the operation, provided that appropriate implicit type conversions yield meaningful values. For example, the expression value1 + value2 first calls the ToPrimitive function to convert the two operands to their original types:

prim1 := ToPrimitive(value1) prim2 := ToPrimitive(value2)

ValueOf methods on objects other than Date will be called preferentially, and because valueOf methods on arrays still return values of array type, their string representations will be returned. If any of the prim1 and prim2 after conversion is a string, string concatenation will be given priority; otherwise, addition will be performed.

"JavaScript operator rules and implicit type conversion" content introduced here, thank you for reading. If you want to know more about industry-related knowledge, you can pay attention to the website. Xiaobian will output more high-quality practical articles for everyone!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report