JavaScript面向对象(下)

目录

一、类的创建

1.ES5

2.ES6

(1)class类名

(2)类表达式

二、原型对象

三、原型链的结构特点

1.构造函数和原型对象

2.实例对象和原型对象

3.objec对象的__proto__属性是null

四、this指针的指向

1.构造函数内部的this指向新创建的对象(当前对象)

2.直接通过函数名调用函数时,this指向全局对象window

3.若将函数作为对象的方法调用,this指向该对象

五、更改this指针的指向

1.apply方法

2.call方法

3.两个方法的区别

六、bind函数

七、JavaScript代码错误处理(异常处理)

1.try

2.throw抛出错误对象

3.常见的错误类型

八、继承

1.ES6的继承:是单一继承(一个类的直接父类只能有一个)

         2.ES5的继承:通过原型对象实现(将父类的实例对象赋给子类的原型对象)

3.在原型链继承中实现方法的覆盖(Override)

实现方法:在子类的原型对象上添加和父类安全同名的方法

4.在继承过程中确定原型对象和实例对象之间关系的方法

(1)instanceof运算符:判断实例对象的类型

(2)isPrototypeOf()方法:判断原型对象的类型

5.原型链的问题

6.原型链问题的解决办法

(1)ES6中实现

(2)ES5中实现

九、类的实例化


一、类的创建

1.ES5

class 类名{
}

2.ES6

(1)class类名

class类名{
    构造函数([参数]){
        初始化成员变量
    }
    成员方法
}

(2)类表达式

var 变量名=class{
    构造函数([参数]){
        初始化成员变量
    }
    成员方法
}

二、原型对象

1.构造函数的原型对象:通过prototype属性访问

2.对象的原型对象:通过对象的__proto__属性访问

3.访问对象的构造方法:在原型对象中有constructor属性指向对象的构造方法

(1)构造方法名.prototype.constructor

(2)对象名.constructor

function Person(){}
console.log(Person.prototype.constructor) //输出[function:Person]
var p1 = new Person()
console.log(p1.constructor) //输出[function:Person]
function Person(){} //原构造方法
var p2 = new Person()
console.log('p2:',p2.constructor) //输出[function:Person]
//给原型对象赋予一个新的对象
Person.prototype = { //原型对象的构造方法改变了
    sayHello:function(){
        console.log('Hello World')
    }
}
var p1 = new Person() //调用新的构造方法实例化一个对象p1
console.log('p1:',p1.constructor) //输出[Function: Object]

4.原型对象的原型对象:原型对象本身也是一个对象,所有它也有一个原型对象

(1)获取原型对象的原型对象:构造方法名.prototype.__proto

(2)原型对象的原型对象构造方法:.prototype.__proto.constructor

ps:

A.JavaScript中的所有类都直接或间接的继承自object

B.所有的对象都是通过构造方法生成的

三、原型链的结构特点

1.构造函数和原型对象

构造函数------(prototype)------->原型对象

原型对象------(constructor)------->构造函数

2.实例对象和原型对象

实例对象------(__proto__)------>实例对象

构造方法------(new)------>实例对象

3.objec对象的__proto__属性是null

function Person(){
    this.name = '张三'
}
Person.prototype.name = '李四'
var p = new Person()
console.log(p.name) //输出:张三
delete p.name //删除对象p的name成员
console.log(p.name) //在p对象的原型对象中查找name成员,输出:李四
delete Person.prototype.name //删除原型对象的name成员
console.log(p.name) //不存在,输出undefined
//给内置对象array的原型对象添加sum方法:用来求数组元素之和
Array.prototype.sum = function(){
    let sum = 0
    for(let i=0;i<this.length;i++){
        sum += this[i]
    }
    return sum
}

//声明数组
var arr = [12,25,38,75]
console.log('数组元素之和:',arr.sum())

四、this指针的指向

1.构造函数内部的this指向新创建的对象(当前对象)

Function Person(){
    this.name = ‘AA’
}
var p1 = new Person()\
var p2 = new Person()

2.直接通过函数名调用函数时,this指向全局对象window

function sayHello(){
    return this
}
var t = sayHello()

3.若将函数作为对象的方法调用,this指向该对象

function Student(n,s){
    this.name = n
    this.sex = s
    this.display = function(){
        console.log(‘姓名:’+this.name+ ‘\n性别:’+this.sex)
    }
}
var s1 = new Student(‘张飞’,‘男’)
s1.display() //通过对象名调用函数,此时

五、更改this指针的指向

1.apply方法

2.call方法

3.两个方法的区别

(1)在调用函数时,第一个参数默认是对象

(2)apply除第一个参数外,后面参数打包成数组进行传递

(3)call方法:除第一个参数外,后面的参数一个一个的传递

六、bind函数

实现提前绑定,在绑定时提前传入调用函数的参数

function method(a,b){
    console.log(this.name+a+b)
}
var name = '张三'
var test = method.bind({name:'李四'},'3','4')
test()

七、JavaScript代码错误处理(异常处理)

1.try

