js数据类型自动转化规律
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数据类型自动转化规律的更多相关文章
- 关于JS的数据类型与转化(自动与强制)
在我们谈到JS的数据类型转化时,一定会知道分为自动转化和强制转化两种方式吧,通俗来讲,自动就是在某种条件下,电脑浏览器自己会把其他类型的数据转化为相应的数据类型,而强制则是咋们程序员应该手动来做的了, ...
- 第二章 js数据类型和变量
一.驼峰命名法 第一个单词首字母大写,如果有多个单词的话其他的单词首字母大写. eg:nickName 二.prototype现象 新的命名规范. 常用的:以下划线为首字母(变量为对象的私有成员变量) ...
- vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结
vue—你必须知道的 目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...
- js数据类型详解
一.js数据类型分类 (1)原始数据类型(值类型) null 空类型,变量声明了并赋值为null.转化为数字是0 undefined 未定义,变量声明了但未赋值.转化为数字为NaN boolean 布 ...
- 【转】第6篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:自动注册JS脚本+自动反射方法分析
作者: 牛A与牛C之间 时间: 2013-11-21 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第6篇:Xilium CefGlue 关于 CLR Object 与 JS ...
- 1. js数据类型_对象_函数_内存
1. js数据类型有哪些? 基本(值)类型 Number ---- 任意数值 String ---- 任意字符串 Boolean ---- true/false undefined ---- unde ...
- JS 强制类型转化
在Js中, 强制类型转化分为两种情况: 一种是引用类型转化基本类型, 如数组转化成数字:一种是两种不同基本类型之间的转化,如字符串转化为数字.你不能将基本类型转化成引用类型,比如,不可能把数字转化为数 ...
- js数据类型简单介绍
JS数据类型 ECMAScript中有5种简单的数据类型:Undefined,Null,Boolean,Number,String.还有一种复杂的数据类型--Object(本质上是由一组无序的名值对组 ...
- 前端(十一)—— JavaScript基础:JS存在的位置、JS变量定义、调试方式、JS数据类型、运算符
JS存在的位置.JS变量定义.调试方式.JS数据类型.运算符 一.JS语言介绍 1.概念 浏览器脚本语言 可以编写运行在浏览器上的代码程序 属于解释性.弱语言类型编程语言 2.组成 ES语法:ECMA ...
随机推荐
- wordpress 图片上传时发生了错误,请稍后再试 的解决办法
前一天网站还是好好的,仅一天过后就显示图片无法上传,百思不得其解 上下百度,大多数帖子提供的解决办法对我都不适用,继续搜,最后发现一篇帖子中提到是wp-config的编码格式问题 想到昨天刚好修改了下 ...
- opencv实现人脸识别(一)opencv的相关知识了解
这回进行了人脸识别的项目,对学习过程进行记录. 首先进行的就是一系列环境的配置,如 python3.7的安装, python的IDE pycharm的安装,然后进行opencv库的安装,可以通过py ...
- MySQL 子查询(二)
接上篇文章,从这节起:MySQL 5.7 13.2.10.5 Row Subqueries 五.行子查询(ROW Subqueries) 标量子查询返回单个值,列子查询返回一个列的多个值.而行子查询是 ...
- 十二、react-reudx之@connect 摆脱redux的繁琐操作
如果对redux的概念和用法掌握的已经不错了 那么现在react-redux会让你的操作更加的得心印手 忘记subscribe,记住reducer,action和dispatch即可 Reac ...
- 案例-使用MapReduce实现join操作
哈喽-各位小伙伴们中秋快乐,好久没更新新的文章啦,今天分享如何使用mapreduce进行join操作. 在离线计算中,我们常常不只是会对单一一个文件进行操作,进行需要进行两个或多个文件关联出更多数据, ...
- opengl 笔记
1. 本函数可以禁用多边形正面或背面上的光照.阴影和颜色计算及操作,消除不必要的渲染计算是因为无论对象如何进行旋转或变换,都不会看到多边形的背面.用GL_CULL_FACE参数调用glEnable和g ...
- VBA决策(十)
决策允许程序员控制脚本或其中一个部分的执行流程.执行由一个或多个条件语句控制.以下是在大多数编程语言中找到的典型决策结构的一般形式. VBA提供了以下类型的决策声明. 点击以下链接来查看它们的详细信息 ...
- K2 BPM_当BPM遇上RPA | 企业合规和风险管理从此更高效_全球领先的工作流引擎
强化企业合规与风险管理已成为全球企业发展的共识,尤其是对于药企.银行.地产这类对于合规性要求高的企业而言,识别预测潜在的管理风险和遵循不断升级的合规义务,是保证企业平稳运行的关键. 如何从流程层面降低 ...
- 使用 Xtrabackup 在线对MySQL做主从复制
1. 说明 1.1 xtrabackup mysqldump对于导出10G以下的数据库或几个表,还是适用的,而且更快捷.一旦数据量达到100-500G,无论是对原库的压力还是导出的性能,mysqldu ...
- 解决在Linux操作系统下无法连接MySQL服务端的问题
遇到这种问题的时候我们需要考虑的是防火墙规则,因为防火墙默认是禁止所有端口访问的,所以我们需要添加一个访问端口来连接MySQL. 命令如下: 允许某端口 firewall-cmd --zone= ...