JavaScript高级
程序员文章站
2022-05-08 15:57:56
...
[JavaScript高级]学习日志
面向对象与原型
一.两种编程思想
面向过程&面向对象
过程=====>亲历亲为 把大象装冰箱分几步
对象=====>找个对象,让对象去做这件事
!!!对象做这件事的时候,做法也是一步一步按步骤按过程来(面向过程)
因此 面向对象与面向过程并不矛盾,面向对象是面向过程的封装
二.面向对象(OOP)===>啥是对象???
- 对象是具体事物的抽象 一本书是对象 书不是对象
- 对象是属性和方法的集合(属性和方法统称为对象的成员)
- 万物皆对象
- js中的理解======>对象是一堆无序键值对的集合
三.如何创建对象?(四种方法)
一.通过使用构造函数new一个对象
var obj=new Object();
obj.name="dfg";
obj.age=20;
obj.sayHi=function(){
console.log("Hi")
}
问题:创建的对象添加属性各种东西贼麻烦,写一大堆? 如何解决?
二.对象字面量
var obj={
name:"lw",
age:30
}
好处:解决了写一大堆麻烦的问题===>但是 还有问题 一次只能创建一个?怎么解决?
三.工厂函数
function createPerson(name,age){
var obj={
name=name,
age=age
}
return obj
}
createPerson("lw",30) //直接调用即可
//可以批量创建了 但是 问题是 console.log的时候打印出来的是{}无法看到创建的是什么类!所以解决方法?
四.自定义构造函数
构造函数的特点?
1.首字母大写(规范 最好这样)
2.配合new来创建使用
function Person(){
this.name=name,
this.age=age,
this.sayHi=function(){
console.log("Hi")
}
}
//var p=new Person("lw",23)
//这样打印出来便可以直接看到创建的对象是什么类了
//问题:
//注意 复杂数据类型之间的判等比较比较的是地址是否相等
var p=new Person()
var p1=new Person()
p==p1
p.sayHi==p1.sayHi
//上面两表达式的值? 显然都是false 说明两个地址不相等 即两个方法不是同一个 但是 调用的结果也是一样的 因此 批量创建很多对象后会造成内存浪费的问题 每次创建对象后都要创建一个sayHi对象放到内存里
//解决思路?
//既然每次创建都要搞一个function 那么把function放到全局然后在构造函数里直接赋值就可以了 这样避免了内存浪费
//但是造成了新的问题 污染全局作用域 解决思路
//污染全局 那不让他是全局就可以了 因此可以创建一个对象,把function放到对象里 通过对象引用即可
至此完美解决四种创建对象方法的绝大部分问题,自定义构造函数还有一个问题,就是,每次都需要自己写一个类,然后构造函数中访问这个类的成员赋值,太麻烦
如何解决?
======>原型 每个函数都有一个原型(对象),并且实例对象(new出来的对象)可以直接访问原型里的方法
什么是原型?
四.原型
1.什么是原型(对象)
就是每个函数都有的一个属性(prototype)的值,这个值是一个对象(键值对的集合)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OViUwqWa-1570697474194)(C:\Users\Administrator\Desktop\js高级手写笔记\prototype.png)]
2.干吗用,里面有啥
装的是构造函数的方法
都是熟悉的配方 以前用过的
3.应用到自定义构造函数创建对象中
function Person() {}
Person.prototype.color = "lime";
Person.prototype.sayHi= function() {
console.log("Hi");
};
var p = new Person();
console.log(p.color);
p.sayHi()
//运行结果
//lime
//Hi
//因此 实例对象可以通过原型prototype直接访问对应构造函数的成员
//如何访问的??????
五.原型和原型链
要回答实例对象如何访问的prototype 就要涉及原型链的问题了
//在原型链之前 ,先介绍两个属性
__proto__和constructor
//1.__proto__
//每个对象都有这个属性 因此实例对象P也有
function Person(){}
var p=new Person();
p.__proto__ ==Person.prototype
//上表达式的值?
//执行结果为true 又对象之间判等比较的是地址,那么可以证明这俩是一个东西
//因此可以访问
//但是 注意的是 ie没有这个属性 这是浏览器的一个私有属性 因此不可以用__proto__来操作原型
//ie中实例对象如何访问的原型?
//constructor
function Person(){}
console.log(Person.prototype.constructor==Person)
//打印的结果为true 因此 原型的constructor属性值指向的便是构造函数
构造函数 实例对象 原型的关系
原型链(找祖宗的过程)
实例对象的原型链
实例对象有proto 有爸爸 构造函数也有对象有爸爸呀
属性操作原则
1.查找属性
先找自己有没有 自己没有再"proto"对应的原型找 再没有按照原型链向上找 找不到就莫得了
2.修改或添加属性
均为给实例自己添加或修改属性 无法修改原型里的成员