1. 原始数据遇运算符

1. +运算符

1) 如果算子两侧都是字符串,返回拼接结果;

2) 如果算子两侧不全是字符串,则根据实际情况:

  • 如果需要字符串,就调用String();
true + "1"; // "true1"
  • 如果需要数字转为数字,就调用Number();
true + 1; //2
  • 如果都可以,优先转为数字。
true + true; //

2. -*/减法、乘法、除法运算符

所有的算子全部转为数字,使用Number()/+。

'4' - '5'; // -1
4-'5'; //-1
true - false; //
'4'/'5'; 0.8

3.非相等比较运算符

>,>=,<,<=

1)如果算子两侧都是字符串,按照Unicode码点依次比较大小

2)如果算子两侧不全是字符串,转为数字进行比较(Number()/+)。

true < '8'; // true
'7' < 8; // true

4.相等比较运算符(==)

1) 如果是不同原始类型的值,将字符串和布尔值都转为数字(Number()或者+)。

true == '1'; //true
'true' == true; // false Number('true')->NaN
// NaN用于任何运算符返回值都是false

2)如果其中一方是对象,先将其转为原始类型的值

如果两侧都是对象,则永远不相等。

3) null == undefined

4)null和undefined都不等于其他值

null == 0; //false
undefined == 0; //false

4) NaN 和任何值都不相等

5.严格相等运算符(===)

1)如果类型不相同,直接返回false

2)如果类型相等,值也相同,直接返回true

2. 对象遇到运算符

1.+运算符

最终结果是对象需要转化成原始数据。

1)对象首先调用valueOf()方法,如果不自定义,一般都返回自身;

2)再调用toString()方法,返回对应的字符串。

但是,Date对象不同,是先调用toString(), 后调用valueOf()

var arr = [5];
arr + 1;// "51"
var obj = {
toString() { return "hello"},
valueOf() {return 1}
};
obj + "2"; // "12" 不管另一个算子是什么类型,都是先调用valueOf()
var date = new Date();
date.toString = function(){return "hello"};
date.valueOf = function(){return 1};
date + 1; // "hello1" 不管另一个算子什么类型,都是先调用toString()

2. -*/减法、乘法、除法运算符

和直接调用Number()一样;

Date对象和其他对象一样,遵循Number()函数的调用规则;

var obj = {
valueOf(){return "8"},
toString() {return "9"}
}
obj - 8; //
var date = new Date();
date.valueOf = function(){return "8"};
date.toString = function(){return "9"};
date - 8; //

3.非相等比较运算符

规则和+运算符(Number()工具函数)一致。

1)先调用valueOf()方法,如果返回值不是原始值,再调用toString()方法

2)调用toString()后还不是原始值,返回NaN

Date对象和其他对象一样,遵循上面的规则!

var obj = {
valueOf(){return "8"},
toString() {return "9"}
}
obj > 8; // false
var date = new Date();
date.valueOf = function(){return "8"};
date.toString = function(){return "9"};
date > 8; // false

4. 相等运算符(==)

如果运算符两侧都是对象,除非地址相同,否则返回都是false;

如果比较符一侧是原始类型的值:

1)先调用valueOf(),如果返回不是原始类型的值,再调用toString();

2) 如果toString()的值返回的还不是原始类型,返回NaN

Date类型相反,先调用toString();

var obj = {
valueOf(){return "8"},
toString() {return "9"}
}
obj == 8; // true
var date = new Date();
date.valueOf = function(){return "8"};
date.toString = function(){return "9"};
date == 8; // false

应用:

若使得下面条件成立,a应该使什么值?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script type="noscript">
a什么情况下,使得下面的条件成立
if(a == 1 && a ==2 && a ==3) {
console.log(1);
}
</script>
<script>
//有两类解决方案:1)数据拦截 2)类型转换
/**
* 1)数据拦截
* a本身可以看作window,使用Object.defineProperty
*/
var i = 1;
Object.defineProperty(window, 'a', {
get() {
return i++;
}
})
/**
* 2)类型转换
* > 使用==时,如果是对象,会先转成原始类型的值
* 先调用valueOf(),如果是原始类型的值返回;
* 否则再调用toString()
*/
// 1)重写valueOf方法
var a = {
index: 1,
valueOf() {
return this.index++;
}
}
// 2)重写toString方法
var a = {
index: 1,
toString() {
return this.index++;
}
}
/*
* > 使用==时,如果是对象,会先转成原始类型的值
* 对象转原型类型本质上是调用的[Symbol.toPrimitive]方法
* 该方法被调用时,会传入一个参数,表示其转为的预期类型
* default/number/string中的一个
*/
var a = {
index: 1,
[Symbol.toPrimitive](hint) {
// 预期是number/string都可以
if(hint === 'default') {
return this.index++;
}
}
} // 运行
if(a == 1 && a ==2 && a ==3) {
console.log(1);
}
</script>
</body>
</html>

5. 严格相等运算符(===)

如果比较符两侧都是对象,除非地址相同,否则都是false;

var obj1 = {};
var obj2 = obj1;
obj1 === obj2; // true
var obj3 = {};
obj1 === obj3; //false

如果比较符一侧是原始值,直接返回false

3. String()工具函数遇对象

转化规律:

1)先调用toString(),如果返回原始类型的值,对这个值使用String()方法,结束;如果是对象,继续执行;

2)调用原对象的valueOf()方法,如果返回的是原始类型的值,对这个值使用String()方法,结束;

3)如果上面的步骤执行完成后还是不是原始值,报错!

