JS中的错误分类
1、语法错误
JS代码在预编译时 就发现了错误。
特点:
1)代码没有机会执行
2)错误最好找
function () {
}
//Uncaught SyntaxError: Function statements require a function name
2、引用错误
通常访问一个没有定义的变量就会发生引用错误。
- 解决办法:先定义好这个变量,再使用之
- 特点:JS代码在执行时的时候,才会发现引用错误,错误之后的代码就不执行
console.log("start");
console.log(a); //ReferenceError: a is not defined
console.log("end");
3、类型错误
使用类型不当,你提供的数据,不是JS想要的。
- 解决办法:一般是你数据类型使用不当,修改之就OK了
- 特点:JS代码在执行时的时候,才会发现引用错误,错误之后的代码就不执行
console.log("start")// TypeError: f is not a function
var f = 110;
f();
console.log("end")
4、范围错误
使用容器时,范围指定不当
var arr = ["a","b","c"]; // 定义数组方式1
var arr2 = new Array(10); // 定义数组方式2 10表示数组中可以存储10个数据
var arr3 = new Array(-5); // Uncaught RangeError: Invalid array length
上面的4类错误,在控制台都会报错,修改就OK了,。还有一类错误,控制台不会报错,叫逻辑逻辑错误。
逻辑错误解决办法:通过debugger调试错误。
异常处理
异常不是错误,异常是指可能出错的错码。
语法:
try{
// 放可能出错的代码
}catch(e){
// 如果上面的代码错误了,就到这里进行错误的处理,其中e表示错误对象
// 它里面包含了错误信息。通过查看e,可以知道它到底出了什么错误
}finally{
// 无论对错,代码都会执行到此处,在JS中用的不多
}
this
结论:
1)如果this出现在普通的函数中,this表示window,如果你通过window打点调用一个函数,这个函数中的this也是window
2)事件绑定,事件处理程序,事件发生时,浏览器帮我们调用这个函数,此函数中的this表示事件源
3)在一个对象中,如果有方法(函数),如果通过这个对象调用方法,方法中的this表示这个对象
4)在IIFE中,this表示window
5)前四点都是在非严格模式下,在严格模式下,调用一个普通函数,this表示und。就IIFE中的this也表示und
面向对象
1、面向对象
JS也是面向对象的,这种面向对象非常奇葩。
基本上所有的高级语言都是面向对象编程。面向对象是一种思想。
常见几种思想:
面向过程:C语言 没有类 没有对象
面向对象:JAVA,C++,JS(恶心)
面向切面:Spring IOC AOP
面向对象特征:
抽象:把一个具体问题抽象化。
封装:把属性和方法封装到类中,在JS中重点说对象。
var obj = {
name:“wc”,
age:100,
say:function(){
log(“say…”);
}
}
继承:一个类可类可以继承另一个类,在JS,类是通过函数表达式。
多态
面向对象中的类和对象:
类:JS中的类本质还是一个函数 是抽象的,不具体
function Person(){ // 是一个类的话,首字母会大写
}
new Person(); // 此时Persion是一个类
Person(); // 此时Person就是一个函数
对象:
var obj = {name:"wc"}; obj就是一个对象,在JS中一个{}就是一个对象。
如果在JAVA中,对象都是new出来的,先有class,后有对象。
2、JS默认提供了很多类
Number 类
var n = new Number("100");
console.log(n); // Number {100}
console.log(typeof n); // object
console.log(n instanceof Number); // true
// instanceof 是一个运算符 判断一个对象是否属性某个类
String 类
var str = new String("hello oop");
console.log(str) // {"hello oop"}
console.log(typeof str) // object
console.log(str instanceof String); // true
console.log(str instanceof Number); // false
// 对象 也叫 实例
// 类 也叫 构造器(JS特有)
Boolean 构造器 类
var f = new Boolean(false);
console.log(f) // {false}
console.log(typeof f) // object
console.log(f instanceof Boolean) // true
Object 构造器 类
// 按理说,你要想写一个对象,都需要通过new一个构造器 得到一个对象
var obj = new Object(); // new一个构造器得到一个对象
obj.name = "wc";
obj.age = 110;
console.log(obj); // {name: "wc", age: 110}
// 下面的写法是上面的写法的语法糖(是上面写法的简写)
var obj2 = { // 字面量形式声明一个对象
name:"xiaoqiang",
age:100
}
Date 日期
var d = new Date();
console.log(d);
console.log(d.getFullYear())
Math 数学计算相关,不需要new 单体内置类
// 常驻内存不需要new
var r = Math.random();
console.log(r);
Array是一个内置类 new
var arr = new Array("a","b","c");
console.log(arr); // ["a", "b", "c"]
// 是上面的形式的语法糖
var arr2 = ["d","e","f"]; // 字面量创建数组(对象)
console.log(arr2); // ["d", "e", "f"]
3、对象中的属性有 4大特征
- configurable 表示是否可以被删除 true表示可以删除
2)writable 表示是否可以修改 true表示可以修改
3)enumerable 是否可以枚举 是否可以输出 true表示可以输出
4)value 属性值 默认是und
var obj = {
name:"wangcai"
}
// 通过Object.getOwnPropertyDescriptor 获取属性的特征
// configurable: true
// writable: true
// enumerable: true
// value: "wangcai"
console.log(Object.getOwnPropertyDescriptor(obj, "name"));
给一个对象添加一个属性时,也可以设置上面的4个特征
// Object.defineProperty()
var obj = {};
Object.defineProperty(obj,"name",{
configurable:false,
writable:false,
enumerable:true,
value:"wangcai"
})
4、属性的分类(私有属性 公有属性)
对象上的属性是分成两类的
- 私有属性
- 公有属性
<script>
var obj = {
name:"wangcai",
age:100
}
// 通过一个api可以查看一个属性是否是私有属性
// 叫 hasOwnProperty();
console.log(obj.hasOwnProperty("name")); // true 查看name是否是obj的私有属性
console.log(obj.hasOwnProperty("age")); // true
// 公有属性 原型属性
console.log(obj)
console.dir(obj.hasOwnProperty("toString")); // false 查看toString是否是obj的私有属性
console.log(obj.hasOwnProperty("__proto__")); // false 查看__proto__是否是obj的私有属性
console.log(obj.__proto__.hasOwnProperty("toString")); // true // 查看toString是否是obj.__proto__这个对象的私有属性
// 对于obj来说:name和age是它的私有属性 toString是它的公有属性
// 对于obj.__proto__来说:toString是它的私有属性
// 也就是说一个属性是私有属性还是公有属性,还需要看它针对是谁。
var arr = ["a","b"];
console.dir(arr);
console.log(arr.hasOwnProperty("length")); // true
console.log(arr.hasOwnProperty("push")); // false
console.log(arr.hasOwnProperty("__proto__")); // false
console.log(arr.__proto__.hasOwnProperty("push")); // true
// delete只能删除私有属性 不能删除公有属性
delete arr[0];
console.log(arr);
delete arr.push;
console.dir(arr)
// 如果一个私有属性和公有属性重名了 会把公有属性覆盖掉
var a1 = ["a"];
console.dir(a1)
a1.push("b")
console.dir(a1)
a1.push = function () {
console.log("自己的push")
}
a1.push("c");
</script>
判断一个属性是否属于某个对象
// hasOwnProperty
// in 是一个运算符 是公有属性 得到的也是true
var obj = {
name:"wangcai"
}
console.log(obj.hasOwnProperty("name"));// 判断name是否是obj的私有属性 true
console.log("name" in obj); // 判断name是否是obj的属性 true
console.dir(obj)
console.dir("toString" in obj) // 判断toString是否是obj的属性 true
console.dir("xxx" in obj) // 判断xxx是否是obj的属性 false
给出一个对象,说出这个对象是由谁构造的(创建的),任何一个对象中都有一个属性,叫__proto__,此属性也是一个对象, 此对象中有一个属性叫 constructor 是构造器。
var arr1 = new Array("a","b");
console.dir(arr1)
var arr2 = ["c","d"];
console.dir(arr2)
function f() { // Function() 一个普通函数是由Function()创建的
console.log("f....")
}
console.dir(f)
5、函数的四种角色
角色一:一个普通的函数
function f() {
console.log("f...")
}
// f(); 作用1:让函数体执行 作用2:得到返回值
f();
角色2:在对象中可以当成一个方法
let obj = {
say:function () { // 方法
console.log("say...")
},
sleep:function () { // 方法
console.log("sleep...")
}
}
obj.say()
obj.sleep()
角色3:类 构造器
function NBAPlayer() {
}
var nbaPlayer1 = new NBAPlayer();
var nbaPlayer2 = new NBAPlayer();
var nbaPlayer3 = new NBAPlayer();
console.log(nbaPlayer1);
console.log(nbaPlayer2);
console.log(nbaPlayer3);
角色4:也可以当作是一个对象
function F() {
}
F.name1 = "wangcai";
F.age = 100
console.log(F.name1)
console.log(F.age)