美文网首页
原型与新版的类-class

原型与新版的类-class

作者: 我也不知道啊丶 | 来源:发表于2018-12-30 00:03 被阅读0次

    首先来理解原型
    原型 === 共用属性
    可以先看看方姐的几篇文章:
    什么是JS原型链
    JS 中 proto 和 prototype 存在的意义是什么?
    JS 的 new 到底是干什么的?

    var obj = {}
    obj.toString = ???  // 按常规逻辑来看,应该是undefined
    //然而 打印结果是 "[object Object]"
    //所以
    obj.toString() = window.Object.prototype.toString()
    

    这样,就做到了代码复用
    再来看一个问题

    var arr = [1,2,3]
    arr.toString() = "1,2,3"
    

    如果说每次调用toString()都相当于是调用window.Object.prototype那为什么不同的对象调用同一个toString()的时候打印出来的值不一样呢?
    是不是可以这样假设:toString()知道是谁调用了它

    实际上

    obj.toString = obj.toString.call(obj);
    obj被传给toString()了
    

    可以来证明一下

    var arr = [1,2,3]
    var arr2 = [4,5,6]
    arr2.toString() 
    //打印出 "1,2,3" 这没有问题
    //那么
    arr2.toString.call(arr) 
    "1,2,3"
    //这样就很明显了
    

    原型的用法?

    按照上面的逻辑
    obj.hi() === 共用属性.hi.call(obj)
    那么来改写一下代码

    var 共用属性 = {
        hi(a){
            console.log(a)
        }
    };
    var obj = { name : "我是obj"};
    obj.__proto__ = 共用属性
    obj.hi()  // === 共用属性.hi.call(obj)
    能否打印出{ name : "我是obj"}?
    
    结果却是 undefined
    

    ???? 什么鬼????
    这就要说到js的一个坑了,实际上obj确实传给了共用属性,但是 用别的形参无法获取到,只能用this
    相当于:

    var 共用属性 = {
        hi(this,a){
            console.log(a)
        }
    };
    这里obj实际上是传给了this,但是js默认隐藏了
    

    所以把代码改成:

    var 共用属性 = {
        hi(){
            console.log(this)
        }
    };
    obj.hi();
    {name : "我是obj"}
    

    好,到这我们再来深入探究一下
    obj.__proto__已经等于了共用属性,也就是说
    obj.__proto__ != window.Object.prototype,那么obj.toString()会是undefined吗?
    答案是 no。
    实际上,当你调用obj.toString()的时候,首先会在自身上看有没有这个属性,如果没有,就会去你的原型上找,前面已经设置了obj的原型等于共用属性,所以,接着会在共用属性上找有没有toSring,还是没有,然后会继续去共用属性的原型window.Object.prototype上找,找到了之后,调用window.Object.prototype.toString.call(obj)
    当然,如果在window.Object.prototype上也没有找到,会接着去它的原型上找....直到找到或者找到null为止

    可以打印出来看看
    window.Object.prototype.__proto__ 
    null
    

    所以,每当你声明一个对象的时候,JS会默认给你执行

    新声明的对象.__proto__=window.Object.prototype
    或者
    新声明的对象.__proto__=window.Array.prototype
    

    什么是类?

    var obj1 = {
        name : '张三',
        age : 18
    };
    var obj2 = {
        name : '李四',
        age : 20
    };
    

    很明显 obj1obj2很相似,可以把它们归为一,所以可以把 obj1obj2叫做同一类对象
    那如果有不同的对象呢?

    var obj3 =  {
        aaa = 1,
        bbb = 2
    };
    

    明显跟上面的不能算一类
    如果同一类对象分为一类,那么我们怎么用代码表示它呢?
    方法有两种:

    • 写一个文档,在文档中写清楚
    • 提供一个函数来创建这一类的对象

    function createPerson(name='',age=18){
        var obj = {}
        obj.name = name
        obj.age = age
        return obj
    };
    //开始创建对象
    createPerson()
    {name : "",age:18}
    createPerson("王二狗",16)
    {name : "王二狗",age:16}
    

    类是拥有共同特征的对象
    再看上面的代码,每个对象的name、age都不一样,怎么在创建它们的时候给它们添加共有属性呢?
    当然是用原型
    所以代码可以改成

    var 共有属性 = {
        attr1(){console.log("我们是同类")},
        attr2: '同一类'
    }
    function createPerson(name='',age=18){
        var obj = {}
        obj.name = name
        obj.age = age
        obj.__proto__ = 共有属性
        return obj
    };
    

    开始创建对象


    构造函数:创建某个类的对象的函数
    类是拥有相同属性的对象
    自有属性:对象自身的属性
    共有属性:对象原型里的属性

    class

    每一个class都有一个constructor(构造函数),用来构造自有属性


    那么共有属性放在哪里呢?
    很简单,放在constructor外面就可以了

    目前 共有属性只能是函数

    再来看看复杂一点的
    extends 继承

    注意:在要继承的对象的构造函数里一定要执行super()
    所以继承extends的意思是:
    如果一个类继承了另一个类,那么这个类的对象就有被继承的类的属性
    那么super()的作用是什么呢?
    还是看代码


    p1居然具有了Animal的constructor里的属性
    所以
    super()的作用就是:执行你继承的类的constructor
    被继承的类可以叫做 基类 或者 超类
    所以super()执行一下超类的构造函数
    super()必须放在constructor的第一行

    再来看看 get
    我们知道想要调用一个对象里的某个函数,就得用对象名.函数名称()这种方式,
    如果在函数前面加一个get,就可以直接用对象名.函数的方法来调用了

    当然这个对象并不是具有这个函数返回值的属性
    但是有一个很严重的问题,如果前面写错了,后期除了更改源代码以外,没有办法再修改get函数里面的内容

    所以js又给了我们一个方法, set
    具体用法如下


    实际上class是有些麻烦的 没有原型灵活
    但是还是有一些优点的,比如某个对象的一个属性,我们想让它是只读的,不允许修改,就可以这样
    用this._隐藏属性,然后在get中return出去,没有set就无法修改
    然后用set来控制写入
    在set里设置规则来控制写入

    静态方法 static
    静态方法就是只能通过类名.方法名来访问的方法,new出来的对象都不能访问

    相关文章

      网友评论

          本文标题:原型与新版的类-class

          本文链接:https://www.haomeiwen.com/subject/pyjulqtx.html