try{
    可能会出现错误的代码
}catch(e){  //e代表错误类型,名称可变
    捕获到错误后的处理代码
}
var o = {}
try {
    o.func() //出现错误:对象o没有func成员
    console.log('AAAAA') //不执行,因为上一条语句错误
} catch (e) {
    console.log(e) //执行:打印错误的类型及其详细信息
                   //TypeError是错误类型,o.func is not a function是错误信息
}
console.log('test') //执行:前一天语句的错误已经被try-catch捕获并处理了,不影响该语句的执行

2.throw抛出错误对象

try {
    let e1 = new Error('错误信息') //创建错误对象,error是内置的错误类
    throw e1 //抛出错误对象e1
} catch (error) { //catch捕获throw抛出的错误对象额e1,将e1赋给参数error
    console.log(error.message) //输出错误对象的信息
}

3.常见的错误类型

(1)Error:普通错误。是其他错误对象的基类(其他对象错误都是继承Error)

(2)TypeError:变量或函数的参数出现类型错误

(3)SyntaxError:语法错误

(4)RangError:数值超出有效的范围

(5)URIError:解析URI编码出错

URI:统一资源标识符()

URL:全球资源定位器()

八、继承

1.ES6的继承:是单一继承(一个类的直接父类只能有一个)

class 子类名 extends 父类名
{
    构造方法
    成员方法
}

2.ES5的继承:通过原型对象实现(将父类的实例对象赋给子类的原型对象)

//通过原型链实现继承

//1.定义父类
function SuperType(){
    this.property = '中国人民银行'
}

//2.给supertype的原型对象添加方法
SuperType.prototype.getSuperValue = function(){
    return this.property
}

//3.定义子类构造方法
function SubType(){
    this.subProperty = '中国工商银行'
}

//4.实现subtype对supertype的继承
SubType.prototype = new SuperType() //通过原型对象实现子类对父类的继承

//5.在子类的原型对象上增加一个方法
SubType.prototype.getSubValue = function(){
    return this.subProperty
}

//6.创建一个子类的实例对象
let sub = new SubType()
console.log('调用父类的方法:',sub.getSuperValue()) //子类的实例对象用父类的方法
console.log('调用子类的方法:',sub.getSubValue())

3.在原型链继承中实现方法的覆盖(Override)

子类的方法名和父类的方法同名时,子类方法就覆盖了父类方法

实现方法:在子类的原型对象上添加和父类安全同名的方法

SubType.prototype.getSuperValue = function(){
    return '中国建设银行'
}

4.在继承过程中确定原型对象和实例对象之间关系的方法

(1)instanceof运算符:判断实例对象的类型

console.log(sub instanceof Object) //true
console.log(sub instanceof SuperType) //true
console.log(sub instanceof SubType) //true

(2)isPrototypeOf()方法:判断原型对象的类型

console.log(Object.prototype.isPrototypeOf(sub)) //true
console.log(SuperType.prototype.isPrototypeOf(sub)) //true
console.log(SubType.prototype.isPrototypeOf(sub)) //true

5.原型链的问题

(1)若原型中包含引用值,则该引用值会在所有的实例对象中共享。这是属性放在构造方法中定义而不放在原型对象中定义的原因

function Father(){
    this.colors = ['red','blue','green'] //colors属性的值是引用值(数组)
}
function Son(){}
//通过原型链的继承
Son.prototype = new Father() //本质:Son的原型对象是Father的实例对象

var s1 = new Son //创建子类的实例对象
s1.colors.push('black') //给属性colors添加已告知black
console.log('s1的colors:',s1.colors)

var s2 = new Son()
console.log('s2的colors:',s2.colors)

(2)子类的实例对象不能给父类的构造方法传参

6.原型链问题的解决办法

盗用父类构造方法(又称“对象伪造”或“经典继承”),基本思路是在子类构造方法中调用父类构造方法

(1)ES6中实现

class Father{ //父类
    constructor(name){
        this.name = name
    }
    show(){
        console.log('姓名:',this.name)
    }
}
class Son extends Father{ //子类
    constructor(name){
        super(name) //在子类构造方法中调用父类构造方法(经典继承,对象伪造)
    }
}

(2)ES5中实现

function Father(name){
    this.name = name
    this.colors = ['red','blue','green']
    this.show = function(){
        console.log('姓名:',this.name)
    }
}
function Son(subname){
    Father.call(this,subname) //继承父类,在子类构造方法中通过call函数调用父类构造方法
}
let s1 = new Son('刘备')
s1.colors.push('black')
s1.show()
console.log(s1.colors) //输出:[ 'red', 'blue', 'green', 'black' ]

let s2 = new Son('诸葛亮')
s2.show()
console.log(s2.colors) //输出:[ 'red', 'blue', 'green' ]

九、类的实例化

使用new运算符创建实例对象的过程。在使用new运算符调用类的构造方法时会执行的操作

1.在内存中创建新对象:即给该对象分配一块存储区

2.在该新对象内部的[protptype]指针会指向构造函数的constructor属性

3.构造函数内部的this指针指向该新对象

4.执行构造函数内部的代码(给新对象添加属性和方法)

5.如果构造函数返回非空对象则返回该对象;否则返回刚创建的新对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值