JavaScript this指向ES5组合继承(构造函数+原型对象)错误处理
Posted YuLong~W
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript this指向ES5组合继承(构造函数+原型对象)错误处理相关的知识,希望对你有一定的参考价值。
文章目录
this指向
调用方式的不同决定了this 的指向不同,一般指向我们的调用者
调用方式 | this指向 |
---|---|
普通函数调用 | window |
构造函数调用 | 实例对象、原型对象里的方法指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
分析this指向
function foo(){
return this
}
var o={
name:'Jim',
func:foo
}
console.log(foo()===window) //true 对应第2种情况
console.log(o.func()===o) //true 对应第3种情况
更改this指向(call、apply、bind方法)
javascript 为专门提供了一些函数方法来处理函数内部 this 的指向问题,常用的有 bind()、call()、apply() 三种方法。
方法 | 说明 | 使用 |
---|---|---|
apply(obj,argArray) | 提供参数的方式是参数数组,函数返回值 | 借助Math对象实现数组最大值、最小值 |
call(obj,arg1,arg2,…) | 提供参数的方式是参数列表,函数返回值 | 做继承 |
bind(obj,arg1,arg2,…) | 可实现提前绑定的效果。在绑定时,还可以提前传入调用函数时的参数,返回指定this值和初始化参数改造的原函数拷贝 | 不调用函数,但是想改变this指向,比如改变定时器内部的this指向 |
//改变this指向
var Person={
name:'张三'
}
function method(a,b){
console.log(this)
console.log(a+","+b)
console.log(this.name)
console.log('---------------------')
}
method('a','b')
method.apply(Person,['a','b'])
method.call(Person,'a','b')
method.bind(Person,'a','b')() //必须得调用 否则就只是绑定了而已
对bind()方法再次理解:
//bind方法
function method(a,b){
console.log(this.name+a+b)
}
var name='张三'
method('1','2') //输出结果为张三12 该方法中this指的是window
var test=method.bind({name:'李四'},'3','4') //method方法绑定了{name:'李四'}对象
test() //method中的 this 指向就是{name:'李四'}的对象
继承
ES6之前并没有提供 extends 继承。可以通过构造函数+原型对象模拟实现继承,被称为组合继承
构造函数实现继承父类属性
原理: 通过call()方法 将父类的this指向子类的this,这样就可以实现子类继承父类的属性
// 利用构造函数继承父类属性 (ES5)
function Father(name, age) {
this.name = name
this.age = age
}
function Son(name, age, score) {
Father.call(this, name, age) //子类继承父类属性
this.score = score
}
var son = new Son('张三', 20, 90)
console.log(son) //输出结果:Son {name: "张三", age: 20, score: 90}
ES6中继承父属性
// 使用super继承(ES6)
class Father {
constructor(name, age) {
this.name = name
this.age = age
}
}
class Son extends Father {
constructor(name, age, score) {
super(name, age)
this.score = score
}
}
var son = new Son('张三', 20, 90)
console.log(son) //输出结果:Son {name: "张三", age: 20, score: 90}
原型对象实现继承父类方法
一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类方法。 可将父类的实例对象作为子类的原型对象来使用
核心原理:
- 将子类所共享的方法提取出来,让子类的 prototype 原型对象 = new 父类()
- 本质:子类原型对象等于是实例化父类,因为父类实例化之后另外开辟空间,就不会影响原来父类原型对象
- 将子类的 constructor重新指向子类的构造函数
// 使用原型对象继承父方法(ES5)
function Father() { }
Father.prototype.money = function () { //通过原型对象给Father添加一个money匿名函数
console.log(1000)
}
function Son() { }
Son.prototype = new Father() //将父类的实例对象作为子类的原型对象
Son.prototype.constructor = Son //将原型对象的constructor属性指向子类
Son.prototype.exam = function () {
console.log(10000)
} //为子类增加exam()方法
new Son().money() //调用父类money()方法 输出结果:1000
new Father().exam() //输出结果:报错 Uncaught TypeError: (intermediate value).exam is not a function
console.log(Father.prototype.exam) //子类不影响父类,父类原型对象没有exam 输出结果:undefined
ES6中继承父方法
// ES6 继承父方法
class Father {
constructor(name, age) {
this.name = name
this.age = age
}
money = function () {
console.log(1000)
}
}
class Son extends Father {
constructor(name, age, score) {
super(name, age)
this.score = score
}
exam = function () {
console.log(10000)
}
}
new Son().money() //输出结果:1000
new Father().exam() //输出结果:报错 Uncaught TypeError: (intermediate value).exam is not a function
错误处理
try catch处理
//错误处理
try{
var o={}
o.fun()
console.log("hello") //如果前面代码出错,这行不会被执行
}catch(e){ //捕获错误 e表示错误对象
console.log(e) // 打印的是对象 结果是:TypeError: o.fun is not a function
console.log(e.message) // 打印的是对象的成员 结果是: o.fun is not a function
}
console.log("hello") //如果错误被处理会执行,不会终止程序的运行 会输出:hello
throw抛出错误对象
//抛出错误对象
try{
var e1=new Error('错误信息') //创建错误对象
throw e1 //抛出错误对象
}catch(e){
console.log(e.message) //输出错误信息
console.log(e1===e) //输出:true 判断e1和e是否为同一对象
}
错误类型
类型 | 说明 |
---|---|
Error | 表示普通错误,其余6种类型的错误对象都继承自该对象 |
EvalError | 调用eval()函数错误,已经弃用,为了向后兼容,低版本还可以使用 |
RangeError | 数值超出有效范围,如“new Array(-1)” |
ReferenceError | 引用了一个不存在的变量,如“var a = 1; a + b;”(变量b未定义) |
SyntaxError | 解析过程语法错误,如“{ ; }”“if()”“var a = new;” |
TypeError | 变量或参数不是预期类型,如调用了不存在的函数或方法 |
URIError | 解析URI编码出错,调用encodeURI()、escape()等URI处理函数时出现 |
以上是关于JavaScript this指向ES5组合继承(构造函数+原型对象)错误处理的主要内容,如果未能解决你的问题,请参考以下文章