BCSP-玄子前端开发之JavaScript+jQuery入门CH06_JavaScript面向对象

BCSP-玄子前端开发之JavaScript+jQuery入门CH06_JavaScript面向对象

4.6 对象

4.6.1 什么是对象

对象是相关属性和方法的集合体

  • 属性
  • 方法

String对象

  • length 属性
  • indexOf()
  • replace() 方法

Array对象

  • length 属性
  • sort()
  • concat()
  • join() 方法

Date对象

  • get×××:获取年、月、日、时、分、秒等等
  • set×××:设置年、月、日、时、分、秒等等

Math对象

  • round()
  • max()
  • min() 方法

Boolean对象

  • toString() 方法

RegExp对象

  • compile()
  • exec()
  • test() 方法

4.6.2 创建对象

  • 内置对象
  • 自定义对象

4.6.3 创建常见内置对象

String 对象

  • 字符串
  • new String()

Date 对象

  • new Date()

Array 对象

  • [ element0, element1, …, elementN ]
  • new Array()

Math 对象

  • 所有属性和方法都是静态的

Boolean 对象

  • new Boolean()

RegExp 对象

  • new RegExp()

4.6.4 创建自定义对象

基于Object对象创建自定义对象

var 对象名称 = new Object();

通过点操作符(.)为其添加属性和方法

var student = new Object();
student.name = "张三";
student.age = 18;
student.email = "zhangsan@163.com";
student.hobby = "打球";
student.showName = function() { alert( this.name ); }
student.showName();

使用字面量赋值方式创建自定义对象

var student = {
     name : "张三",
     age : 18,
     email : "zhangsan@163.com",
     hobby : "打球",
     showName : function() {
              alert( this.name );
     }
 }
student.showName();

4.7 简单工厂模式

基于Object对象或使用字面量创建对象,如需批量创建对象,会产生大量重复代码

使用简单工厂模式封装对象的创建逻辑

  • 模式是指在某一环境下某个问题的一种解决方案
  • 简单工厂模式是一种用来创建对象的软件设计模式

4.7.1 演示

将对象的创建逻辑封装在一个函数中

function createStudent( name, age, email, hobby ) {
        var p = new Object();
        p.name = name;
        ……
        p.showName = function() { alert( this.name ); }
        return p;
}

使用工厂函数创建对象

var person1 = createStudent("张三", 18, "zhang3@163.com", "打球");
person1.showName();
var person2 = createStudent("李四", 19, "lisi@163.com", "看书");
person2.showName();

4.8 构造函数

前述创建对象的方法无法区分不同类型的对象

4.8.1 定义构造函数

用以创建特定类型的对象

function Student( name, age, email, hobby ) {
            this.name = name;
            ……
            this.showName = function() { alert(this.name); }
}

4.8.2 与工厂函数相比

  • 没有显式创建Object对象,没有return语句
  • 将属性和方法赋给this对象

4.8.3 使用构造函数创建对象

var stu1 = new Student( "张三", 18, "zhangsan@163.com", "打球" );
stu1.showName();
var stu2 = new Student( "李四", 19, "lisi@163.com", "看书" );
stu2.showName();

4.8.4 构造函数执行过程

构造函数执行过程中会经历以下4个步骤

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象,因此this就指向了这个新对象
  3. 执行构造函数中的代码,为这个新对象添加属性及方法
  4. 返回新对象

4.8.5 constructor属性和

对象中包含constructor属性,指向其构造函数

alert( stu1.constructor == Student );  // 结果为true
alert( stu2.constructor == Student );  // 结果为true

4.8.6 instanceof操作符

使用instanceof操作符检测对象类型

alert( stu1 instanceof Student );  // 结果为true
alert( stu2 instanceof Student );  // 结果为true

stu1和stu2同是Object类型,所有对象都继承自Object

alert( stu1 instanceof Object );  // 结果为true
alert( stu2 instanceof Object );  // 结果为true

4.8.7 构造函数问题分析

构造函数的定义方式会导致showName()方法在每个实例上都要重新创建一遍

function Student( name, age, email, hobby ) {
            ……
            this.showName = function() { alert(this.name); }
}

通过函数定义的方式把showName()方法转移到构造函数的外部,所有实例共享全局作用域中定义的同一个showName()函数

function Student( name, age, email, hobby ) {
            ……
            this.showName = showName
}
function showName() { alert(this.name); }

全局函数实际上仅为某个对象调用,全局函数破坏了自定义类型的封装性


4.9 原型对象

