JS高级---面向对象

2020-12-18 20:35

阅读:575

标签:子类   自己的   方便   this   OLE   继承   作用域链   border   back   

嗨!我是前端小M~~

面向对象

面向对象编程:一种编程范式(编程方式,编程成果)

将现实问题构建关系、抽象成类,为类定义属性、方法、在将类【实例化】成实例,访问实例属性,调用实例方法进行使用

let arr = new Array();  arr==>实例  array=>数组例

 

---编程范式(编程方式,编程成果)

 

1.声明式编程(HTML,CSS,告诉计算机需要XX)

 

2.命令式编程 每一步都要告诉计算机(比如声明一个变量)强调了做事步骤

 

  • a,面向过程 分析出解决问题的每一步,逐步实现 (-----ATM机的功能实现程序)
  • b,面向对象 把构成问题的事物分解成各个对象,让具体对象去实现相应事情 (人 ATM机)

 

类:种类,模板,摸具 (数量庞大就可以用类区分,归纳)

 

类和对象的关系:对象具有某些类

 

类属于对象,对象有这些类,类是对象的一种抽象概括,对象是类的具体实现,类是模板,用于生产多个实力

 

----面向对象三大特征

 

封装、继承、多态

 

封装:信息隐藏,把实现功能的方法包装起来,函数是对于算法的封装【随机函数的封装】,类是对于属性和方法的封装【遥控板 电视】

 

继承:子类可以继承父类的所有属性和方法,还可以扩展自己的属性和方法

 

多态:相同的行为,不同的实现

 

----封装

 

1.对象方式表现出类,看不出类和实类的关联(把属性和方法组成类的过程叫封装)

 

2.ES6 class 声明类

class Dog {  //声明一个狗类
            constructor(name, age, gender) { //构造器定义属性 constructor
                this.name = name;
                this.age = age;
                this.gender = gender;
            }
        }
        let xiaohei = new Dog(‘xiaohei‘, 2, ‘male‘);  //实例出对象

3.ES6 之前 ---->工厂模式 

function CatFactory(name,age,gender){
	return{
	name,
	age,
	gender
	}
}
let cat_obj = CatFactory(‘xiaohua‘,2,‘female‘);  

4.混合模式 (构造函数 + 原型)

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(); 得到实例对象后通过实例对象去调用的方法、属性

6、使用new关键字在内部经历的4个步骤
(1)创建一个该类型的空对象,就像是 let _obj = {}
(2)将这个新对象的__proto__(隐式原型)指向了类的prototype(原型)就像是
cat1.__proto__=> Cat.prototype
(3)将构造函数(类)内部的this指向该实例对象,并执行代码,就像是this => _obj
(4)返回该对象

===原型 隐式原型

1.函数和原型 (类或者函数)

每一个函数都有一个属性prototype 表示原型(原型对象)

class Dog{ }==>类也是函数 new Dog( )

原型的来源:

JS之父 布兰登爱奇

JS语言没有子类父类概念,也没有类和实例的概念,靠原型链实现继承的,开始只是进行网页表单验证,原本与继承无关,但语言中有需要一种机制将所有对象关联起来。

要不要继承?继承会加大初学者的学习成本,所有设计出new关键字用来生成实例对象,所有new后面跟的是函数。函数都有原型

原型的作用:给所有的实例提供公共的访问

2.对象和隐式原型

每一个实例对象都有一个__proto__ 称为隐式原型,指向创建该对象的类的原型

let arr = [];
    console.log(arr.__proto__ === Array.prototype); // ==>true

3.原型和构造器

每一个类(对象)的prototype都有一个constructor ,指向函数本身

console.log(Array.prototype.constructor === Array);// ==>true

4.原型链(图片可在网上搜索)

  • 链式调用 ==> 快,美化代码,简洁方便
  • 作用域链 ==>找变量
  • 原型链 ==>找公用属性
  1. 方法是特殊的属性,

  2. 一个实例在调用属性方法时会依次从:
    实例自身 ---->创建该实例的构造函数原型----->Object原型
    查看是否有对应的属性和方法,专业上称为原型链

-----继承

当类与类之间发生了is关系,就看作继承

狗is动物 学生is人

继承的作用:子类继承父类,继承所有属性和方法,子类可以扩展自己的属性方法,实现代码复用

                      缺点:糟糕的继承关系,出现代码冗余,关系臃肿

 //创建一个父类函数
        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

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

 6.1全局 this => window    
 6.2对象{ }不会生成作用域,所以对象方法中的箭头函数  this =>window

-----修改this指向

1.call 呼叫 2.apply 应用->传数组 3.bind捆绑

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环境 3类:a.全局EC  b.局部EC,函数级别上下文  c.eval EC

----执行上下文EC

代码当前的执行环境,又称为执行上下文环境

EC产生时间:函数调用时产生

全局EC : 默认环境(浏览器环境) 产生时间: 打开页面 --关闭页面 =====> 生命周期

                     node                                             node执行-- node关闭

                   局部EC                                           调用时 -----调用结束

JS是单线程非阻塞式异步语言,也就是说浏览器一次只能执行做一件事,代码开始执行进入默认globalEC然后每调用一个函数,新的EC 被创建(进栈、压栈)调用完成出栈,最终留下globalEC,页面关闭,global退栈

浏览器总是运行栈顶的EC

  • --EC的组成

    当调用函数时,新的EC会被创建,在JS引擎内部,这个EC的生命周期还会被分为:

    1.创建阶段

    VO(variable object)变量对象:arguments,声明式函数,var声明的变量
    scope:确定作用域链
    this:确定环境对象
    创建函数发生在调用函数,并执行内部代码之前
    

    2.激活阶段

    1.函数的引用
    2.变量赋值
    3.执行其他代码(调用,打印,自增) 

    3.销毁阶段  

----VO

是执行上下文创建阶段 内部创建的一个对象,用于记录在当前作用域中所有可变的变量,VO中的属性都是不可访问的,只有等激活阶段VO变AO(active Object)激活对象才能被访问

----作用域链

作用域链是一套EC的访问规则,由当前上下文和上层上下文中一系列VO组成

访问规则:先访问自身EC,若找不到变量,则访问声明时所在的EC的变量,以此类推直至全局

 

2.变量赋值3.执行其他代码(调用,打印,自增)

JS高级---面向对象

标签:子类   自己的   方便   this   OLE   继承   作用域链   border   back   

原文地址:https://www.cnblogs.com/trail0226/p/14130161.html


评论


亲,登录后才可以留言!