js class类和普通函数,模块化的区别,为什么用它,何时用它,它真正的区别在哪

·  阅读 217
js class类和普通函数,模块化的区别,为什么用它,何时用它,它真正的区别在哪

弄懂这些问题,我们分四步

1.它是什么【明白原理】

2.它跟原来的其他能实现同样功能的区别在哪【找到差异】

3.为什么要用它【本质上区别】

4.怎么再工作中立刻就能想到用它【真正的实际意义】

跟着走第一步:概念:ES6规范中引入的class概念,主要思想是想靠近面向对象编程(有过后端开发经验的会清楚c#,java等面向对象编程 类的三大特性 继承 封装 多态);

再看历史:ES6之前 js函数中有构造函数,构造函数的第一个用处(省略重复性代码)如下图:

> 举个例子,我们要录入一年级一班中每一位同学的个人信息,那么我们可以创建一些对象,比如:
> var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
> var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
> var p3 = { name: 'ww', age: 6, gender: '女', hobby: 'singing' };
> var p4 = { name: 'zl', age: 6, gender: '男', hobby: 'football' };
复制代码

以上代码出现太多重复性代码,用构造函数去实现如下:

> function Person(name, gender, hobby) {
>     this.name = name;
      this.gender = gender;
>     this.hobby = hobby;
>     this.age = 6;
> }
复制代码

当创建上面的函数以后, 我们就可以通过 new 关键字调用,也就是通过构造函数来创建对象了。

> var p1 = new Person('zs', '男', 'basketball');
> var p2 = new Person('ls', '女', 'dancing');
> var p3 = new Person('ww', '女', 'singing');
> var p4 = new Person('zl', '男', 'football');
> // ...
复制代码

这是构造函数的第一个用处,再来了解构造函数的第二个知识点--继承原型方法: 在构造函数中定义的 方法 本质上是定义在他们的祖先原型上prototype; 构造函数第三个知识点:this的指向(指向的是本实例对象),我们都知道改变this指向的方式有 :如用箭头函数、bind、apply、call和new(也就是我们的构造函数)

回到我们的class上: 为使JS更像面向对象,ES6版本引入class概念,其基本语法:

class Cat{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    Say(){
        return '我的名字是' + this.name;
    }
}
var cat1 = new Cat('有鱼',2);
console.log(cat1.Say());//我的名字是有鱼
复制代码

class本质上就是一个function 是在构造函数的基础上更“漂亮些”,我说的漂亮是指五官轮廓更清晰; class和构造函数的继承上的区别:看下面例子

> // 构造函数
> function Duck(){
>     this.duckSinging = function (){
>         console.log("嘎")
>     }
> }
> 
> function bird() {
>     this.birdFootNum = function (){
>         console.log("只有两只脚")
>     }
> }
> 
> Duck.prototype = new bird()
> 
> let tanglaoya = new Duck()
> tanglaoya.duckSinging() // 嘎
> tanglaoya.birdFootNum() // 只有两只脚
复制代码

class类的写法:

> class bird {
>     constructor(num = 2){
>         this.num = num
>     }
>     birdFootNum(){
>         console.log(“`有${this.num}只脚”)
>     }
> }
> 
> class Duck extends bird {
>     constructor(num = 2){
>         super(num) // super()就是被继承的对象的constructer
>     }
>     duckSinging(){
>         console.log("嘎")
>     }
> }
> 
> let tanglaoya = new Duck()
> tanglaoya.duckSinging() // 嘎
> tanglaoya.birdFootNum() // 只有2只脚
复制代码

相比之下,更建议后者的class写法,更加符合面向对象编程思想。

跟着走第二步:跟能实现相同功能的模块化有什么区别

在我学习class时候,自己一直有一个疑惑,原来用模糊化编程把同一个场景的方法放在一个模块中 不是一样也可以实现所谓的class的概念,我单独写一个模块js export出去,为什么会有class而他们之间的区别到底是什么,下面个人观点来说下他们的区别: 区别一:作用域和this指向

1.模块模式为自执行匿名函数,通过返回值暴露函数作用域中的变量(即闭包),可以访问外部变量,this绑定为隐式绑定。

而构造函数模式,构造函数就是普通函数,只是通过new关键字执行this 绑定的new绑定——创造一个新的作用域并将其this变量绑定到作用于内部。

类可以多态而模块不行(隐式绑定总是由调用位置决定,而自执行匿名函数调用位置总是在声明时确定)。

所以区别有:

1.模块划分一旦确定不可轻易更改,类的声明却没有太多顾及。

2.模块由于闭包有内存管理问题,类没有。

3.模块需要运行,先后顺序很重要,类是函数声明,由于JS自带的函数升级,写在代码的任何位置都是可以的,只要new的时候按顺序就行。

4.大部分现代模块系统都不会多次加载一个模块,但是类可以多次new。

跟着走第三步:为什么要用它,其实回答这个问题再弄懂前面两个问题的后,心中即有个百分之7,8十的答案了

总结一句话:考虑业务场景,功能时 充分利用面向对象的三大特性 封装(复用性,扩展性,独立性) 继承(这种是实际工作中好处很多) 多态(目前js的多态用到的还不是太多) 这里粗略讲下js多态: 多态的实际含义是:同一操作作用于不同的对象上面时,可以产生不同的解释和不同的执行结果。换句话说,就是给不同的对象发送同一消息时,这些消息会根据这个消息分别给出不同的反馈。 多态的思想实际就是把“做什么”和“谁来做”分离开来

字面意思难以理解,直接上代码:

class People{
    constructor(name){
        this.name = name;
    }
    sayName(){}
}
class A extends People{
    constructor(name){
        super(name);
    }
    sayName(){
        console.log('I am A');
    }
}
class B extends People{
    constructor(name){
        super(name);
    }
    sayName(){
        console.log('I am B');
    }
}
(new A()).sayName();
(new B()).sayName();
//打印:
/*
I am A
I am B
*/
————————————————
复制代码

跟着走第四步:目前还没实际好的例子拿出来,等后续写完一个例子在贴出来

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改