尼采般地抒情

公告栏

此网站主题为本人手写主题, 主题待开源···

站点信息

文章总数目: 305
已运行时间: 1063
目录
  1. 体系一:原型+原型链
    1. 隐式原型__proto__
    2. 显式原型prototype
    3. constructor构造函数
    4. instanceof
    5. 原型链和成员查找机制
    6. 原型体系中的继承
  2. 体系二:类(class)【ES6】
    1. 创建+继承+使用
  3. 对象的各种创建方式
    1. 字面量
    2. 模式工厂
    3. 构造函数
    4. 原型模式
  4. 对象的内置方法
    1. Object.defineProperty
    2. 删除对象属性
    3. assign()
  5. 对象的遍历
    1. for...in
    2. Object.keys(obj)

尼采般地抒情

尼采般地抒情

公告栏

此网站主题为本人手写主题, 主题待开源···

站点信息

文章总数目: 305
已运行时间: 1063

前言:JavaScript首先在ES6没有出来之前,利用一个叫原型的一系列机制来用一段很长的代码来实现类的继承,说白了就是在函数里面默认给你加个一个叫原型的对象属性,再利用一系列指向来完成继承。在ES6之后,才有了形式上的类class及其对象,以及一个单词extends就搞定的继承,虽说搞定,但这里面的机制还是原型相关知识,记录学习一下。

不管是原型也好,新加的class也罢,就一个目的——为了实现面向对象。从两个体系来展开详述。

体系一:原型+原型链

隐式原型__proto__

每个对象里面都有__proto__属性,这个叫对象原型,这个玩意指向构造函数的prototype对象

__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype

比如说,有一个Person类,有一个Student类,Student类继承自Person类,Student有一个实例student_1,那么student_1会有__proto__对象属性,并且展开该__proto__,会发现里面是Person类的方法和属性

显式原型prototype

每个构造函数里面都有一个属性,这个属性叫prototype,指向另一个对象有什么用?在后面原型链就会发现有用了),并且这个属性是一个对象,叫做构造函数原型

这样可以解决一个问题,就是创建不同实例,这些事例所用的方法都是同一个内存下的方法,实现共享

constructor构造函数

  1. 对象原型( __proto__)和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身
  2. constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
  3. 一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor  就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

instanceof

a instanceof b

判断是true还是false

看a的constructor是什么

当b为 a的constructor或a的__proto__的constructor……

结果都是true

原型链和成员查找机制

原型体系中的继承

call方法可以改变一个函数的指向

  1. 继承父构造函数里面的属性
// 1. 父构造函数

function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
// 3.使用 call 方式实现子继承父的属性
Father.call(this, uname, age);
this.score = score;
}
var son = new Son('刘德华', 18, 100);
console.log(son);
  1. 继承方法
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log(100000);
};
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father.call(this, uname, age);
this.score = score;
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用 constructor 指回原来的构造函数
Son.prototype.constructor = Son;
// 这个是子构造函数专门的方法
Son.prototype.exam = function() {
console.log('孩子要考试');
}
var son = new Son('刘德华', 18, 100);
console.log(son);

体系二:类(class)【ES6】

在 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。类抽象了对象的公共部分,它泛指某一大类(class)对象特指某一个,通过类实例化一个具体的对象。其创建的方式和之前学过的语言很类似。

在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象

创建+继承+使用

// 奥特曼类
class Aoteman {
// 构造函数里面放共有属性、方法
constructor(name, age) {
this.name = name;
this.age = age;
}
Ability(abi) {
console.log(this.name + " can " + abi);
}
}

// 假奥特曼类 继承 奥特曼
class Jia extends Aoteman {
constructor (x, y) {
// 继承父类的构造函数
super(x,y);
// 方便写自己的函数
this.x = x;
this.y = y;
}
// 自己内部的函数
Chuiniu() {
console.log(this.x + " chuiniu");
}

}

// 创建迪迦对象
let dijia = new Aoteman('dijia', 100);
console.log(dijia);
dijia.Ability("X-ray");
let dijia_jia = new Jia("dijia_jia", 50);
dijia_jia.Ability("xxx");
dijia_jia.Chuiniu();

对象的各种创建方式

字面量

属性和方法的调用:

属性可以用"."和["属性名"]来调用

方法用"."来调用

模式工厂

new 一个空对象,let obj = new Object();

然后利用"."的方式给其添加属性和方法

内置的 Object()构造函数

构造函数

构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

function 构造函数名(形参 1,形参 2,形参 3) {
this.属性名 1 = 参数 1;
this.属性名 2 = 参数 2;
this.属性名 3 = 参数 3;
this.方法名 = 函数体;
}

let obj = new 构造函数名(实参 1,实参 2,实参 3)


  • 构造函数约定首字母大写
  • 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
  • 构造函数中不需要 return 返回结果
  • 当我们创建对象的时候,必须用 new 来调用构造函数

原型模式

下面详述什么是原型

对象的内置方法

参考教程:

Object.defineProperty

Object.defineProperty 设置或修改对象中的属性

Object.defineProperty(对象,修改或新增的属性名,{
value:修改或新增的属性的值,
writable:true/false,//如果值为 false 不允许修改这个属性值
enumerable: false,//enumerable 如果值为 false 则不允许遍历
configurable: false //configurable 如果为 false 则不允许删除这个属性 属性是否可以被删除或是否可以再次修改特性
})

删除对象属性

assign()

  • Object.assign 后者覆盖前者,再返回前者
  • 常用于深拷贝浅拷贝数据

对象的遍历

for...in

语句用于对数组或者对象的属性进行循环操作。

其语法如下:

for (变量 in 对象名字) {
// 在此执行代码
}
  • 语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。书里面建议用 const 来加持。
for (let k in obj) {
console.log(k); // 这里的 k 是属性名
console.log(obj[k]); // 这里的 obj[k] 是属性值
}

Object.keys(obj)

获取属性名

var obj = {
id: 1,
pname: '小米',
price: 1999,
num: 2000
};
var result = Object.keys(obj)
console.log(result)//[id,pname,price,num]

评论区

Twikoo giscus