JS高级---面向对象
2020-12-18 20:35
标签:子类 自己的 方便 this OLE 继承 作用域链 border back 嗨!我是前端小M~~ 面向对象 面向对象编程:一种编程范式(编程方式,编程成果) 将现实问题构建关系、抽象成类,为类定义属性、方法、在将类【实例化】成实例,访问实例属性,调用实例方法进行使用 let arr = new Array(); arr==>实例 array=>数组例 1.声明式编程(HTML,CSS,告诉计算机需要XX) 2.命令式编程 每一步都要告诉计算机(比如声明一个变量)强调了做事步骤 封装:信息隐藏,把实现功能的方法包装起来,函数是对于算法的封装【随机函数的封装】,类是对于属性和方法的封装【遥控板 电视】 继承:子类可以继承父类的所有属性和方法,还可以扩展自己的属性和方法 多态:相同的行为,不同的实现 1.对象方式表现出类,看不出类和实类的关联(把属性和方法组成类的过程叫封装) 2.ES6 class 声明类 3.ES6 之前 ---->工厂模式 4.混合模式 (构造函数 + 原型) 6、使用new关键字在内部经历的4个步骤 1.函数和原型 (类或者函数) 每一个函数都有一个属性prototype 表示原型(原型对象) class Dog{ }==>类也是函数 new Dog( ) 原型的来源: JS之父 布兰登爱奇 JS语言没有子类父类概念,也没有类和实例的概念,靠原型链实现继承的,开始只是进行网页表单验证,原本与继承无关,但语言中有需要一种机制将所有对象关联起来。 要不要继承?继承会加大初学者的学习成本,所有设计出new关键字用来生成实例对象,所有new后面跟的是函数。函数都有原型 原型的作用:给所有的实例提供公共的访问 2.对象和隐式原型 每一个实例对象都有一个__proto__ 称为隐式原型,指向创建该对象的类的原型 3.原型和构造器 每一个类(对象)的prototype都有一个constructor ,指向函数本身 4.原型链(图片可在网上搜索) 方法是特殊的属性, 一个实例在调用属性方法时会依次从: 当类与类之间发生了is关系,就看作继承 狗is动物 学生is人 继承的作用:子类继承父类,继承所有属性和方法,子类可以扩展自己的属性方法,实现代码复用 缺点:糟糕的继承关系,出现代码冗余,关系臃肿 1.全局环境下 this=>window 2.普通函数(包括嵌套)this=>window 3.通过对象调用的方法 this=>对象 4.通过事件 this=>事件源 5.构造函数 new出来的实例 this =>实例 6.箭头函数 this指向取决于当前箭头函数声明的环境 ----->执行上下文环境 箭头函数需要获取函数定义时的所在的EC的this 箭头函数定义在那个作用域中,就继承当前作用域的this的指向 EC环境 3类: a.全局EC b.局部EC,函数级别上下文 c.eval EC 1.call 呼叫 2.apply 应用->传数组 3.bind捆绑 作用:生效 域:范围 变量生效的范围,也叫做语法环境 作用域的产生事件: 函数定义(声明)时产生 作用域分类: EC环境 3类:a.全局EC b.局部EC,函数级别上下文 c.eval EC 代码当前的执行环境,又称为执行上下文环境 EC产生时间:函数调用时产生 全局EC : 默认环境(浏览器环境) 产生时间: 打开页面 --关闭页面 =====> 生命周期 node node执行-- node关闭 局部EC 调用时 -----调用结束 JS是单线程非阻塞式异步语言,也就是说浏览器一次只能执行做一件事,代码开始执行进入默认globalEC然后每调用一个函数,新的EC 被创建(进栈、压栈)调用完成出栈,最终留下globalEC,页面关闭,global退栈 浏览器总是运行栈顶的EC 当调用函数时,新的EC会被创建,在JS引擎内部,这个EC的生命周期还会被分为: 1.创建阶段 2.激活阶段 3.销毁阶段 是执行上下文创建阶段 内部创建的一个对象,用于记录在当前作用域中所有可变的变量,VO中的属性都是不可访问的,只有等激活阶段VO变AO(active Object)激活对象才能被访问 作用域链是一套EC的访问规则,由当前上下文和上层上下文中一系列VO组成 访问规则:先访问自身EC,若找不到变量,则访问声明时所在的EC的变量,以此类推直至全局 2.变量赋值3.执行其他代码(调用,打印,自增) JS高级---面向对象 标签:子类 自己的 方便 this OLE 继承 作用域链 border back 原文地址:https://www.cnblogs.com/trail0226/p/14130161.html---编程范式(编程方式,编程成果)
类:种类,模板,摸具 (数量庞大就可以用类区分,归纳)
类和对象的关系:对象具有某些类
类属于对象,对象有这些类,类是对象的一种抽象概括,对象是类的具体实现,类是模板,用于生产多个实力
----面向对象三大特征
封装、继承、多态
----封装
class Dog { //声明一个狗类
constructor(name, age, gender) { //构造器定义属性 constructor
this.name = name;
this.age = age;
this.gender = gender;
}
}
let xiaohei = new Dog(‘xiaohei‘, 2, ‘male‘); //实例出对象
function CatFactory(name,age,gender){
return{
name,
age,
gender
}
}
let cat_obj = CatFactory(‘xiaohua‘,2,‘female‘);
function Cat(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
Cat.prototype.eat = function(){
console.log(`饿了,干饭去`);
}
let cat1 = new Cat("虾虎",2,"male"); //创建具有某些类的对象 实例方法
cat1.eat();
console.log(cat1);
let cat2 = new Cat("大华",3,‘female‘);
cat2.eat();
console.log(cat2);
5.静态方式(工具型)
Math.random(); JSON.parse(); -->直接在类构造函数身上使用
实例方法
let arr = new Array() arr.push(); 得到实例对象后通过实例对象去调用的方法、属性
(1)创建一个该类型的空对象,就像是 let _obj = {}
(2)将这个新对象的__proto__(隐式原型)指向了类的prototype(原型)就像是
cat1.__proto__=> Cat.prototype
(3)将构造函数(类)内部的this指向该实例对象,并执行代码,就像是this => _obj
(4)返回该对象===原型 隐式原型
let arr = [];
console.log(arr.__proto__ === Array.prototype); // ==>true
console.log(Array.prototype.constructor === Array);// ==>true
实例自身 ---->创建该实例的构造函数原型----->Object原型
查看是否有对应的属性和方法,专业上称为原型链-----继承
//创建一个父类函数
class Graph {
constructor(left, top, color) {
this.left = left;
this.top = top;
this.color = color;
this.node = null;
this.init();
}
init() {
this.node = document.createElement(‘div‘);
body.appendChild(this.node);
this.setPosition();
this.setColor();
}
setPosition() {
Object.assign(this.node.style, {
position: ‘absolute‘,
top: `${this.top}px`,
left: `${this.left}px`
});
}
setColor() {
Object.assign(this.node.style, {
backgroundColor: `${this.color}`
});
}
}
//创建一个圆型 子类
class Circle extends Graph { //extends 继承
constructor(left, top, color, radius) {
super(left, top, color); //子类要先继承父类的super,然后在扩展自己的this.XX属性,不然报错
this.radius = radius; //radius自身扩展的属性
this.setSize();
}
setSize() {
Object.assign(this.node.style, {
width: `${this.radius * 2}px`,
height: `${this.radius * 2}px`,
borderRadius: `${this.radius}px`,
});
}
}
----this
6.1全局 this => window
6.2对象{ }不会生成作用域,所以对象方法中的箭头函数 this =>window
-----修改this指向
function foo(n){
console.log(this, n);
}
const obj = {
name:‘zhangsan‘
}
foo.call(obj,5);
foo.apply(obj,[5]);
foo.bind(obj)(5);
call,apply改变this的同时立即调用函数,bind改变后返回一个新数组,需要重新调用
------作用域 scope
----执行上下文EC
--EC的组成
VO(variable object)变量对象:arguments,声明式函数,var声明的变量
scope:确定作用域链
this:确定环境对象
创建函数发生在调用函数,并执行内部代码之前
1.函数的引用
2.变量赋值
3.执行其他代码(调用,打印,自增)
----VO
----作用域链