本文章仅针对我自己在看书过程中对一些不太清楚的知识点进行查漏补缺——《你不知道的JavaScript(中卷)》第一部分类型和语法中的 第三章+第四章+第五章
原生函数
原生函数有哪些
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
原生函数当作构造函数使用会怎么样
原生函数可以被当作构造函数来使用,但其构造出来的对象可能会和我们设想的有所出入
var a = new String( "abc" );
typeof a; // 是"object",不是"String"
a instanceof String; // true
Object.prototype.toString.call( a ); // "[object String]"
var b = new Boolean( false );
!b; // false 而不是true 因为此时b为一个对象valueOf()函数有什么作用
如果想要得到封装对象中的基本类型值,可以使用 valueOf() 函数
var a = new String( "abc" );
var b = new Number( 42 );
var c = new Boolean( true );
a.valueOf(); // "abc"
b.valueOf(); // 42
c.valueOf(); // true哪些原生函数尽量不要使用
Object(..)/Function(..)/RegExp(..)
在实际情况中没有必要使用 new Object() 来创建对象,因为这样就无法像常量形式那样一次设定多个属性,而必须逐一设定。
构造函数 Function 只在极少数情况下很有用,比如动态定义函数参数和函数体的时候。不要把 Function(..) 当作 eval(..) 的替代品,你基本上不会通过这种方式来定义函数。
强烈建议使用常量形式(如 /^a*b+/g )来定义正则表达式,这样不仅语法简单,执行效率也更高,因为 JavaScript 引擎在代码执行前会对它们进行预编译和缓存。与前面的构造函数不同,RegExp(..) 有时还是很有用的,比如动态定义正则表达式时:
var name = "Kyle";
var namePattern = new RegExp( "\\b(?:" + name + ")+\\b", "ig" );
var matches = someText.match( namePattern );Symbol
Symbol不能通过构造函数即new Symbol形式创建,否则会报错
Object.getOwnPropertySymbols(..) 便可以公开获得对象中的所有符号
Symbol.iterator属性的值是一个函数,它返回一个迭代器对象;迭代器指的是拥有next方法的对象;next方法返回的是一个带有value和done的对象,而for/of循环是用于遍历可迭代对象的
var obj = {}
obj[Symbol.iterator] = function(){ /*..*/ };特殊的原生原型
Function.prototype 是一个空函数
RegExp.prototype 是一个“空”的正则表达式(无任何匹配)
Array.prototype 是一个空数组
强制类型转化
JSON
undefined、function 、symbol (ES6+)和包含循环引用(对象之间相互引用,形成一个无限循环)的对象都不符合 JSON 结构标准,支持 JSON的语言无法处理它们
JSON.stringify(..) 在对象中遇到 undefined 、function 和symbol 时会自动将其忽略,在数组中则会返回 null
如果对象中定义了 toJSON() 方法,JSON 字符串化时会首先调用该方法,然后用它的返回值来进行序列化。但这并不意味着toJSON() 返回的是 JSON 字符串化后的值,而是返回一个能够被字符串化的安全的 JSON值
Number()
如果Number()函数里面的参数是一个对象,检查该值是否有 valueOf() 方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用toString() 的返回值(如果存在)来进行强制类型转换。如果 valueOf() 和 toString() 均不返回基本类型值,会产生TypeError 错误。
var a = {
valueOf: function(){
return "42";
}
};
var b = {
toString: function(){
return "42";
}
};
var c = [4,2];
c.toString = function(){
return this.join( "" ); // "42"
};
Number( a ); // 42
Number( b ); // 42
Number( c ); // 42
Number( "" ); // 0
Number( [] ); // 0
Number( [ "abc" ] ); // NaNBoolean假值有哪些
undefined
null
false
+0 0 -0 NaN
"" " " "\t" "\n" "\n\t"
其他都为真哦,包括假值对象如
var a = new Boolean( false );
var b = new Number( 0 );
var c = new String( "" );
var d = Boolean( a && b && c );
d; // true+
var timestamp = +new Date(); // 当前时间的时间戳
var p = +"3.14"; // 3.14parseInt()
parseInt的第一个参数为字符串(会隐式转化为数字),第二个参数为进制,默认10进制
下面来看看几个奇怪的返回值
parseInt( 1/0, 19 ); // 18解释:
1 / 0 的结果为Infinity,为数字类型,但因为parseInt的第一个参数需要为字符串,所以转化为"Infinity",进制为19,I符合19进制,n不符合,因此后面的字符都省略,即
parseInt(1 / 0, 19) => parseInt(Infinity, 19) => parseInt('Infinity', 19) => parseInt('I', 19) => 18
其他的几个例子也同理
parseInt( 0.000008 ); // 0 ("0" 来自于 "0.000008")
parseInt( 0.0000008 ); // 8 ("8" 来自于 "8e-7")
parseInt( false, 16 ); // 250 ("fa" 来自于 "false")
parseInt( parseInt, 16 ); // 15 ("f" 来自于 "function..")
parseInt( "0x10" ); // 16
parseInt( "103", 2 ); // 2==
== 允许在相等比较中进行强制类型转换,而 === 不允许
==的两边如果是数字和字符串,则会将字符串强制转化为数字再进行比较
var a = 42;
var b = "42";
a === b; // false
a == b; // true==的两边如果有布尔值,则会将布尔值强制转化为数字再进行比较
var a = "42";
var b = true;
a == b; // false==的两边如果同时为undefined或null,则相等
var a = null;
var b;
a == b; // true
a == null; // true
b == null; // true
a == false; // false
b == false; // false
a == ""; // false
b == ""; // false
a == 0; // false
b == 0; // false==的两边如果是(字符串或数字)和对象,则对象会经过抽象操作(如toString() 、valueOf())后再进行比较
var a = 42;
var b = [ 42 ];
a == b; // true举两个例子看懂了说明你彻底理解了
false == [] // 等价
0 == [] // 等价
0 == '' // 等价
0 == 0 // 所以结果为true[] == ![] // 等价
[] == false // 等价
"" == false // 等价
"" == 0 // 等价
0 == 0 // 所以结果为true
其他奇奇怪怪的情况
Number.prototype.valueOf = function() {
return 3;
};
new Number( 2 ) == 3; // truevar i = 2;
Number.prototype.valueOf = function() {
return i++;
};
var a = new Number( 42 );
if (a == 2 && a == 3) {
console.log( "Yep, this happened." );
}语法
语句和表达式
语句相当于英语中的句子,由一个或多个短语组成,它们之间由运算符连接起来
表达式相当于英语中的短语,
var a = 3 * 6;
var b = a;
b;var a = 3 * 6 和 var b = a称为“声明语句”
a = 3 * 6 和 b = a叫作“赋值表达式”
第三行代码中只有一个表达式 b ,同时它也是一个语句,叫作“表达式语句”
第一行的3 * 6 是一个表达式,第二行的 a 也是一个表达式,第三行的 b 也是
运算符优先级
&& > || > a?b:c
且... ? ... : ... 是右关联的,即
a ? b : c ? d : e; // 等价
a ? b : (c ? d : e);那么以下代码的值是多少呢?
var a = 42;
var b = "foo";
var c = false;
var d = a && b || c ? c || b ? a : c && b : a;
d; // 42
1225



被折叠的 条评论
为什么被折叠?



