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高可用集群环境介绍

    MySQL高可用集群环境搭建 01.MySQL高可用环境方案 02.MySQL主从复制原理 03.MySQL主从复制作用 04.在Linux环境上安装MySQL 05.在MySQL集群环境上配置主从复 ...

  2. (十五)SpringBoot之使用Redis做缓存数据

    一.添加Redis依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  3. 怎样用sql语句复制表table1到表table2的同时复制主键

    原文:怎样用sql语句复制表table1到表table2的同时复制主键 在从table1表复制到table2的时候,我们会用语句: select * into table2 from table1 但 ...

  4. CentOS 系统下使用 yum 安装 Redis

    本文主要介绍在 CentOS 7 系统下使用 yum 安装 Redis 的过程. 更改 yum 源 将 Centos 的 yum 源更换为国内的阿里云源. 首先备份你的原镜像文件,保证出错后可以恢复: ...

  5. Linux查看系统及版本信息

    1.查看操作系统版本cat /proc/version 2.查看系统发行版cat /etc/issue 或cat /etc/redhat-release 3.查看系统内核信息uname -a

  6. JavaScript指定日期格式化

    formatDataToString:function (dates, formats) { var o = { "M+": dates.getMonth() + 1, //月份 ...

  7. 工作流引擎Activiti

    背景: 在计算机尚未普及时,许多工作流程采用手工传递纸张表单的方式,一级一级审批签字, 工作效率非常低下,对于数据统计以及生成报表的功能,需要经过大量的手工操作才能实现. 随着电脑的普及,这些工作的参 ...

  8. c#winform listview设置每项的间距

    代码如下: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private stat ...

  9. c# 执行调用Oracle Procedure传参及回传值

    ////定義參數               //IDataParameter[] parameters =               //             {               ...

  10. 挖矿病毒watchbog处理过程

    1 挖矿病毒watchbog处理过程 简要说明 这段时间公司的生产服务器中了病毒watchbog,cpu动不动就是100%,查看cpu使用情况,发现很大一部分都是us,而且占100%左右的都是进程wa ...