JavaScript构造函数,原型对象原型链,this指向,错误处理

目录

构造函数

静态成员和实例成员

原型对象

原型链

访问对象的原型对象

原型对象的原型对象

原型链

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处理函数时出现

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别Null.了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值