原型+构造函数+面向对象

面向对象

编程思想

1、面向过程:面向过程思想强调的是步骤,当碰见问题时,思考的是“我该怎么做”,分析出解决问题所需的步骤,一步步的去实现。

2、面向对象:面向对象思想强调的是对象,当碰见问题时,思考的是“我该让谁来做”。这个“谁”其实就是对象。找合适的对象做合适的事情。而对象如何去做(采用什么样的步骤)我们就不关心了,最终把问题解决掉就可以了。

面向过程是动作的执行者,面向对象是动作的指挥者

相关概念:

var 对象 = {
    key1: value1,
    key2: value2,
    ...
}

1、对象:无序的名值对

2、对象组成

  • 1、属性:对象的特征描述,静态,名词(不是函数的就是属性)
  • 2、方法:对象的行为,动态(函数就是方法)

3、对象的基本特征:封装、继承、多态(了解)

4、类和实例

  • 类:类是对象的类型模板
  • 实例:实例是根据类创建的对象
  • 面向对象学习,就是学习创建类(模板),利用类生成实例(月饼)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tWOgO11u-1631802427240)(img/类和实例.jpg)]

对象的读写

var obj = {
    name: 'zs',
    age: 3,
    dd: undefined,
    fn: function () {
        console.log('前端开发');
    }
}

// -----------------------------------
// 读
console.log(obj.name);
console.log(obj['age']);

// -----------------------------------
// 写
obj.name = 'ls';
obj['sex'] = '男';
console.log(obj);

// -----------------------------------
// 遍历
for (var attr in obj) {
    console.log(attr, '------', obj[attr]);
}

// -----------------------------------
// in操作符:判断对象是否有这个属性,返回布尔值
// 格式:'key' in 对象
console.log('name' in obj); // true
console.log('sex' in obj); // true
console.log('dd' in obj); // true
console.log('zz' in obj); // false

// -------------------------------
// 删除对象的属性
// 格式:delete 对象.属性
delete obj.name;
console.log(obj);

面向对象创建

字面量创建
// 字面量创建:其实就是 json 形式的对象,适用于创建单个对象。
// 不足:这种创建方式,适用于单个对象的创建,如果要创建多个对象,会代码冗余。

var obj1 = {
    name: 'zs',
    age: 3,
    fn: function () {
        console.log('前端开发');
    }
}

var obj2 = {
    name: 'ls',
    age: 2,
    fn: function () {
        console.log('前端开发');
    }
}
实例创建
// 实例创建
// 不足:想创建一个类似的对象,就会产生大量的代码

var obj1 = new Object();
obj1.name = 'zs';
obj1.age = 3;
obj1.fn = function () {
    console.log('前端开发');
}
console.log(obj1);




var obj2 = new Object();
obj2.name = 'ls';
obj2.age = 4;
obj2.fn = function () {
    console.log('前端开发');
}
console.log(obj2);
工厂模式
// 工厂模式,归根到底就是封装函数

function person(name, age) {
    // 1、准备原料
    var obj = new Object();

    // 2、生产
    obj.name = name;
    obj.age = age;
    obj.fn = function () {
        console.log('前端开发');
    }

    // 3、出厂
    return obj;
}


var p1 = person('zs', 3);
console.log(p1);

var p2 = person('ls', 4);
console.log(p2);

instanceof

// 工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例


// instanceof 运算符,一个对象是否为指定的构造函数的实例,返回布尔值
// 语法:实例 instanceof 构造函数;

console.log([] instanceof Array); // true
console.log([] instanceof Object); // true

console.log(p1 instanceof person); // false
console.log(p1 instanceof Object); // true
构造函数模式
构造函数的特点:

构造函数的特点:

1、构造函数名首字母大写(为了区分普通函数,不是必须,是约定)

2、构造函数方法没有显示的创建对象(new Object())

3、直接将属性和方法赋值给 this 对象

4、没有 return 语句,不需要返回对象

5、通过构造函数创建对象,必须使用 new 运算符(直接调用跟普通函数一样)

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.fn = function () {
        console.log('前端开发');
    }
}
functioin Person (name,age) {
    this.name = name;
}
new Person;
构造函数通过new调用

构造函数通过new调用,会经历四步

(1) 创建一个新对象;

(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);

(3) 执行构造函数中的代码(为这个新对象添加属性);

(4) 返回新对象(隐式的)。

var p1 = new Person('zs', 3);
console.log(p1);
// console.log(p1.name);
// p1.fn();

var p2 = new Person('ls', 4);
console.log(p2);

// var p3 = Person('ww', 5); // 如果不通过new调用,属性加给了window,且没有返回值

// ---------------------------------------
// 构造函数创建解决了 instanceof 识别问题
console.log(p1 instanceof Person); // true
console.log(p1 instanceof Object); // true

// ------------------------------------
// 构造函数创建对象问题:一样的函数会存在多次创建的问题,占用内存空间
// 解决:原型创建对象
alert(p1.fn)
alert(p2.fn)
console.log(p1.fn == p2.fn); // false

对象的比较

// 基本类型:基本类型的比较是值的比较
var a = 3;
var b = 3;
console.log(a == b); // true


// 引用类型:引用类型的比较,是地址的比较
console.log([] == []); // false
console.log(function () { } == function () { }); // false
原型创建对象 (原型与原型链)

