确定值类型:typeof、instanceof、Object.prototype.toString
1、typeof运算符
返回类型:number、string、boolean、undefined、null、object、function
1.1 知识点补充:null 和 undefined的区别?
区别:
null:表示空值
undefined:未定义
Number(null) // 0 eg: nul + 5 // 5 Number(undefined) // NaN eg: undefined + 5 // NaN
1.2 boolean值
转换规则:除了下面6个值为false,其他均为true null undefined 0 ''或者"" false NaN
注意:[] 和 {} 得到的bool值也为true
1.3 number
javaScript 语言没有整数,所有数字都是小数(64位浮点数)。
由于浮点数不是精确的数值,所以:
0.1 + 0.2 === 0.3 // false
0.3 / 0.1 // 2.9999999999999996
parseInt:将字符串转为整数
parseInt:将字符串转为整数 parseInt('123'); // 123 头部有空格,会被自动去除 parseInt(' 81'); // 81 如果parseInt的参数不是字符串,则会先转为字符串再转换。 parseInt('1.23'); // 1 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。 parseInt('8a') // 8 parseInt('12**') // 12 parseInt('12.34') // 12 parseInt('15e2') // 15 parseInt('15px') // 15
如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN
。
parseInt('abc') // NaN parseInt('.3') // NaN parseInt('') // NaN parseInt('+') // NaN parseInt('+1') // 1
parseFloat:方法用于将一个字符串转为浮点数。
如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回NaN。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
isNaN:方法可以用来判断一个值是否为NaN
。
isNaN只对数值有效,如果传入其他值,会被先转成数值。所以如果为true的话,有可能是NaN也有可能是字符串
isNaN(NaN) // true
isNaN(123) // false
isNaN('Hello') // true
// 相当于
isNaN(Number('Hello')) // true
但是,对于空数组和只有一个数值成员的数组,isNaN
返回false
。
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
判断NaN
更可靠的方法是,利用NaN
为唯一不等于自身的值的这个特点,进行判断。
function myIsNaN(value) { return value !== value; }
isFinite():isFinite
方法返回一个布尔值,表示某个值是否为正常的数值。
isFinite(Infinity) // false isFinite(-Infinity) // false isFinite(NaN) // false isFinite(undefined) // false isFinite(null) // true isFinite(-1) // true
除了Infinity
、-Infinity
、NaN
和undefined
这几个值会返回false
,isFinite
对于其他的数值都会返回true
。
base64转码:
JavaScript 原生提供两个 Base64 相关的方法。
btoa()
:任意值转为 Base64 编码atob()
:Base64 编码转为原来的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"
这两个方法不适合非 ASCII 码的字符,会报错。
btoa('你好') // 报错
要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。
编码:
btoa(encodeURIComponent('你好'));
// "JUU0JUJEJUEwJUU1JUE1JUJE"
解码:decodeURIComponent(atob('
JUU0JUJEJUEwJUU1JUE1JUJE
')); // 你好
对象:
对象指向的是同一个内存地址; var obj1 = {}; var obj2 = obj1; obj1.a = 1; obj2.a; // 1
变量不指向同一个内存地址
var x = 1;
var y = x;
x = 2;
y; // 1
查看一个对象本身的所有属性,可以使用Object.keys
方法。
var obj = { key1: 1, key2: 2 }; Object.keys(obj); // ['key1', 'key2']
属性的删除:delete 命令
var obj = { p: 1 }; Object.keys(obj) // ["p"] delete obj.p // true obj.p // undefined Object.keys(obj) // []
检查属性是否存在:in 运算符
存在返回true,否则返回false
var obj = { p: 1 }; 'p' in obj // true 'toString' in obj // true
in
运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。就像上面代码中,对象obj
本身并没有toString
属性,但是in
运算符会返回true
,因为这个属性是继承的。
这时,可以使用对象的hasOwnProperty
方法判断一下,是否为对象自身的属性。
var obj = {}; if ('toString' in obj) { console.log(obj.hasOwnProperty('toString')) // false }
对象属性的遍历:for...in 循环
var obj = {a: 1, b: 2, c: 3}; for (var i in obj) { console.log('键名:', i); console.log('键值:', obj[i]); }
在函数对象内修改某个参数,可以影响原对象,但是修改整个对象就不会影响原对象
修改对象中的某个值:因为指向同一个内存地址 var obj = { p: 1 }; function f(o) { o.p = 2; } f(obj); obj.p // 2 修改整个对象,不会影响原对象数据,因为它重新对o
赋值导致o
指向另一个地址,保存在原地址上的值当然不受影响。 var obj = [1, 2, 3]; function f(o) { o = [2, 3, 4]; } f(obj); obj // [1, 2, 3]
arguments:由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。
arguments对象包含了函数运行时的所有参数 argument[0] 第一个参数 argument[1] 第二个参数
这个对象只有在函数体内部,才可以使用。
var f = function (one) { console.log(arguments[0]); console.log(arguments[1]); console.log(arguments[2]); } f(1, 2, 3)
闭包:能够读取其他函数内部变量的函数
闭包的最大用处有两个,一个是可以读取外层函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
IIFE:立即调用的函数表达式(Immediately-Invoked Function Expression);
var i = function(){ return 10; }();
eval:命令接受一个字符串作为参数,并将这个字符串当作语句执行。
eval('var a = 1;'); // 1 如果参数字符串无法当作语句运行,那么就会报错。 eval('3x') // Uncaught SyntaxError: Invalid or unexpected token
数组:
delete可以删除数组的元素,形成空位,但是不会影响数组的长度。 eg: var a = [1, 2, 3]; delete a[1]; a[1] // undefined a.length // 3
数组的某个位置是空位,与某个位置是undefined
,是不一样的。如果是空位,使用数组的forEach
方法、for...in
结构、以及Object.keys
方法进行遍历,空位都会被跳过。
如果是undefined,则不会跳过。