每个函数都有一个prototype属性,指向其原型对象

使用原型对象方式添加属性和方法,所有实例会共享它所包含的属性和方法

构造函数名.prototype.属性或方法
function Student() {}
Student.prototype.name = "张三";
……
Student.prototype.showName = function() { alert(this.name); };
……

当实例读取某个属性时

  • 首先在实例本身开始搜索,找到则返回
  • 如没有找到,则继续在原型对象中查找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-59hCbbw2-1682304866455)(./assets/image-20230423214211000.png)]


4.10 继承

  • 原型链
  • 对象继承

4.10.1 原型链

一个类型的实例是另一个类型的原型对象,相关的原型对象层层递进,构成了实例与原型的链条,即原型链

function Person() { this.foot = 2; }
Person.prototype.getFoot = function() { return this.foot; }

function Woman() { this.head = 1; }
Woman.prototype = new Person();
// 继承了Person
Woman.prototype.getHead = function() { return this.head; }

var woman1 = new Woman();
alert(woman1 instanceof Woman); //true
alert(woman1 instanceof Person);  //true
alert(woman1 instanceof Object);   //true
alert(woman1.getFoot()); //2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ck5uG8DX-1682304866458)(./assets/image-20230423214422125.png)]

woman1调用getFoot()的步骤

  1. 搜索实例
  2. 搜索Woman.prototype
  3. 搜索Person.prototype

搜索的过程要一环一环地前行到原型链的末端才会停下来

4.10.2 完整的原型链

所有函数的默认原型都是Object对象的实例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTDUxUOj-1682304866458)(./assets/image-20230423214512202.png)]

4.10.3 方法重写

子类型可以通过prototype对象重写父类型中的方法

function Person() { this.foot = 2; }
Person.prototype.getFoot = function() { return this.foot; }

function Woman() { this.head = 1; }
Woman.prototype = new Person();
Woman.prototype.getHead = function() { return this.head; }

Woman.prototype.getFoot = function() { return false; }
……

4.11 对象继承

function Person() {
    this.skinColor = [ "black", "white" ]; // 肤色
}
function Woman() {}
Woman.prototype = new Person(); // 继承了Person

var woman1 = new Woman();
woman1.skinColor.push( "yellow" );
alert(woman1.skinColor); // 输出什么?

var woman2 = new Woman();
alert(woman2.skinColor); // 输出什么?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xro1zHPd-1682304866458)(./assets/image-20230423214607121.png)]

问题1:两个实例输出的信息一样,为什么?

问题2:创建子类型的实例时,不能向父类型的构造函数中传参

4.11.1 借用构造函数

借用构造函数又被称为伪造对象或经典继承,指在子类型构造函数的内部调用父类型的构造函数

应用某一对象的一个方法,用另一个对象替换当前对象

apply( [ thisOjb [, argArray ]] )

调用一个对象的一个方法,以另一个对象替换当前对象

call( [ thisObj [, arg1 [, arg2 [,[, argN ]]]]] )
function Person() {
    this.skinColor = [ "black", "white" ]; // 肤色
}
function Woman() {
    Person.call(this); // 也可以使用apply()方法
    // 继承了Person
}
var woman1 = new Woman();
woman1.skinColor.push( "yellow" );
alert(woman1.skinColor); // 输出什么?
var woman2 = new Woman();
alert(woman2.skinColor); // 输出什么?

借用构造函数可以在子类型构造函数中向父类型构造函数传参

function Person(name) {
    this.name = name;
}
function Woman(){
    Person.call( this, "amy" );
    this.age = 18;
}
……

为了确保父类型构造函数不会重写子类型的属性,可以在调用父类型构造函数后再添加应该在子类型中定义的属性

4.11.2 组合继承

组合继承也叫做伪经典继承

  • 将原型链和借用构造函数的技术组合到一块,融合二者的优点并规避二者的缺陷,是JavaScript开发中最常用的一种继承模式
  • 使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承
  • 既实现了函数复用,又能够保证每个实例都有自己的属性
function Person(name) {
    this.name = name;
    this.skinColor = [ "black", "white" ]; // 肤色
}
Person.prototype.sayName = function () { alert(this.name); }

function Woman(name, age) {
    Person.call(this, name); // 继承属性
    this.age = age;
}
Woman.prototype = new Person(); // 继承方法
Woman.prototype.sayAge = function () { alert(this.age); }
……

BCSP-玄子前端开发之JavaScript+jQuery入门CH06_JavaScript面向对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值