1、原型:js每声明一个function,都有prototype原型,prototype原型是函数的一个默认属性,在函数的创建过程中由js编译器自动添加。

也就是说:当生产一个function对象的时候,就有一个原型prototype。原型中存储对象共享的属性和方法。

2、原型链:当查找对象的属性的时候,先找自身,如果自身没有,则找顺着__proto__找到原型,如果原型也没有,则继续向上找,一直找到Object的原型。这个查找这个链表就是原型链。

// 每声明一个函数,这个函数下面就有一个prototype的属性,它是这个构造函数创建这类实例的原型对象
// 原型对象:是存储这类实例共有属性和方法的地方。原型对象默认会有一个constructor属性,它又指向构造函数

var arr = new Array(); // 创建一个实例(arr就是实例,Array就是构造函数)

console.log(arr);

console.log(arr.__proto__); // 原型对象(通过实例访问)
console.log(Array.prototype); // 原型对象(通过构造函数访问)
console.log(arr.__proto__ == Array.prototype); // true

console.log(Array.prototype.constructor); // 原型对象下面有一个constructor属性,它又指向构造函数




// ---------------------------------------
// 每声明一个函数,它就默认会有一个prototype属性,这个属性里面有一个constructor属性,它又指向这个函数
function fn() { }
console.log(fn.prototype); // {constructor: ƒ}

在这里插入图片描述

原型链:

浏览器不显示 proto
浏览器显示 [[Prototype]]
proto= [[Prototype]]

图1
在这里插入图片描述

图2

在这里插入图片描述

图3
在这里插入图片描述

原型创建对象

function Person() { }

// console.log(Person.prototype); // {constructor: ƒ}
// console.log(Person.prototype.constructor); // Person

Person.prototype.name = 'zs';
Person.prototype.age = 3;
Person.prototype.fn = function () {
    console.log('前端开发');
}

// console.log(Person.prototype);

// -----------------------------------------
var p1 = new Person();
console.log(p1);
console.log(p1.name); // 'zs'
p1.fn();
console.log(p1.toString);

// 不足:不能传参,创建的人都是一样的
var p2 = new Person();
console.log(p2.name);

// -----------------------
// 原型创建解决了重复创建函数的问题
console.log(p1.fn == p2.fn); // true

在这里插入图片描述

6、混合模式创建对象
// 混合模式创建对象 (标准方法)
// 构造函数+原型方式
// 属性写在构造函数里面,方法写在原型上面
function Person(name, age) {
    this.name = name;
    this.age = age;
}

//Person.prototype.showName = function () {
//    console.log(this.name);
//}
//Person.prototype.showAge = function () {
//    console.log(this.age);
//}

Person.prototype = {
 // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
            constructor: Star, //地址变了,需要重新指回原地址
            showName: function() {
                console.log(this.name);
            },
            showAge: function() {
                console.log(this.age);
            }
        }

var p1 = new Person('zs', 3);
console.log(p1);
p1.showName();

var p2 = new Person('ls', 5);
console.log(p2);
console.log(p2.name);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-30Ey2EMz-1631802427250)(C:\Users\Administrator\Desktop\课堂笔记\第二阶段\笔记\image\混合模式创建对象.jpg)]

7、动态混合模式
// 动态混合模式:给人封装的感觉

function Person(name, age) {
    this.name = name;
    this.age = age;

    if (!Person.prototype.showName) {
        Person.prototype.showName = function () {
            console.log(this.name);
        }
        Person.prototype.showAge = function () {
            console.log(this.age);
        }
    }
}

var p1 = new Person('zs', 3);
console.log(p1);

var p2 = new Person('ls', 5);
console.log(p2);

面向对象实例

面向对象的选项卡

原则:先写出普通的写法,然后改成面向对象写法

1、普通方法变型

尽量不要出现函数嵌套函数

可以有全局变量

把onload中不是赋值的语句放到单独函数中(init)

2、改成面向对象()

​ 先写构造函数

onload中创建对象,并init调用

全局变量就是属性

函数就是方法

(属性和方法前面,都要加this)

改this指向问题(尽量让this指向对象)

结论:我们改成面向对象了之后,感觉是不是更复杂了?确实是这样,确实是更复杂了,但是我们这个面向对象特别适合复杂的开发,对于简单的,不太推荐使用面向对象。面对复杂开发时,它特别容易扩展,同时,复用性特别强。上面的例子,多添加几个,就可以发现特别方便复用和扩展。

n(‘zs’, 3);
console.log(p1);

var p2 = new Person(‘ls’, 5);
console.log(p2);






## 面向对象实例



**面向对象的选项卡**

原则:先写出普通的写法,然后改成面向对象写法

1、普通方法变型

尽量不要出现函数嵌套函数

可以有全局变量

把onload中不是赋值的语句放到单独函数中(init)

2、改成面向对象()

​	先写构造函数

onload中创建对象,并init调用

全局变量就是属性

函数就是方法

(属性和方法前面,都要加this)

改this指向问题(尽量让this指向对象)



**结论**:我们改成面向对象了之后,感觉是不是更复杂了?确实是这样,确实是更复杂了,但是我们这个面向对象特别适合复杂的开发,对于简单的,不太推荐使用面向对象。面对复杂开发时,它特别容易扩展,同时,复用性特别强。上面的例子,多添加几个,就可以发现特别方便复用和扩展。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值