72. JavaScript - オブジェクト指向の概要
オブジェクト指向プログラミング (OOP)
1. プログラムは何をするものですか?
- プログラムは現実世界の抽象化です (写真は人々の抽象化です)
2. 主題は何ですか?
- プログラムに抽象化されると、オブジェクトになります。
- プログラムのテスト接続では、すべてがオブジェクトです
- モノは通常、データと機能の 2 つの部分で構成されます
- オブジェクトは、プロパティとメソッドの 2 つの部分で構成されます。
- 静的は属性、動的はメソッドです
- 物のデータはオブジェクトの中にあり、それが属性として反映されます
- 物事の機能はオブジェクトの中にあり、メソッドとして具現化されます
<script>
const five = {
name: "张三",
sleep(){
console.log(this.name+"在睡觉")
}
}
</script>
73、JavaScript - クラスの紹介
Object を使用してオブジェクトを作成する際の問題
1. 異なるタイプのオブジェクトを区別できない
2. オブジェクトをバッチで作成するのは不便です
JSでは、この問題はクラスによって解決できます
1. クラスはオブジェクトのテンプレートであり、オブジェクト内のプロパティとメソッドはクラス内で直接定義できます。
定義したら、クラスを通じてオブジェクトを直接作成できます。
2. 同じクラスで作成されたオブジェクトを類似オブジェクトと呼びます。
onstanceof を使用すると、オブジェクトが特定のクラスによって作成されたかどうかを確認できます。
文法:
class クラス名 { } クラス名は大きなこぶのある名前にする必要があります class person {}
const クラス名 = クラス { }
// Person类专门用来创建人的对象
class Person {
}
const p1 = new Person()
//打印p1
console.log(p1)
// 利用instanceof检查p1是否由Person创建
console.log(p1 instanceof Person)
74、JavaScript - 属性
インスタンスの属性:
new の p1 と p2 は両方ともインスタンスです
インスタンスのプロパティにアクセスします 。instance.property name(p1.name)
クラス属性:
static を使用して宣言された属性は静的属性 (クラス属性) です。
クラスに追加される静的属性は class 属性です
アクセスクラスの属性 クラス、属性名 (Person.test)
<script>
/*
类是创建对象的模板,要创建第一件事就是定义类
*/
class Person {
/*
类的代码块,默认就是严格模式
类的代码是用来设计对象的属性的,不是什么代码都能写
*/
name // Person的实例属性name,new出来的p1和p2都是实例
age // Person的实例属性age
static test = "test是静态属性" // 使用static声明的属性,是静态属性(类属性),只能通过 类.属性去访问 例 Person.test
}
const p1 = new Person()
console.log(p1)
const p2 = new Person()
console.log(p2)
</script>
75、JavaScript - メソッド
インスタンスメソッド:
新しい p1 はインスタンスです
アクセスインスタンスメソッド instance.propertymethodName(p1.sayHello())
クラス属性:
staticで宣言したメソッドは静的メソッド(クラスメソッド)です
クラスに追加された静的メソッドはクラスメソッドです
静的メソッドでは、これは現在のクラスを指します。
アクセスクラス属性 class.methodName(Person.test())
<script>
class Person {
name = "张三";
// 添加方法的一种方式
sayHello = function() {
}
// 添加方法的另一种方式(实例方法)
sayHello() {
// 这里的this指的是实例对象,这里的实例对象是p1,
console.log("大家好,我是" + this.name)
}
// 静态方法,使用static声明的方法,只能通过 类.方法 调用
// 静态方法中,this指向的是当前类
static test() {
console.log("我是静态方法", this)
}
}
const p1 =new Person()
p1.sayHello()
</script>
76、JavaScript - コンストラクター
<script>
// class Person {
// // 当我们在类中直接指定实例属性的值时,意味着我们创建的所有对象的属性都是这个值
// name = "张三"
// age = 12
// gender = "男"
// sayHello() {
// console.log(this.name)
// }
// }
// // 创建一个Person实例
// const p1 = new Person()
class Person{
name
age
gender
// 在类中可以添加一个特殊的方法constructor
// 该方法我们称之为构造函数 (构造方法)
// 构造函数会在我们调用类创建对象时执行,new的时候执行
constructor(name, age, gender){
// 在构造函数中,为实例属性进行赋值
// 在构造函数中,this表示当前所创建的对象
this.name = name
this.age = age
this.gender = gender
}
}
// 直接在创建对象时就进行赋值,因为有构造函数
const p1 = new Person("张三", 18, "男")
const p2 = new Person("李四", 11, "女")
</script>
77、JavaScript - カプセル化
オブジェクト指向の機能
カプセル化、継承、ポリモーフィズム
1.カプセル化
- オブジェクトは、さまざまなプロパティを保存するためのコンテナです
- オブジェクトは属性を割り当てるだけでなく、データのセキュリティも割り当てます
- オブジェクトに直接追加されたプロパティは、任意に変更される可能性があるため安全ではありません
- データのセキュリティを確保する方法
1. データの私物化
- 保護する必要があるデータをプライベートとして設定し、内部でのみ使用する
- プライベート化されたデータは使用前に宣言する必要があります
- # で始まるインスタンスはプライベート プロパティになり、プライベート プロパティにはクラス内でのみアクセスできます。
2. データに対する操作を開くためのセッター メソッドとゲッター メソッドを提供する
- 属性はプライベートに設定され、ゲッター メソッドとセッター メソッドを通じて属性を操作する利点
1. 属性の読み取りおよび書き込み権限を制御できます
2. 属性の値はメソッド内で確認できます。
-カプセル化は主にデータのセキュリティを確保するために使用されます
- カプセル化を実現する方法
1. 属性のプライベート化:属性名の前に # を追加します。
2. getterメソッドとsetterメソッドを使用してプロパティを操作する
get プロパティ名() {
this.#プロパティ名を返します
}
属性名(パラメータ)を設定 {
this.#attribute = パラメータ
}
gettert と setter を使用する場合は、2 番目の記述方法を使用することをお勧めします。
class Person{
// 封装属性前线声明
#name
#age
#gender
constructor(name, age, gender){
this.#name = name
this.#age = age
this.#gender = gender
}
// 第一种写法:获取私有属性的方法
getName() {
return this.#name
}
// 第一种写法:修改私有属性
setName(name) {
this.#name = name
}
// 另一种写法(推荐使用)
get age() {
return this.#age
}
// 另一种写法(推荐使用)
set age(age){
this.#age = age
}
}
const p1 = new Person("张三", 19, "男")
// 第一种写法的修改
p1.setName("李四")
// 第一种写法的获取
console.log(p1.getName())
// 第二种写法的修改(推荐使用)
p1.age = 11
// 第二种写法的获取(不需要加括号)(推荐使用)
console.log(p1.age)
</script>
78、JavaScript - ポリモーフィズム
<script>
class Person {
constructor(name) {
this.name = name
}
}
class Dog{
constructor(name){
this.name = name
}
}
const dog1 = new Dog("旺财")
const p1 = new Person("小李")
/*
定义一个函数,这个函数将接收一个对象作为参数,它可以输出hello并打印对象的name属性
多态
- 在JS种不会检查参数的类型,所以这就意味着任何数据都可以作为参数传递
- 要带调用某个函数,无需指定的类型,只要对象满足某些条件即可
- 多态为我们提供了灵活性
*/
function sayHello(obj){
console.log("Hello" + obj.name)
}
// dog1对象和p1对象的类中都有name的属性,所以可以成功调用
sayHello(dog1)
</script>
79、JavaScript - 継承
継承する
- 継承は extends キーワードを通じて行うことができます
- クラスが別のクラスを継承する場合、別のクラスのコードを現在のクラスにコピーするのと同じです(単純な理解)
・継承が発生した場合、継承したクラスiを親クラス(スーパークラス)、継承したクラスをサブクラスと呼びます。
<script>
/*
继承
- 可以通过extends关键字来完成继承
- 当一个类继承另一个类时,就相当于将另一个类中的代码复制到了当前类中(简单理解)
- 继承发生时,被继承的类i称为 父类(超类),继承的类称为 子类
*/
class Animal{
constructor(name){
this.name = name
}
sayHello() {
console.log("动物在叫")
}
}
class Dog extends Animal{
}
class Cat extends Animal{
}
const dog = new Dog("旺财")
const cat = new Cat("小喵")
dog.sayHello()
cat.sayHello()
console.log(dog)
</script>
80. JavaScript - 継承
<script>
/*
继承
- 通过继承可以在不修改一个类的情况下对其进行拓展
- OCP原则
- 程序应该对修改关闭,对扩展开放
*/
class Animal{
constructor(name){
this.name = name
}
sayHello() {
console.log("动物在叫")
}
}
class Dog extends Animal{
// 在子类中,可以通过创建同名方法来重写父类的方法
sayHello(){
console.log("汪汪汪")
}
}
class Cat extends Animal{
// 重写构造函数
constructor(name, age){
// 重写构造函数时,构造函数的第一行代码必须为super()
super(name) // 调用父类的构造函数
this.age = age
}
// 在方法中调用父类的方法 super.父类方法名
sayHello() {
// 调用父类的sayHello
super.sayHello() // 在方法中可以使用 super来调用父类的方法
console.log("喵喵喵")
}
}
const dog = new Dog("旺财")
const cat = new Cat("小喵", 67)
dog.sayHello()
cat.sayHello()
console.log(dog)
console.log(cat)
</script>
八一、JavaScript - オブジェクトの構造
実際には、オブジェクトに属性を格納するための領域が 2 つあります。
1.オブジェクト自体
- オブジェクト自体内で、オブジェクトを通じて直接追加されたプロパティ
- オブジェクト自体の x = y を介してクラスに追加された プロパティ
2. 謎の場所:(プロトタイプ)
- オブジェクトにはまだいくつかのコンテンツがあり、他のオブジェクト (プロトタイプ オブジェクト)に保存されます。
- オブジェクトにはプロトタイプ オブジェクトを格納するための属性があり、この属性は __proto__ と呼ばれます。
-プロトタイプ オブジェクトは、オブジェクトのプロパティを保存する役割も果たします。
オブジェクト内のプロパティにアクセスするときは、まずオブジェクト自体のプロパティにアクセスします。
オブジェクト自体にこの属性が含まれていない場合、プロトタイプ オブジェクト内でこの属性が検索されます。
-プロトタイプオブジェクトの場合に追加されます
1. クラス内の xxx( ){ } によって追加されたメソッドはプロトタイプにあります
2. プロトタイプにプロパティとメソッドを積極的に追加します。
<script>
/*
对象中存储属性的区域实际有两个
1. 对象自身
- 直接通过对象添加的属性,位于对象自身中
- 在类中通过 x = y 的形式添加的属性,位于对象自身中
2. 神秘位置:(prototype)
- 对象中还有一些内容,会存储到其他对象里(原型对象)
- 在对象中会有一个属性用来存储原型对象,这个属性叫_proto_
- 原型对象也负责为对象存储属性
当我们访问对象中的属性时,会优先访问对象自身的属性
对象自身不包含该属性时,才会去原型对象中寻找
- 会添加到原型对象的情况
1. 在类中通过xxx( ){ }方式添加的方法,位于原型中
2. 主动向原型中添加属性和方法,
*/
class Person{
name = "孙悟空"
// 原型对象的sayHello
sayHello(){
console.log("Hello,我是"+ this.name)
}
}
const p = new Person()
// p对象中的sayHello
p.sayHello = "hello"
// 线访问对象自身,再访问原型对象,最后访问父类
console.log(p.sayHello)
</script>
82. JavaScript - プロトタイプ
オブジェクトのプロトタイプ オブジェクトにアクセスする
1.オブジェクト.__proto__
2. JS組み込みアクセスプロトタイプオブジェクト:Object.getPrototypeOf(オブジェクト名)
プロトタイプオブジェクト内のデータ
1. オブジェクト内のデータ (プロパティ、メソッドなど)
2. コンストラクター(オブジェクトコンストラクター)
注:
プロトタイプ オブジェクトにもプロトタイプがあり、プロトタイプ チェーンを形成します。オブジェクトの複雑さに応じて、プロトタイプ チェーンの長さも異なります。
p オブジェクトのプロトタイプ チェーン: p オブジェクト -- プロトタイプ -- プロトタイプ -- null
プロトタイプチェーン:
- オブジェクトのプロパティを読み取る場合、オブジェクト自身のプロパティが優先されます。
オブジェクト内に存在する場合はそれを使用し、存在しない場合はオブジェクトのプロトタイプに移動して検索します。
プロトタイプにある場合はそれを使用し、ない場合はプロトタイプのプロトタイプに移動して見つけます。
Objectオブジェクトのプロトタイプが見つかるまで、オブジェクトのプロトタイプはプロトタイプを持たない(null)
それでも見つからず、obj.__proto__ も見つからない場合は、unknown が返されます。
-スコープ チェーン、変数チェーンを検索します。
-プロトタイプ チェーンは属性を検索するために使用されます。見つからない場合は、未定義が返されます。
<script>
class Person{
name = "张三"
age = 18
sayHello(){
console.log("我是" + this.name)
}
}
/*
访问一个对象的原型对象
1. 对象.__proto__
2. JS内置的访问原型对象: Object.getPrototypeOf(对象名)
原型对象中的数据
1. 对象中的数据(属性,方法等)
2. constructor (对象的构造函数)
注意:
原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同
p对象的原型链:p对象 -- 原型 -- 原型 -- null
原型链:
- 读取对象属性时,会优先对象自身属性
如果对象中有,则使用,没有就去对象的原型中找
如果原型中有,则使用,没有则去原型的原型中寻找
直到找到Object对象的原型,Object的原型没有原型(为null)
如果依然没有找到,找到obj.__proto__还没有,则返回undefined
- 作用域链,时找变量链
- 原型链,是用来找属性的,找不到会返回undefined
*/
const p = new Person()
// 访问原型对象
console.log(p.__proto__)
</script>
八十三、JavaScript - プロトタイプの役割
同じタイプのすべてのオブジェクトは同じプロトタイプ オブジェクトを持ちます。
つまり、同じタイプのプロトタイプチェーンは同じです
プロトタイプの役割:
プロトタイプは、このクラスのすべてのインスタンスがアクセスできるパブリック領域に相当します。
この方法では、すべてのインスタンスからアクセスできるプロパティを 1 つ作成するだけで済みます。
JS での継承はプロトタイプを通じて実現されます。
継承する場合、サブクラスのプロトタイプは親クラスのインスタンスになります。
オブジェクトには、属性 (名前、年齢、性別) など、オブジェクトに固有の値がいくつかあり、各オブジェクトは独自の値を持つ必要があります。
ただし、さまざまなメソッドなど、一部の値は各オブジェクトで同じなので、これらの同じ値の重複を作成する必要はありません。
<script>
class Person{
name = "张三"
age = 18
sayHello(){
console.log("我是" + this.name)
}
}
const p = new Person()
const p2 = new Person()
/*
所有的同类型对象他们的原型对象都是同一个
也就意味着同类型的原型链是一样的
原型的作用:
原型就相当于是一个公共的区域,可以被所有该类实例访问
这样我们只需要创建一个属性,都可以被所有实例访问
JS中继承就是通过原型来实现的
当继承时,子类的原型就是父类的实例
在对象中,有些值是对象独有的,像属性(name,age,gender) 每个对象都应该有自己的值
但是有些值对于每一个对象来说都是一样的,像各种方法,对于这些一样的值没必要重复的创建
*/
// 结果为true ,所有的同类型对象他们的原型对象都是同一个
console.log(p.__proto__ === p2.__proto__)
class Animal{
}
class Cat extends Animal{
}
const cat = new Cat()
// 当继承时,子类的原型就是父类的实例
// cat的原型是父类Animal实例, 父类Animal的原型object,object的原型为Object,Object原型为null
console.log(cat)
console.log("cat的原型" + cat.__proto__)
console.log("父类Animal的原型" + cat.__proto__.__proto__)
console.log("object的原型为" + cat.__proto__.__proto__.__proto__)
console.log("Object原型为" + cat.__proto__.__proto__.__proto__.__proto__)
</script>
84、JavaScript - プロトタイプを変更する
ほとんどの場合、プロトタイプ オブジェクトを変更する必要はありません。
知らせ:
クラスのインスタンスを通じてプロトタイプを変更しないでください。
1. インスタンスを通じて同じタイプのすべてのオブジェクトに影響を与えるのは不適切です
2. プロトタイプを修正するには、まずインスタンスを作成する必要があり、面倒です
3. 危険
__proto__ を介してオブジェクトのプロトタイプにアクセスすることに加えて、
クラスのプロトタイプ プロパティを通じてインスタンスのオブジェクトにアクセスすることもできます: class.prototype
プロトタイプを変更します。クラスを通じて変更するのが最善です。
利点:
1. 変更とは、すべてのインスタンスのプロトタイプを変更することです。
2. インスタンスを作成せずにクラスの変更を完了できる
原則として:
1. プロトタイプを変更しないようにしてください
2. インスタンス オブジェクトを通じて変更するかどうか
3.class.prototypeによる変更
4. Person.prototype = { } のように、プロトタイプに値を直接割り当てないことをお勧めします。
<script>
/*
大部分情况下,我们不需要修改原型对象
注意:
千万不要通过类的实例去修改原型
1. 通过一个实例去影响所有的同类对象,这么做不合适
2. 修改原型得先创建实例,麻烦
3. 危险
除了通过__proto__能访问对象的原型外,
还可以通过类的prototype属性,来访问实例的对象: 类.prototype
修改原型,最好还是通过类去修改
好处:
1. 已修改就是修改所有实例的原型
2. 无需创建实例即可完成对类的修改
原则:
1. 原型尽量不要修改
2. 要改也不要通过实例对象修改
3. 通过 类.prototype 去修改
4. 最好不要直接给prototype去赋值 如:Person.prototype = { }
*/
class Person{
name = "张三"
age = 18
sayHello(){
console.log("我是" + this.name)
}
}
const p = new Person()
const p2 = new Person()
// 通过对象修改原型,向原型中添加方法,修改后所有的同类实例都能访问该方法
p.__proto__.run = () => {
console.log("我在跑")
}
p.__proto__ = new Dog() // 直接为对象赋值了一个新的原型,不要这么做
console.log(Person.prototype) // 访问Person实例的原型对象
p.run()
p2.run()
</script>
85、JavaScript -instanceof と hasOwn
instanceof は、オブジェクトがクラスのインスタンスであるかどうかを確認するために使用されます。
-instanceof は、オブジェクトのプロトタイプ チェーン上にクラスのインスタンスがあるかどうかを確認します。
プロトタイプチェーン上にこのクラスのインスタンスがある限り、true を返します。
-
犬 -> 動物インスタンス -> オブジェクト インスタンス -> オブジェクト プロトタイプ
- Object はすべてのオブジェクトのプロトタイプであるため、Object と Object を使用した instanceof 操作は true を返します。
の
- in 演算子を使用してプロパティをチェックすると、プロパティがオブジェクト自体にあるかプロトタイプにあるかに関係なく、true が返されます。
object.hasOwnProperty(プロパティ名) (非推奨)
- オブジェクト自体に特定のプロパティが含まれているかどうかを確認するために使用されます
Object.hasOwn(オブジェクト, プロパティ名) (推奨)
- オブジェクト自体に特定のプロパティが含まれているかどうかを確認するために使用されます
<script>
class Animal{
}
class Dog extends Animal{
}
const dog = new Dog()
/*
instanceof 用来检查一个对象是否是一个类的实例
- instanceof 检查的是对象的原型链上是否有该类实例
只要原型链上有该类实例,就会返回true
-
dog -> Animal的实例 -> Object实例 -> Object原型
- Object是所有对象的原型,所以任何和对象和Object进行instanceof运算都会返回true
*/
// 通过instanceof检查dog是否是Dog类的实例
console.log(dog instanceof Dog) // true
console.log(dog instanceof Animal) // true
console.log(dog instanceof Object) // true
// 读取实例原型的两种方式
const obj = new Object()
//方式一:通过对象访问Object原型
console.log(obj.__proto__)
//方式二:直接通过类访问Object原型
console.log(Object.prototype)
class Person{
name = "张三"
age = 18
sayHello(){
console.log("我是" + this.name)
}
}
const p = new Person()
/*
in
- 使用in运算符检查属性时,无论属性在对象自身还是在原型中,都会返回true
对象.hasOwnProperty(属性名)(不推荐使用)
- 用来检查一个对象的自yong身是否含有某个属性
Object.hasOwn(对象,属性名) (推荐使用)
- 用来检查一个对象的自yong身是否含有某个属性
*/
// 检查 p 对象中是否含有 name 这个属性
console.log("name" in p)
// 检查 p 对象中是否含有 sayHello 这个属性
console.log(p.hasOwnProperty("sayHello"))
</script>
87、JavaScript - 新しい演算子
new 演算子は、オブジェクトの作成時に使用する演算子です。
- 新しい説明 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
- new を使用して関数を呼び出す場合、この関数はコンストラクターとして呼び出されます。
new で関数を呼び出すとどうなるかは次のとおりです。
1. 通常の JS オブジェクト (オブジェクト オブジェクト { }) を作成します。便宜上、これを新しいオブジェクトと呼びます。
2. コンストラクターのプロトタイプ プロパティを新しいオブジェクトのプロトタイプに設定します。
3. 実際のパラメータを使用してコンストラクタを実行し、新しいオブジェクトを関数内で this として設定します。
4. コンストラクタが非プリミティブ値を返す場合、その値は new 演算子の戻り値として返されます。
コンストラクタの戻り値がプリミティブ値の場合、または戻り値が指定されていない場合
新しいオブジェクトが戻り値として返されます
88、JavaScript - オブジェクトの概要
オブジェクト指向の本質は、コードを記述するときにすべての操作がオブジェクトを通じて実行されることです。
オブジェクト指向プログラミングの手順:
1. 誰かを探す
2. オブジェクトに関与する
学習対象:
1. オブジェクトが何を表し、何に使用されるかを明確にする
2. このオブジェクトの取得方法
3. このオブジェクトの使い方(オブジェクト内のプロパティとメソッド)
オブジェクトの分類:
組み込みオブジェクト
- ES規格で定義されたオブジェクト
- 例: オブジェクト関数文字列番号。。。
ホストオブジェクト
- ブラウザによって提供されるオブジェクト
- グッドドム
カスタムオブジェクト
- 開発者自身が作成したオブジェクト