typeof:返回一个值的数据类型
instanceof:表示对象是否是某个构造函数的实例
Object.prototype.toString
typeof
可以用来检查一个未声明的变量,而不报错;
// 基本数据类型
var tmp1 = "字符串";
var tmp2 = 1;
var tmp3 = 1.1;
var tmp4 = true;
// 特殊类型
var tmp5= undefined;
var tmp6 = null; // null 是一个 object
// 对象
var tmp7 = {}; // 对象
var tmp8 = []; // 数组
var tmp9 = function(){}; // 函数
console.log("typeof(tmp1)", typeof (tmp1));
console.log("typeof(tmp2)", typeof (tmp2));
console.log("typeof(tmp3)", typeof (tmp3));
console.log("typeof(tmp4)", typeof (tmp4));
console.log("typeof(tmp5)", typeof (tmp5));
console.log("typeof(tmp6)", typeof (tmp6));
console.log("typeof(tmp7)", typeof (tmp7));
console.log("typeof(tmp8)", typeof (tmp8));
console.log("typeof(tmp9)", typeof (tmp9));
// function 因为有类object 的操作, 所以也属于 object
console.log("tmp9.name", tmp9.name); // 获取函数名
//typeof(tmp1) string
//typeof(tmp2) number
//typeof(tmp3) number
//typeof(tmp4) boolean
//typeof(tmp5) undefined
//typeof(tmp6) object
//typeof(tmp7) object
//typeof(tmp8) object
//typeof(tmp9) function
//tmp9.name tmp9
null 和 undefined 的区别
boolean
布尔值表示真和假,true 表示真,false 表示假;
下列运算符会返回布尔值:
表示 false 的值
在自动数据转换中,下列值会表示 false:
其他的值都会被当成 true;
空数组 [] 和空对象 {} 对应的布尔值都是 true;
在 js 中,所有的数值都是 64 位浮点数的形式进行存储的,也就是说在 js 底层,没有整数只有浮点数;
因为浮点数精度的问题,js 在进行浮点数运算的时候经常会出现问题:
console.log(0.1 + 0.2);
// 0.30000000000000004
默认情况下,js 内部会将八进制,十六进制,二进制转为十进制;
NaN 是 js 中的特殊值,表示非数字 (Not a Number), 主要出现在字符串解析成数字出错的时候;
Infinity 用来表示无穷,一般出现在两种场景下:
parseInt(string[,radix])
parseInt(string[,radix])
将字符串解析成数值;如果入参非字符串,则会调用入参的 toString
方法转换为字符串再进行转换;如果设置了第二个参数 radix, 则会将字符串按指定的 radix 进制转换成十进制;返回数值或者 NaN
var a = '0xf';
console.log(a, 16); // 将 16 进制的 0xf 转为十进制
// 15
parseFloat(string)
parseFloat(string)
将字符串入参解析成浮点数;返回浮点数或者 NaN ;
var a = "4.567";
console.log(parseFloat(a)); // 4.567
// 当入参有非法字符, 则只保留合法部分进行转换
var b = "4.567abcd";
console.log(parseFloat(b)); // 4.567
// 第二个小数点忽略
var c = "1.2.3";
console.log(parseFloat(c)); // 1.2
// 起始为非法字符则直接返回 NaN
var d = "aaa1.2"; // NaN
console.log(parseFloat(d));
isNaN()
判断某个入参是否是 NaN; 可以利用 NaN 的不等性来进行判断
var a = NaN;
if (a != a ){
console.log("it is NaN");
}
isFinite()
判断某个入参是否是 Infinity;
js 中使用的字符集为 Unicode 字符集,所有的字符串都使用 Unicode 表示;
var f\u006F\u006F = 'abc';
console.log(f\u006F\u006F);
encodeURIComponent
decodeURIComponent
var base64encode = Buffer.from("js").toString("base64");
var base64decode = Buffer.from(base64encode,'base64').toString();
Obejct.keys()
可以查看该对象自身的属性,继承来的属性无法查看
var a = {
hello: function(){
consoel.log("hi");
},
table: [1, 2, 3],
name: "kevin",
age: 21,
married: false
}
console.log(Object.keys(a));
//[ 'hello', 'table', 'name', 'age', 'married' ]
var a = {
hello: function(){
consoel.log("hi");
},
table: [1, 2, 3],
name: "kevin",
age: 21,
married: false
}
delete a.age, delete a.hello;
console.log(Object.keys(a));
// [ 'table', 'name', 'married' ]
hasOwnProperty()
: 判断某个属性是否是该对象自身的属性;JSvar a = {
hello: function () {
consoel.log("hi");
},
table: [1, 2, 3],
name: "kevin",
age: 21,
married: false
}
console.log(a.hasOwnProperty('table'));
if ("table" in a) {
console.log("table is property of a");
}
hasOwnProperty()
进行筛选var a = {
hello: function(){
consoel.log("hi");
},
table: [1, 2, 3],
name: "kevin",
age: 21,
married: false
}
for (const aKey in a) {
// 使用 hasOwnProperty 进行筛选
if (a.hasOwnProperty(aKey)) {
console.log(aKey);
}
}
js 中函数声明有三种方式
function a(){}
var a = function(){}
var a = Function("a","b", "return a+b")
或者 var a = new Function("a","b", "return a+b")
这两种方式效果一样js 将函数看成是一个值,与其他数据类型一样,凡是可以使用其他数据类型的地方都可以使用函数,例如:
js 中全局变量名存在变量提升,函数内部的局部变量也存在变量提升;
function outer() {
console.log(a); // undefined 说明全局变量存在变量提升
console.log(b); // undefined 说明局部变量存在变量提升
var b = 2;
}
outer();
var a = 1;
js 中函数的声明也存在变量提升,可以先调用该方法,再定义该方法
b();
function b() {
console.log("b called");
}
js 中函数的参数不是必须的,允许省略函数的参数;
函数的 length 属性只和函数声明时形参的个数有关,和实际调用时传入的参数个数无关;
arguments[0]
就是第一个参数;Array.prototype.slice.call(arguments)
var a = 1;
var b = 2;
function f() {
var b = 3;
console.log(a, b);
function f1() {
var b = 4;
console.log(a, b);
}
f1();
}
f(); // 1 3// 1 4
链式作用域查找
子级会优先使用自己的作用域,如果变量存在则使用,不存在则会依次向上寻找,直至全局作用域;
闭包定义
通过闭包实现简单的计数器
function count() {
var count = 0;
function f() {
count++;
console.log("count", count);
}
return f;
}
f = count();
f();
f();
f();
js 中有三种立即调用函数的方式
var f = function(){}();
(function(){}())
(function(){})()
通常情况下,只对匿名函数使用这种立即执行的表达式,这样有两个目的:
eval 别名调用
eval 的别名调用在 nodejs 下无法跑通,需要在浏览器下运行;
需要注意,在 eval 通过别名调用的时候,作用域永远是全局作用域;
var a = 1;
var e = eval;
(function () {
var a = 2;
e("console.log(a);"); // eval 在别名调用的时候使用全局作用域
}())
var a = 1;
var e = eval;
(function () {
var a = 2;
e("console.log(a);"); // eval 在别名调用的时候使用全局作用域
}
())
var a = [1, 1.1, true, {}, [], "hello", null, undefined];
console.log("a.length", a.length);
a.name = "add a.name property";
for (const aKey in a) {
console.log(aKey, a[aKey]);
}
console.log("Object.keys(a)", Object.keys(a));
a.length = 0;
console.log("a", a);
console.log("a['name']", a['name']);
console.log("a.name", a.name);
console.log("a[0]", a[0]);
var a = 1;
var e = eval;
(function () {
var a = 2;
e("console.log(a);"); // eval 在别名调用的时候使用全局作用域
}
())
var a = [1, 1.1, true, {}, [], "hello", null, undefined];
console.log("a.length", a.length);
a.name = "add a.name property";
for (const aKey in a) {
console.log(aKey, a[aKey]);
}
console.log("Object.keys(a)", Object.keys(a));
a.length = 0;
console.log("a", a);
console.log("a['name']", a['name']);
console.log("a.name", a.name);
console.log("a[0]", a[0]);
var a = [1, 1.1, true, {}, [], "hello", null, undefined];
for infor(const aKey in a) {
console.log("aKey:", aKey, "value:", a[aKey]);
}
console.log("-------------------------------")
forfor(var i = 0; i <= a.length; i++) {
console.log("index:", i, "value:", a[i]);
}
console.log("-------------------------------")
whilevar index = 0;
while (index <= a.length) {
console.log("index:", index, "value:", a[index]);
index++;
}
console.log("-------------------------------")
forEacha.forEach(function (value, key) {
console.log("key:", key, "value:", value);
})
js 中的数组支持空值,出现空值时会占用该索引位,但是遍历的时候不会遍历该索引的值
var a = [1, 2, 3, , 5];
a.forEach(function (value, key) {
console.log("key", key, "value", value);
})
// key 0 value 1
// key 1 value 2
// key 2 value 3
// key 4 value 5
var arr = Array.prototype.slice.call(arrayLike);
Array.prototype.forEach.call(arrayLike, function(){});
当 +
加号作为操作符,且操作数中含有字符串时,会自动将另一个操作数转为字符串;
规则如下:
valueOf()
方法,如果该方法返回基础数据类型则将其转为字符串,如果返回的是复合数据类型,则调用 toString()
方法,如果返回的是基础数据类型则将其转为字符串,如果不是则报错;// 基础类型
// 自动数据类型转换
// + 字符串
// 1. 字符串 + 基础数据类型: 会直接将基础数据类型转为和字面量相同的字符串
var tmp1 = "" + 3;
console.log("tmp1", tmp1); // tmp1 "3"
var tmp2 = "" + true;
console.log("tmp2", tmp2); // tmp2 "true"
var tmp3 = "" + undefined;
console.log("tmp3", tmp3); // tmp3 "undefined"
var tmp4 = "" + null;
console.log("tmp4", tmp4); // tmp4 "null"
// 字符串+复合数据类型: 复合数据类型会先调用 valueOf 方法, 如果此方法返回的是引用类型, 则再调用 toString()方法, 最后将返回值转为字符串类型
var tmp5 = [1, 2, 3] + "";
console.log("tmp5", tmp5); // tmp5 1,2,3
var tmp6 = {} + "";
console.log("tmp6", tmp6); // tmp6 [object Object]
// 重写 toString 方法
var o = {
toString: function () {
return 1;
}
}
var tmp7 = o + "";
console.log("tmp7", tmp7) // tmp7 "1"
// 重写 valueOf 方法
o.valueOf = function () {
return 2;
}
var tmp8 = "" + o;
console.log("tmp8", tmp8); // tmp8 2
var a = {
valueOf: function () {
return {}
},
toString: function () {
return "toString"
}
};
console.log("" + a); // toString
数值转布尔值
数值在逻辑判断条件下会自动转成布尔值;±0 和 NaN 为 false, 其他数值都是 true;
if (0) {
console.log("0 is true");
}else{
conso