目录
一、对象的结构
二、原型
三、原型的作用
四、修改原型
五、instanceof 和 hasOwn
六、旧类
七、new运算符
八、对象总结
对象中存储属性的区域实际有两个:
1. 对象自身
- 直接通过对象所添加的属性,位于对象自身中
- 在类中通过 x = y 的形式添加的属性,位于对象自身中
2. 原型对象(prototype)
- 对象中还有一些内容,会存储到其他的对象里(原型对象)
- 在对象中会有一个属性来存储原型对象,这个属性叫做_ _proto_ _
- 原型对象也负责为对象存储属性,
当我们访问对象中的属性时,会优先访问对象自身的属性,
对象自身不包含该属性时,才会去原型对象中寻找
(也就是当对象自身和原型对象中含有同一个属性名时,会访问对象自身中的该属性)
- 会添加到原型对象中的情况:
1. 在类中通过xxx(){ }方式添加的方法,位于原型中
2. 主动向原型中添加的属性或方法
访问一个对象的原型对象: 对象._ _proto_ _(开头是下划线或者其他特殊的表示不希望被访问的)
或 Object.getPrototypeOf(对象) (更安全)
原型对象中的数据:
1. 对象中的数据(属性、方法等)
2. constructor (对象的构造函数,也就是对象所在的类)
注意:原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同,如在下面代码中的p对象和obj对象的原型链长度就不同:
p对象的原型链:p对象 --> 原型 --> 原型 --> null
obj对象的原型链:obj对象 --> 原型 --> null
原型链:读取对象属性时,会优先读取对象自身属性
如果对象中有,则使用,没有则去对象的原型中寻找
如果原型中有,则使用,没有则去原型的原型中寻找
直到找到Object对象的原型(Object的原型没有原型(为null))
如果依然没有找到,则返回undefined
注意:
作用域链,是找变量的链,找不到会报错;
原型链,是找属性的链,找不到会返回 undefined 。
所有的同类型对象它们的原型对象都是同一个
也就意味着,同类型对象的原型链是一样的
原型的作用:
原型就相当于是一个公共的区域,可以被所有该类实例访问,可以将一个该类实例中所有的公共属性(方法)统一存储到原型中,这样我们只需要创建一个属性,即可被所有实例访问。
JS的继承就是通过原型来实现的
当继承时,子类的原型就是一个父类的实例
在对象中有些属性值是对象独有的,像属性(name, age , gender)每个对象都应该有自己的值
但是有些值对于每个对象来说都是一样的,像各种方法,对于一样的值没必要重复的创建
尝试:
函数的原型链是什么样的?
Object的原型链是什么样的?
大部分情况下不需要修改原型对象
注意:千万不要通过类的实例去修改原型
原因:1.通过一个对象影响所有同类对象,这么做不合适
2.修改原型先得创建实例,这么做麻烦
3.危险
除了通过__proto__能访问对象的原型外,
还可以通过类的prototype属性,来访问实例的原型
修改原型时,最好通过类去修改
好处:
1. 一修改就是修改所有实例的原型
2. 无需创建实例即可完成对类的修改
原则:
1. 原型尽量不要手动改
2. 要改也不要通过实例对象去改
3. 通过 类. prototype 属性去修改
4. 最好不要直接给 prototype 去赋值
Instanceof 用来检查一个对象是否是一个类的实例
- instanceof 检查的是对象的原型链上是否有该类实例
只要原型链上有该类实例,就会返回true
- Object 是所有对象的原型,所以任何对象和Object 进行 instanceof 运算都会返回 true
in
- 使用 in 运算符检查属性时,无论属性在对象自身还是在原型中,都会返回true
对象.hasOwnProperty(属性名)(不推荐使用)
- 用来检查一个对象的自身是否含有某个属性,现在不太用这种方法了
Object.hasOwn(对象,属性名)(推荐使用)
- 用来检查一个对象的自身是否含有某个属性
早期的JS中,直接通过函数来定义类
- 一个函数如果直接调用 xxx( ), 那么这个函数就是一个普通函数
- 一个函数如果通过new 调用 new xxx( ) 那么这个函数就是一个构造函数
等价于:class Person{ }
静态属性 Person.staticProperty = 'xxx'
静态方法 Person.staticMethod = function(){}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
- 当使用 new 去调用一个函数时,这个函数将会作为构造函数调用,
使用new调用函数时,将会发生这些事:
1.创建一个普通的JS对象(Object对象{ }),为方便,我们称其为新对象
2. 将构造函数的prototype属性设置为新对象的原型
3. 使用实参来执行构造函数,并且将新对象设置为函数中的 this
4. 如果构造函数返回的是一个非原始值,则该值会作为new 运算的返回值返回(千万不要这么做),
如果构造函数的返回值是一个原始值或者没有指定返回值,则新的对象将会作为返回值
通常不会为构造函数指定返回值
面向对象本质就是,编写代码时所有的操作都是通过对象来进行的。
面向对象的编程的步骤:
1.找对象
2.搞对象(对对象进行操作)
学习对象:
1. 明确这个对象代表什么,有什么用
2.如何获取到这个对象
3. 如何使用这个对象(对象中的属性和方法)
对象的分类:
内建对象
- 由ES标准所定义的对象,比如 Object Function String Number......
宿主对象
- 由浏览器提供的对象,如document
- BOM、DOM
自定义对象
- 由开发人员自己创建的对象
-