关于get,set的一点学习 2019-07-03

Vue源码阅读前必须知道javascript的基础内容
的时候遇到这个东西, 就简单测了一下

1. 原型上定义的get,set会影响实例嘛?

    function Name() {};
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      }
    })

    let obj = new Name();
    console.log(obj.name); //its Name.prototype

2. 如果实例上定义能够覆盖吗?

不能, 表明原型上的get优先级更高?

   function Name() {};
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      }
    })

    let obj = new Name();
    console.log(obj.name); //its Name.prototype
    obj.name = 555;
    console.log(obj.name); //its Name.prototype

3. 实例上赋值, 会走原型上定义的set吗?

    function Name() {};
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      },
      set: function (val) {
        data = val
      }
    })

    let obj = new Name();
    console.log(obj.name);//its Name.prototype
    obj.name = "555";
    console.log(obj.name);// 555

4. 既然是原形上定义的get,set, 实例之间是否会影响?

会, 这就有点懵逼

    function Name() {};
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      },
      set: function (val) {
        data = val
      }
    })

    let obj = new Name();
    console.log(obj.name);// its Name.prototype
    obj.name = "555";
    console.log(obj.name);// 555

    let obj2 = new Name();
    console.log(obj2.name);// 555
    obj2.name = 'its obj2';
    console.log(obj2.name);//its obj2
    console.log(obj.name);//its obj2

5. 到这里, 就是第一个跟以前的常识大不相同了

之前的常识是,
子可以访问获取父,
但同时, 子可以覆盖父,(所谓的继承和多态性的基础?)
间接说明, 子和子之间是不会互相影响的.
但是按照上面的代码结果, 则表示
每个实例无法覆盖, 且子与子之间是会互相影响的.

换个角度去思考

表明, 子与子之间, 可以有互相传递数据的通道了?
下面是把obj.a 通过原型的name, 传递给obj2.b, 关键是, obj和obj2是两个实例

    obj.a = 'i am obj.a';
    obj2.b = 'i am obj.b';
    obj.name = obj.a;// 传递
    console.log(obj.name);//i am obj.a
    console.log(obj2.name);////i am obj.a
    console.log(obj.a);//i am obj.a
    console.log(obj2.b);//i am obj.b
    obj2.b = obj2.name;
    console.log(obj2.b);//i am obj.a

6. 子上定义的get 能否覆盖父的get?

能, 表明, 想要覆盖原型上的get, 只能用实例上的get?

    function Name() { };
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      },
      set: function (val) {
        data = val
      }
    })

    let obj = new Name();
    console.log(obj.name);// its Name.prototype
    obj.name = "555";
    console.log(obj.name);// 555
    let obj2 = new Name();
    console.log(obj2.name);// 555


    let str = "its another obj";

    Object.defineProperty(obj, 'name', {
      get: function () {
        return str
      },
      set: function (val) {
        str += val
      }
    })
    console.log(obj.name);// its another obj
    obj.name = "999";
    console.log(obj.name);// its another obj 999
    console.log(obj2.name);// 555  

7. 如果, 子上只定义get, 没定义set会怎么样?

还是会覆盖父级的set, 相当于用一个空set进行了覆盖.
表明get,set是成对走的?

   function Name() { };
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      },
      set: function (val) {
        data = val
      }
    })

    let obj = new Name();
    console.log(obj.name);// its Name.prototype
    obj.name = "555";
    console.log(obj.name);// 555
    let obj2 = new Name();
    console.log(obj2.name);// 555


    let str = "its another obj";

    Object.defineProperty(obj, 'name', {
      get: function () {
        return str
      }
    })
    console.log(obj.name);// its another obj
    obj.name = "999";
    console.log(obj.name);// its another obj
    console.log(obj2.name);// 555  

8. 咦? 继续往下读发现子还是可以覆盖父级的get的?

表明: 关键不在于只能get覆盖get,
defineProperty定义的优先级会更高?
父上defineProperty定义的只能通过子的defineProperty进行覆盖?

    function Name() { };
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      get: function () {
        return data
      },
      set: function (val) {
        data = val
      }
    })
    let obj = new Name();
    Object.defineProperty(obj, 'name', {
      value: 100
    })
    console.log(obj.name);

9. 父用defineProperty, 定义一个value, 子能否用正常属性赋值进行覆盖?

不能! 只能用difineProperty进行覆盖!

    function Name() { };
    let data = "its Name.prototype";
    Object.defineProperty(Name.prototype, 'name', {
      value: 100
    })
    let obj = new Name();
    console.log(obj.name);//100
    obj.name = 555;
    console.log(obj.name);//100

10. defineProperty的优先级比原型链的优先级高?

同样是difineProperty的情况下, 子才会覆盖父?

为什么这么设计?

盗个图

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。