var obj = {
valueOf(){ return 5; },
toString() { return 'hello'; }
};
String(obj); // "hello"
// 当执行完都不返回原始值时
var obj = {
valueOf: function () { return {};},
toString: function () { return {};}
};
String(obj); //Uncaught SyntaxError: Invalid or unexpected token

4. Number()工具函数遇对象

转化规律:

1)先调用valueOf()方法,如果返回原始值,对这个值使用Number()函数,结束;否则继续

2)调用原对象toString()方法,如果返回原始值,对这个值使用Number()函数,结束;

3)如果都不是原始值,报错

var obj = {
valueOf(){ return 5; },
toString() { return 'hello'; }
};
Number(obj); // 5
// 当执行完都不返回原始值时
var obj = {
valueOf: function () { return {};},
toString: function () { return {};}
};
Number(obj); //Uncaught SyntaxError: Invalid or unexpected token

5. 当遇到函数时

当遇到函数调用,就会自动调用函数的toString()方法;

所以执行a();会打印两次2

function a() {
var obj = function(){ };
obj.valueOf= function(){console.log(1); },
obj.toString = function() {console.log(2);}
return obj; //
};
a(); // 2

js数据类型自动转化规律的更多相关文章

  1. 关于JS的数据类型与转化(自动与强制)

    在我们谈到JS的数据类型转化时,一定会知道分为自动转化和强制转化两种方式吧,通俗来讲,自动就是在某种条件下,电脑浏览器自己会把其他类型的数据转化为相应的数据类型,而强制则是咋们程序员应该手动来做的了, ...

  2. 第二章 js数据类型和变量

    一.驼峰命名法 第一个单词首字母大写,如果有多个单词的话其他的单词首字母大写. eg:nickName 二.prototype现象 新的命名规范. 常用的:以下划线为首字母(变量为对象的私有成员变量) ...

  3. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  4. js数据类型详解

    一.js数据类型分类 (1)原始数据类型(值类型) null 空类型,变量声明了并赋值为null.转化为数字是0 undefined 未定义,变量声明了但未赋值.转化为数字为NaN boolean 布 ...

  5. 【转】第6篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:自动注册JS脚本+自动反射方法分析

    作者: 牛A与牛C之间 时间: 2013-11-21 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第6篇:Xilium CefGlue 关于 CLR Object 与 JS ...

  6. 1. js数据类型_对象_函数_内存

    1. js数据类型有哪些? 基本(值)类型 Number ---- 任意数值 String ---- 任意字符串 Boolean ---- true/false undefined ---- unde ...

  7. JS 强制类型转化

    在Js中, 强制类型转化分为两种情况: 一种是引用类型转化基本类型, 如数组转化成数字:一种是两种不同基本类型之间的转化,如字符串转化为数字.你不能将基本类型转化成引用类型,比如,不可能把数字转化为数 ...

  8. js数据类型简单介绍

    JS数据类型 ECMAScript中有5种简单的数据类型:Undefined,Null,Boolean,Number,String.还有一种复杂的数据类型--Object(本质上是由一组无序的名值对组 ...

  9. 前端(十一)—— JavaScript基础:JS存在的位置、JS变量定义、调试方式、JS数据类型、运算符

    JS存在的位置.JS变量定义.调试方式.JS数据类型.运算符 一.JS语言介绍 1.概念 浏览器脚本语言 可以编写运行在浏览器上的代码程序 属于解释性.弱语言类型编程语言 2.组成 ES语法:ECMA ...

随机推荐

  1. ARTS 第八周打卡

    Algorithm : 做一个 leetcode 的算法题 13. 罗马数字转整数 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符          数值 I         ...

  2. Dining(POJ-3281)【最大流】

    题目链接:https://vjudge.net/problem/POJ-3281 题意:厨师做了F种菜各一份,D种饮料各一份,另有N头奶牛,每只奶牛只吃特定的菜和饮料,问该厨师最多能满足多少头奶牛? ...

  3. Python 中集合使用

    集合在使用中由于自动虑重,而且效率特高,故在提取数据时用上,但是由于集合没有切片功能没有取第几个元素的功能,但是一直使用集合切片不报错,但是执行不下去,导致一直存在问题. 修改为list后正常 例如: ...

  4. 删除列表的三个方式(python)

    del是个语句而不是方法 del member[1]:通过下标进行删除 del member:也可删除整个列表 remove():根据列表元素本身来删除,而不是通过下标 member.remove(' ...

  5. 【判环】Perpetuum Mobile

    Perpetuum Mobile 题目描述 The year is 1902. Albert Einstein is working in the patent office in Bern. Many ...

  6. 南宁AI项目

    1.能了解并对项目整体进度情况有清晰的认识,什么时间点需要完成什么工作项. 2.认识了解项目干系人,能和客户独立沟通交流,理解现场业务,不要一问三不知,什么情况都不了. 3.能推动项目进展和问题及时处 ...

  7. opengl 笔记

    1. 本函数可以禁用多边形正面或背面上的光照.阴影和颜色计算及操作,消除不必要的渲染计算是因为无论对象如何进行旋转或变换,都不会看到多边形的背面.用GL_CULL_FACE参数调用glEnable和g ...

  8. Python 遍历文件夹清理磁盘案例

    import os suffix_name_list = [".pdb", ".ilk"] def find_file(path): # 遍历文件夹 for i ...

  9. 7.生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)

    /* * 生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信) * */ public class TestProductorAndConsumerForLoc ...

  10. Qemu: User mode emulation and Full system emulation

    转载: https://wiki.edubuntu.org/UbuntuDevelopment/Ports QEMU QEMU is a processor emulator and supports ...