1.Js中字符串是不可变的 可以用call
apply
调用数组的一些方法,但是不能调用会改变自身的方法 例如:反转字符串
let a = 'abcd';
console.log([].reverse.call(a));
//Cannot assign to read only property '0' of object '[object String]'
破解做法
let a = 'abcd';
console.log(a.split("").reverse().join(""));//dcba
2.内置构造函数创建的值
let a = new String("abc");
typeof a; // 是"object",不是"String"
let a = new Array(1, 2, 3);
typeof a; // 是"object",不是"Array"
typeof new RegExp(".d{1}", "g");// 'object'
typeof new Boolean(1)// 'object'
typeof new Number(1)// 'object'
typeof Symbol(1) //'symbol'
3.JSON.stringify JSON.parse() 的其他参数
以前在使用这两个方法时几乎没传过其他的参数 都忘了这两方法还有这种用法
JSON.stringify
() 方法用于将 JavaScript
值转换为 JSON
字符串。
语法: JSON.stringify(value[, replacer[, space]])
参数说明:
value
:必需, 要转换的JavaScript
值(通常为对象或数组)。replacer
:可选。用于转换结果的函数或数组。- 如果
replacer
为函数,则JSON.stringify
将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:“”。 - 如果
replacer
是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
- 如果
space
: 可选,文本添加缩进、空格和换行符,如果space
是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果space
大于10
,则文本缩进10
个空格。space
也可以使用非数字,如:\t
。
JSON.parse() 方法用于将一个 JSON 字符串转换为对象。
JSON.stringify(..)
并不是强制类型转换。在这里介绍是因为它涉及 ToString
强制类型转换,具体表现在以下两点。
- 字符串、数字、布尔值和 null 的 JSON.stringify(…) 规则与
ToString
基本相同。 - 如果传递给 JSON.stringify(…) 的对象中定义了 toJSON() 方法,那么该方法会在字符串化前调用,以便将对象转换为安全的 JSON 值。
语法
JSON.parse(text[, reviver])
参数说明: text
:必需, 一个有效的 JSON 字符串。reviver
: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。
let a = {
b: 42,
c: "42",
d: [1, 2, 3]
};
console.log(JSON.stringify(a, ["c", "b"]));//{"c":"42","b":42}
let res = JSON.stringify(a, function(key, value) {
if (key !== "c") return value;
});
console.log(res);//{"b":42,"d":[1,2,3]}
let obj = JSON.parse(res, function(key, value) {
if (typeof value === "number") return value + "parse";
return value;
});
console.log(obj);//{ b: '42parse', d: [ '1parse', '2parse', '3parse' ] }
// 会递归处理
console.log(JSON.stringify(a, null, 3));
/*
{
"b": 42,
"c": "42",
"d": [
1,
2,
3
]
}
*/
console.log(JSON.stringify(a, null, "-----"));
/*
{
-----"b": 42,
-----"c": "42",
-----"d": [
----------1,
----------2,
----------3
-----]
}
*/
4.强制类型转换科技 0.0 我们常用下面的方法来获得当前的时间戳,例如:
let d = new Date( "Mon, 18 Aug 2014 08:53:06 CDT" );
+d; // 1408369986000
let timestamp = +new Date();
5.强制类型转换 奇特的 ~ 运算符
将值强制类型转换为 32 位数字,然后执行字位操作“非”(对每一个字 位进行反转)。
对~
还可以有另外一种诠释,源自早期的计算机科学和离散数学:~
返回 2 的补码
。
~x
大致等同于 -(x+1)
。
~42; // -(42+1) ==> -43
在 -(x+1) 中唯一能够得到 0(或者严格说是 -0)的 x 值是 -1。也就是说如果 x 为 -1 时,~
和一些数字值在一起会返回假值 0,其他情况则返回真值。
-1 是一个“哨位值”,哨位值是那些在各个类型中(这里是数字)被赋予了特殊含义的值。
在 C 语言中我们用 -1 来代表函数执行失败,用大于等于 0 的值来代表函数执行成功。
JavaScript 中字符串的 indexOf(…) 方法也遵循这一惯例,该方法在字符串中搜索指定的子
字符串,如果找到就返回子字符串所在的位置(从 0 开始),否则返回 -1。
let a = "Hello World";
if (a.indexOf( "lo" ) >= 0) { // true
// 找到匹配!
}
if (a.indexOf( "lo" ) != -1) { // true
// 找到匹配!
}
if (a.indexOf( "ol" ) < 0) { // true
// 没有找到匹配!
}
if (a.indexOf( "ol" ) == -1) { // true
// 没有找到匹配!
}
>= 0
和 == -1
这样的写法不是很好,称为“抽象渗漏”,意思是在代码中暴露了底层的实
现细节,这里是指用 -1
作为失败时的返回值,这些细节应该被屏蔽掉。
现在我们终于明白 ~
有什么用处了!~
和 indexOf()
一起可以将结果强制类型转换(实际
上仅仅是转换)为真 / 假值:
let a = "Hello World";
console.log(~a.indexOf("lo")); // -4 <-- 真值!
if (~a.indexOf( "lo" )) { // true
// 找到匹配!
}
console.log(~a.indexOf("ol")); // 0 <-- 假值!
console.log(!~a.indexOf("ol")); // true
if (!~a.indexOf( "ol" )) { // true
// 没有找到匹配!
}
由 -(x+1) 推断 ~-1 的结果应该是 -0,然而实际上结果是 0,因为它是字位操 作而非数学运算。
6. 字位截除
x | 0
和 ~~x
可以截除数字的小数部分
一些开发人员使用 ~~ 来截除数字值的小数部分,以为这和 Math.floor(…) 的效果一样, 实际上并非如此。
~~ 中的第一个 ~ 执行 ToInt32 并反转字位,然后第二个 ~ 再进行一次字位反转,即将所有 字位反转回原值,最后得到的仍然是 ToInt32 的结果。
~~ 和 !! 很相似, 对 ~~ 我们要多加注意。首先它只适用于 32 位数字,更重要的是它对负数的处理与 Math. floor(…) 不同。
Math.floor( -49.6 ); // -50
~~-49.6; // -49
~~x 能将值截除为一个 32 位整数,x | 0 也可以,而且看起来还更简洁,出于对运算符优先级的考虑,我们可能更倾向于使用 ~~x
~~1E20 / 10; // 166199296
1E20 | 0 / 10; // 1661992960
(1E20 | 0) / 10; // 166199296