JavaScript构造函数,原型对象原型链,this指向,错误处理
Posted 别Null.了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript构造函数,原型对象原型链,this指向,错误处理相关的知识,希望对你有一定的参考价值。
目录
构造函数
构造函数主要用来创建对象,并为对象的成员赋初始值。
//实例化对象
var p1 = new Person('张三', 18)
var p2 = new Person('李四', 19)
console.log(p1.name) // 输出结果:张三
console.log(p2.age) // 输出结果:19
p2.sing() // 输出结果:我会唱歌
//Person构造函数
function Person(name, age){
this.name = name;
this.age = age;
this.sing = function(){
console.log('我会唱歌')
}
}
构造函数和类的区别:
类中的成员方法是定义在类中的,使用类创建对象后,这些对象的方法都是引用了同一个方法,这样可以节省内存空间
静态成员和实例成员
实例成员是指实例对象的成员,而静态成员是指通过类或构造函数访问的成员。
function Person(uname){
this.uname = uname
}
Person.school = 'X大学'; // 添加静态属性school
Person.sayHello = function(){ // 添加静态方法sayHello
console.log('Hello')
}
console.log(Person.school) // 访问静态属性,输出结果:X大学
Person.sayHello(); // 访问静态方法,输出结果:Hello
原型对象
每个构造函数都有一个原型对象存在,这个原型对象通过构造函数的prototype属性来访问。
function Person(){} // 定义函数
console.log(Person.prototype) // 输出结果:{constructor: ƒ}
console.log(typeof Person.prototype) // 输出结果:object
例子:利用原型对象共享方法
function Person(uname){
this.uname = uname
}
Person.prototype.sayHello = function(){
console.log('你好,我叫' + this.uname)
}
var p1 = new Person('张三')
var p2 = new Person('李四')
console.log(p1.sayHello === p2.sayHello) // 输出结果:true
p1.sayHello() // 输出结果:你好,我叫张三
p2.sayHello() // 输出结果:你好,我叫李四
原型链
访问对象的原型对象
对象的原型对象:每个对象都有一个__proto__属性,这个属性指向了对象的原型对象。
实例对象与原型对象的关系:
访问对象的构造函数
对象的构造函数:在原型对象里面有一个constructor属性,该属性指向了构造函数。
例子:用赋值方式修改原型对象为新的对象,就无法访问构造器函数。
//用赋值方式修改原型对象为新的对象,就无法访问构造函数
function Person(){}
//修改原型对象为一个新的对象
Person.prototype = {
sayHello:function(){
console.log("hello")
}
}
var p1 = new Person() //使用实例对象p1可以访问新的原型对象中的属性
p1.sayHello()
console.log(p1.constructor) //使用constructor属性无法访问原来的构造函数
//constructor 属性返回对创建此对象的数组函数的引用,故输出为hello
构造函数、原型对象和实例对象之间的关系
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。 ——摘自《javascript高级程序设计》
原型对象的原型对象
原型对象的原型对象:原型对象也是对象,那么这个对象应该也会有一个原型对象存在。
例子:Person.prototype.__proto__这个对象其实就是Object.prototype对象
function Person(){}
console.log(Person.prototype.__proto__ === Object.prototype) // true
var obj = {}
console.log(obj.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__) // 输出结果:null
原型链
原型链结构特点
- 每个构造函数都有一个prototype属性指向原型对象。
- 原型对象通过constructor属性指向构造函数。
- 通过实例对象的__proto__属性可以访问原型对象。
- Object的原型对象的__proto__属性为null。
原型链结构图
函数在原型链中的结构
this指向
分析this指向
- 构造函数内部的this指向新创建的对象
- 直接通过函数名调用函数时,this指向的是全局对象window。
- 如果将函数作为对象的方法调用,this将会指向该对象。
更改this指向方法:apply()方法和call()方法
function method(){
console.log(this.name)
}
method.apply({ name: '张三' }) // 输出结果:张三
method.call({ name: '李四' }) // 输出结果:李四
apply()方法和call()方法的区别:
function method(a, b){
console.log(a + b)
}
method.apply({}, ['1', '2']) // 数组方式传参,输出结果:12
method.call({}, '3', '4') // 参数方式传参,输出结果:34
错误处理
通常用于不能直接得到代码错误原因及位置时。
try{ } catch(e){ }
var o = {}
try{ // 在try中编写可能出现错误的代码
o.func()
console.log('a') // 如果前面的代码出错,这行代码不会执行
}
catch(e){ // 在catch中捕获错误,e表示错误对象
console.log(e)
}
console.log('b') // 如果错误已经被处理,这行代码会执行
抛出错误对象
try{
var e1 = new Error('错误信息') // 创建错误对象
throw e1 // 抛出错误对象,也可以与上一行合并为:throw new Error('错误信息');
}
catch (e){
console.log(e.message) // 输出结果:错误信息
console.log(e1 === e) // 判断e1和e是否为同一个对象,输出结果:true
}
错误类型
类型 | 说明 |
---|---|
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指向,错误处理的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript构造函数,原型对象原型链,this指向,错误处理
Javascript 原型链之原型对象实例和构造函数三者之间的关系