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. PAT(B)1003 我要通过!(Java)

    1003 我要通过! 题目   判断字符串是否符合给定的规则.更多内容点击标题. 参考博客 ValarMorghulis的博客 分析   规律:num_a * num_b = num_c.字符串a中字 ...

  2. spring 框架的核心总结

    最近在学习Java语言,从而也学习了SpringFramework 这个大名鼎鼎的框架.从而做一些的记录. 题外话: 学习过几种不同的语言,后来知道所有的编程语言里所有的概念翻来覆去都是一样的事物,只 ...

  3. Hibernate的入门Curd用法

    今天分享的是hibernate关系映射框架的入门用法 一:Hibernate简介 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建 ...

  4. linux运维工程师常用命令

    1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a  列出包括.a开头的隐藏文件的所有文件-A  通-a,但不列出"."和".."-l  列 ...

  5. java中针对 try和finally一些总结

    结论 1.不管有没有异常,finally中的代码都会执行 2.当try.catch中有return时,finally中的代码依然会继续执行 3.finally是在return后面的表达式运算之后执行的 ...

  6. ELK 日志收集系统

    传统系统日志收集的问题 在传统项目中,如果在生产环境中,有多台不同的服务器集群,如果生产环境需要通过日志定位项目的Bug的话,需要在每台节点上使用传统的命令方式查询,这样效率非常底下. 通常,日志被分 ...

  7. Neo4j基本使用及导入三元组

    下载和安装Neo4j 安装Java JDK 下载Neo4j安装文件 创建系统环境变量 Neo4j配置 配置文档存储在conf目录下,Neo4j通过配置文件neo4j.conf控制服务器的工作.默认情况 ...

  8. office2016激活码 最新各个版本 激活

    office2016专业版激活密钥 Microsoft Office 2016 Pro Plus Retail 零售版序列号密钥: BHXN7-MQB36-MTHQ4-8MHKV-CYT97 Micr ...

  9. Https请求被中止: 未能创建 SSL/TLS 安全通道

    可以参考https://www.cnblogs.com/ccsharp/p/3270344.html 和https://blog.csdn.net/baidu_27474941/article/det ...

  10. layui下拉多选formSelects使用方法

    下载formSelects-v4插件(引入formSelects-v4.css和formSelects-v4.js) 下载地址:https://fly.layui.com/extend/formSel ...