文章目录
- js 常见报错
- 1.1 SyntaxError(语法错误)
- 1.2 ReferenceError(引用错误)
- 1.3 RangeError(范围错误)
- 1.4 TypeError(类型错误)
- 1.5 URLError(URL错误)
- 1.6 手动抛出错误
- js 获取数据类型
- 1.1 typeof
- 注意
- 1.2 Object.prototype.toString.call()
- 注意
- 1.3 instanceof
- 判断自定义类型
- 1.4 constructor
- 判断自定义类型
- 封装打印所有类型
- js 判断是否是数组
- instanceof、constructor不好的原因
- isArray
- 封装方法
今天菜鸟整理自己的 goole 书签栏,突然发现,看着确实挺有用,通过标题大致就知道是什么内容,大致就知道了什么时候可以帮助菜鸟解决什么问题,没用的或者太简单的就删除了。
但是菜鸟转念一想,发现菜鸟脑子里是一点印象都没有,如果用的时候来找的话,找得到还好,找不到就像考试作弊,明明考试前还看见了,但是一到考试就找不到答案在哪里的感觉,心态直接炸了。
而且感觉一些基础,即使不好记,也真的需要记在脑子里,而不是书签里,所以就把几个菜鸟感觉很重要、很常用的,这里做个总结,俗话说:好记性不如烂笔头,也希望可以帮助读者!
js 常见报错
建议熟悉单词:
- Invalid 无效
- unexpected 意外的
- defined 未定义
- property 属性
也要熟记这后面的几个错误单词!!!
1.1 SyntaxError(语法错误)
解析代码时发生的语法错误
var 1a; //Uncaught SyntaxError: Invalid or unexpected token 无效或意外的标识符 - 变量名错误
console.log 'hello'); //Uncaught SyntaxError: Unexpected string 意外的字符串 - 缺少括号
1.2 ReferenceError(引用错误)
console.log(a); //Uncaught ReferenceError: a is not defined a未定义 - 引用了一个不存在的变量
console.log()= 1; //Uncaught ReferenceError: Invalid left-hand side in assignment 将变量赋值给一个无法被赋值的对象
1.3 RangeError(范围错误)
var a = new Array(-1); //Uncaught RangeError: Invalid array length 无效长度 - 超出有效范围
1.4 TypeError(类型错误)
变量或参数不是预期类型,比如,对字符串、布尔值、数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数
var a = new 123; //Uncaught TypeError: 123 is not a function
调用不存在的方法
var a;
a.aa(); //Uncaught TypeError: Cannot read property 'aa' of undefined
1.5 URLError(URL错误)
与url相关函数参数不正确,主要是encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。
decodeURI('%2') //Uncaught URIError: URI malformed at decodeURI
1.6 手动抛出错误
以上这 5 种派生错误,连同原始的Error对象,都是构造函数。开发者可以使用它们,人为生成错误对象的实例。
throw new Error("出错了!");
throw new RangeError("出错了,变量超出有效范围!");
throw new TypeError("出错了,变量类型无效!");
上面代码表示新建错误对象的实例,实质就是手动抛出错误。可以看到,错误对象的构造函数接受一个参数(可以是对象),代表错误提示信息。
菜鸟还有一种报错没总结,感觉常用,更多参考:JS中常见的几种报错类型
js 获取数据类型
js 的数据类型
ES6以前。6种:Undefined、Null、Number、Boolean、String、Object
ES6标准。7种:Undefined、Null、Number、Boolean、String、Symbol、Object
ES2020标准。8种:Undefined、Null、Number、Boolean、String、Symbol、BigInt、Object
以下是用于测试的各种类型(不包括 BigInt 类型):
var a = 123,
b = true,
c = "123",
d = undefined,
e = null;
var o = new Object();
var f = new Function();
var f1 = function () {};
function f2() {}
var arr = [];
var arr1 = new Array();
var reg = new RegExp();
var sy = Symbol();
1.1 typeof
可以判断 js 中基本数据类型,但无法判断对象的具体类型
代码:
console.log("a:" + typeof a);
console.log("b:" + typeof b);
console.log("c:" + typeof c);
console.log("d:" + typeof d);
console.log("e:" + typeof e);
console.log("o:" + typeof o);
console.log("f:" + typeof f);
console.log("f1:" + typeof f1);
console.log("f2:" + typeof f2);
console.log("arr:" + typeof arr);
console.log("arr1:" + typeof arr1);
console.log("reg:" + typeof reg);
console.log("sy:" + typeof sy);
结果:
注意
当使用基本包装类型创建字符串、数组或布尔值时,使用typeof返回的是Object
判断基本类型
function ccTypeof(cc){
return cc === null ? "null" : typrof(cc);
}
1.2 Object.prototype.toString.call()
可以判断具体的对象类型,包括正则等
代码:
console.log("a:" + Object.prototype.toString.call(a));
console.log("b:" + Object.prototype.toString.call(b));
console.log("c:" + Object.prototype.toString.call(c));
console.log("d:" + Object.prototype.toString.call(d));
console.log("e:" + Object.prototype.toString.call(e));
console.log("o:" + Object.prototype.toString.call(o));
console.log("f:" + Object.prototype.toString.call(f));
console.log("f1:" + Object.prototype.toString.call(f1));
console.log("f2:" + Object.prototype.toString.call(f2));
console.log("arr:" + Object.prototype.toString.call(arr));
console.log("arr1:" + Object.prototype.toString.call(arr1));
console.log("reg:" + Object.prototype.toString.call(reg));
console.log("sy:" + Object.prototype.toString.call(sy));
结果:
注意
无法判断自定义对象类型
function A() {
return 111;
}
var x = new A();
console.log(Object.prototype.toString.call(x));
该代码结果为
而不是预期的 A
1.3 instanceof
用法:变量 instaceof 对象,返回值为boolean
仅能判断对象类型的具体类型,undefined 和 null 报错,但可以拥于判断自定义对象类型。
改成小写也不行,报错:
Uncaught TypeError: Right-hand side of ‘instanceof’ is not an object
null 同理!
代码:
console.log(a instanceof Number);
console.log(b instanceof Boolean);
console.log(c instanceof String);
console.log(o instanceof Object);
console.log(f instanceof Function);
console.log(f1 instanceof Function);
console.log(f2 instanceof Function);
console.log(arr instanceof Array);
console.log(arr1 instanceof Array);
console.log(reg instanceof RegExp);
console.log(sy instanceof Symbol);
结果·:
判断自定义类型
代码:
function A(){
this.a = 1;
}
function B(){
this.b = 2;
}
var x = new A();
if(x instanceof A){
console.log("x is A");
}
if(x instanceof B){
console.log("x is B");
}else{
console.log("x is not B");
}
结果:
1.4 constructor
查看对象对应的构造函数,object 的每个实例都具有属性 constructor,保存着用于创建当前对象的函数,和 instaceof 一样,undefined 和 null 报错,但是比 instaceof 功能更强大。
代码:
console.log(a.constructor === Number);
console.log(b.constructor === Boolean);
console.log(c.constructor === String);
console.log(o.constructor === Object);
console.log(f.constructor === Function);
console.log(f1.constructor === Function);
console.log(f2.constructor === Function);
console.log(arr.constructor === Array);
console.log(arr1.constructor === Array);
console.log(reg.constructor === RegExp);
console.log(sy.constructor === Symbol);
结果:
判断自定义类型
代码:
function A() {
this.a = 1;
}
function B() {
this.b = 2;
}
var x = new A();
if (x.constructor == A) {
console.log("x is A");
}
if (x.constructor == B) {
console.log("x is B");
} else {
console.log("x is not B");
}
结果:
封装打印所有类型
function ccTypeof(cc){
var typeName == Object.prototype.toString.call(cc);
if( typeName == "[object Object]"){
typeName = "[object" + cc.constructor.name + "]";
}
}
js 判断是否是数组
有了上述学习,可以轻易的知道有 3 种方式可以知道是否为 Array ,分别为:Object.prototype.toString.call()、instanceof 、constructor,但是其实 instanceof 、constructor 不是特别好。
instanceof、constructor不好的原因
instanceof 运算符用于检验构造函数的 prototype 属性是否出现在对象的原型链中的任何位置,返回一个布尔值。
需要注意的是,prototype 属性是可以修改的,所以并不是最初判断为true就一定永远为真。
其次,当我们的脚本拥有多个全局环境,例如:html中拥有多个iframe对象,instanceof的验证结果可能不会符合预期
//为body创建并添加一个iframe对象
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
//取得iframe对象的构造数组方法
xArray = window.frames[0].Array;
//通过构造函数获取一个实例
var arr = new xArray(1,2,3);
arr instanceof Array;//false
导致这种问题是因为 iframe 会产生新的全局环境,它也会拥有自己的 Array.prototype 属性,让不同环境下的属性相同很明显是不安全的做法,所以 Array.prototype !== window.frames[0].Array.prototype,想要 arr instanceof Array 为 true,你得保证 arr 是由原始 Array 构造函数创建时才可行。
constructor 也有该问题!
isArray
虽然 Object.prototype.toString.call() 没有上述问题,但是这么长的一串确实不好记,其实 js 已经考虑到了这些,所以为我们提供了更加方便的方法:isArray!
简单好用,而且对于多全局环境,Array.isArray() 同样能准确判断,但有个问题,Array.isArray() 是在ES5中提出,也就是说在ES5之前可能会存在不支持此方法的情况。
封装方法
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}