面向对象.

面向对象

概述:

面向对象是一种编程思维(oop),他的核心就是找有对应方法的对象做对应的事情(万物皆对象 (万物都可以被当作对象))

示例

需求:我想泡个脚

面向过程的思维:(按照对应的步骤走)

1.准备一个盆

2.烧水

3.把水倒入盆中

4.脱鞋子

5.泡脚

面向对象的思维:(找一个会做事情的对象去做)

去洗脚城(找个技师)

面向对象的核心 对象(将一切不是动作的内容抽取为属性一切是动作的行为抽取为方法

对象的创建

第一种通过构造方法创建(new关键词)
构造方法是什么

构造方法是一个方法(函数)他是一个匿名函数 他的名字就是你对应class的名字(首字母大写)

//构造函数创建 new关键词 构造函数的首字母必须大写
function Person(){
    console.log(this);
}
//class的写法 其实他的底层就是上面的构造函数
// class Person{
//     //构造函数
//     constructor(){
//         console.log(this);
//     }
// }
//对象实例的创建
var person = new Person()
person.name = "hello"
第二个使用工厂方法模式创建
//工厂方法模式 (设计模式 类似于一个复用工厂 出产对应的对象 Object是属于对象超类 所有对象默认都继承Object)
function factor(name){
    //准备一个对象
    var obj = new Object()
    //将所有要设置的属性 设置给这个对象
    obj.name = name
    //将这个对象返回
    return obj
}
var person1 = factor("jack")
console.log(person1);
第三种创建 使用字面量
var person = {
	name:'tom',
	age:18,
	eat(){
		console.log("吃饭")
	}
}
总结
构造函数创建的过程
  • 自动创建对象
  • 手动添加属性
  • 自动返回对象
工厂方法创建的过程
  • 手动创建对象
  • 手动添加属性
  • 手动返回对象

细讲一下构造函数

特性:

1.首字母必须大写

2.和普通的函数没有区别(可以自由传值 以及可以指定默认参数)

function Person(name="tom",age){
	this.name = name //this指向用户实例 person.name = name
	this.age = age //相当于perosn.age = age
    this.sayHi = function(){ //perosn.sayHi
        console.log('Hi')
    }
}
var person = new Person('jack',18)//创建对象实例
person.sayHi()

3.需要new关键词修饰(如果没有参数可以省略后面的括号)

function Person(){
	
}
var person = new Person //可以省略对应的括号
示例(汽车的对象)
//汽车的构造
function Car(name,color,price){
    this.name = name
    this.color = color
    this.price = price
    //跑的方法
    this.run = function(){
        console.log(`我开着${this.price}${this.color}${this.name}在跑`)
    }
}
var car = new Car('二手五菱宏光','金色',300)
var car1 = new Car('兰博基尼','金色',28888888)
car.run()
car1.run()
//false 这个里面new俩个对象 开辟了俩个内存 这个俩个内存里面的数据是不是分别开辟的内容
console.log(car.run == car1.run);

经过上述代码我们发现对应的一个对象在new的时候 会重新开辟一个新的内存空间 在这个时候里面的属性和方法都会被重新开辟一个空间来存储,所以就导致我们对应的俩个对象的方法的指向是不一样的(俩个方法存在着俩个内存空间)这个时候就会产生一个资源浪费的问题。

为了解决这个问题 就产生了一个内容叫做原型。

所以在这个时候我们就明白了原型中一般存储方法。

原型

prototype

概述:prototype是每一个函数都有的一个空间(对象),里面就可以存放一些内容了

function test(){
	
}
console.log(test.prototype)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkIvqxOG-1655896099013)(C:\Users\29769\AppData\Roaming\Typora\typora-user-images\image-20220620152938595.png)]

constructor

这个会指向对应的对象的构造函数,相对构造函数本身

prototype拥有的方法

hasOwnProperty 返回一个boolean类型的值 判断当前的对象上是否存在对应的属性

// hasOwnProperty 判读当前的对象上是否具备对应的属性
function Person(){

}
Person.prototype.hello = 'jack'
var person = new Person()
person.name = 'hello'
// console.log(Person.prototype.hasOwnProperty());
console.log(person.hasOwnProperty('hello')); //false 
console.log(person.hasOwnProperty('name')); //true

isProtoTypeOf 返回一个boolean类型的值 判断当前的对象是否处在对应的原型链上

//isPrototypeOf
// object 参数是 Object 类型的一个对象,将对其原型链进行检查。
// console.log(Person.prototype.isPrototypeOf());
console.log(Person.isPrototypeOf(person)); //false
  • 因为对应的构造函数也是一个函数 所以他同样具备这个内存空间(prototype)

  • prototype是属于我们的构造函数的

