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. MySQL创建用户、为用户授权

    一.创建用户 1.root用户(管理员)登录,进入mysql数据库 mysql> use mysql Database changed 2.创建用户 1.创建用户: # 指定ip:192.168 ...

  2. MySQL 解决source 命令导入数据库 乱码

    在我把库.表.sql脚本的编码格式都设置为UTF-8后,任然有乱码,任然有报错: 于是按以下方式重新登录后,解决: mysql -u root -p --default-character-set=u ...

  3. mysql中的锁机制之概念篇

    锁的概念 ①.锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具. ②.在计算机中,是协调多个进程或线程并发访问某一资源的一种机制. ③.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等 ...

  4. C# 重载,重写,代理,枚举实例

    1.日期说法时区不同所取到的值也不同, 多个国的服务器要注意这个玩意 DateTime newDate = DateTime.Now; Console.WriteLine(newDate.ToStri ...

  5. (十三)SpringBoot之Spring-Data-Jpa(二)CRUD实现以及添加自定义方法

    一.jpa中添加自定义方法 http://blog.csdn.net/qq_23660243/article/details/43194465 二.案例 1.3 引入jpa依赖 <depende ...

  6. 体验三大JavaScript文件上传库(Uppy.js/Filepond/Dropzone)

    最近发现了一个高颜值的前端上传组件Uppy.js,立即上手体验了一波,感觉还不错.然后又看到同类型的Filepond以及Dropzone.js,对比体验了一下,感觉都很优秀,但是在体验过程中,都遇到了 ...

  7. SQLAlchemy 在查询期间丢失与MySQL服务器的连接

    遇到问题 pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query') 建立的 pymysq ...

  8. 使用帅气的cordic算法进行坐标系互转及log10的求解

    参考博客 https://blog.csdn.net/u010712012/article/details/77755567 https://blog.csdn.net/Reborn_Lee/arti ...

  9. golang包管理工具

    软件开发中,不可避免的会使用到第三方库,因此包管理工具可以极大的方便开发者管理第三方依赖,避免掉入"依赖地狱". 作为google强大背书的golang语言,golang官方包管理 ...

  10. UITableView个人使用总结【前篇-增量加载】

    UITableView现在边整边总结. 预计分两个部分,第一个部分主要是对UITableView本身属性的学习.第二个部分可能会是加上一个编辑按钮以及对列表的操作. 今天先学习第一部分. 第一部分,我 ...