因为对应的构造函数有这个内存空间(对象)所以我们可以往这个对象里面设置属性和方法

//构造函数
function Person(){

}
//构造函数的原型prototype
Person.prototype.name = 'jack'
Person.prototype.sayHello = ()=>{
    console.log('hello')
}
//当前person实例会自动读取到原型中的内容
var person = new Person()
//打印的属性是原型中的
console.log(person.name) //jack
//原型中的方法
person.sayHello()

通过对应的对象实例.属性名 可以访问到构造函数里面的prototype里面的值

console.log(person.sayHello == person1.sayHello);//true

那么通过上面的代码我们就知道构造函数的问题就被解决了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ec2IGsxS-1655896099014)(C:\Users\29769\AppData\Roaming\Typora\typora-user-images\image-20220620154635350.png)]

总结
  • 我们一般将对应的属性存储在构造方法里面
  • 将对应的方法存储在原型上
  • 存储在原型上的内容可以直接通过对象实例.去获取
对应的对象怎么去获取prototype里面的值呢 他如何来指向的呢
__proto__
概述:

所有的对象都具备一个属性__proto__ 这个也是一个对象空间

var obj = {

}
console.log(obj.__proto__)

那么同样的我们的实例化对象也是一个对象 所以他也存在对应的一个空间__proto__ 那么这个空间指向哪?

function Person(){

}
Person.prototype.name = "jack"
var person = new Person()
console.log(person.__proto__)
//我们的实例对象的__proto__和构造函数的prototype的指向是一致 这个俩个东西就是一个东西
console.log(person.__proto__ ==  Person.prototype)

经过上述我们发现对应的实例对象的__proto__和构造函数的prototype的指向是一致

在构造函数里面的我们是先编译出一个构造函数(函数在预编译阶段先加载)再自动生成一个对象(构造函数先诞生 对象后诞生)

经过上述的讲解我们知道 实例对象的__proto__指向对应构造函数的prototype的

所以我们往prototype存东西 我们可以通过实例对象的__proto__来获取 同样的我们也可以通过对应的实例对象的__proto__来设置数据进入到构造函数的prototype

function Person(){

}
Person.prototype.name = "jack" //往原型中存储数据
var person = new Person()
person.__proto__.age = '18' //往原型中存数据
var person1 = new Person()
console.log(person1.age)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xkhgktcb-1655896099016)(C:\Users\29769\AppData\Roaming\Typora\typora-user-images\image-20220620162213089.png)]

原型链

  • 构造函数的prototype是一个对象 里面可以存放的对应的数据(不会二次的开辟空间)
  • 实例对象的__proto__他指向对应的构造函数的prototype
  • 那么请问我们的构造函数是不是也是一个对象 那么他同时也具备对应的__proto__ 他的__proto__指向哪里?

那么这个就诞生了原型链

概述:

对象在原型(__proto__)上找属性的过程被称为原型链

Object.name = 'hello'
Object.prototype.username = 'hi'
function Person(){
	
}
Person.prototype = new Son()
Person.prototype.age = 18
function Son(){
	
}
var son = new Son()
var person = new Person()
console.log(son.name) //undefinde
console.log(person.name) //undefinde
console.log(son.age) //undefinde
console.log(person.age) //18
console.log(son.username) //hi
console.log(person.username) //hi

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lTH0dDN8-1655896099016)(C:\Users\29769\AppData\Roaming\Typora\typora-user-images\image-20220620170220816.png)]

总结
原型链找的过程
  • 先找自己的__proto__是否存在(构造函数的prototype)
  • 再找父类的__proto__是否存在 (构造函数的prototype)
  • 再找对应的父类,直到找到Object的__proto__为止 如果还找不到
  • 找到null 并且返回
原型链是会忽略对象的赋值的
  • 没有就创建这个属性
  • 有就更改这个属性
  • 他跟__proto__没有关系

我们在创建构造函数的时候会将对应的属性写在构造函数上 将方法写在原型上

写一个tab切换(面向对象)

H0dDN8-1655896099016)]

总结
原型链找的过程
  • 先找自己的__proto__是否存在(构造函数的prototype)
  • 再找父类的__proto__是否存在 (构造函数的prototype)
  • 再找对应的父类,直到找到Object的__proto__为止 如果还找不到
  • 找到null 并且返回
原型链是会忽略对象的赋值的
  • 没有就创建这个属性
  • 有就更改这个属性
  • 他跟__proto__没有关系

我们在创建构造函数的时候会将对应的属性写在构造函数上 将方法写在原型上

写一个tab切换(面向对象)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值